java - 音频文件获取左/右声道

标签 java android audio-processing

经过大量研究,我找不到明确的答案。我想要实现的是:获取一个 mp3/wav 文件并将其左右声道保存为 2 byte[]。然后我可以操作每个 channel ,然后再次将它们相加并创建一个新的 wav 文件。 (最好是 Java 的解决方案)

相关问题是split two channels of AudioRecord of CHANNEL_IN_STEREO .然而这是使用audiorecord,如何应用它来读取音频文件?

谢谢

最佳答案

这是读取 16 位波形文件的程序

示例音频:http://freewavesamples.com/korg-triton-slow-choir-st-c4

16 位立体声 PCM 的数据打包: 样本 1


channel 0 | channel 0 | channel 1 | channel 1

(左)| (左)| (右) | (右)

低阶 |高阶 |低阶 |高阶

字节 |字节 |字节 |字节


并以 CSV 格式打印。我不会将 CSV 编写器代码放在这里。它已在此处提供。

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.UnsupportedEncodingException;

public class AudioReader {

    class WavHeader {
        public byte[] RIFF_ID = new byte[4]; // "riff"
        public int SIZE; //
        public byte[] WAV_ID = new byte[4]; // "WAVE"
        public byte[] FMT_ID = new byte[4]; // "fmt id"
        public int FMT_SZ; // fmt
        public int FORMAT; //
        public short CHANNELS; // Channels
        public int SAMPLE_PER_SEC; // Sample per second
        public int AVGBYTE_PER_SEC; // Average Byte per second
        public short BLOCK_SZ; // CHANNELS * (BIT>>3)
        public short BIT; // BITS
        public byte[] DATA_ID = new byte[4]; // "data"
        public int DATA_SZ; //
    }

    String m_strFileName;
    WavHeader m_objHeader;

    public AudioReader(String strFileName) {
        m_strFileName = strFileName;
        m_objHeader = new WavHeader();
    }

    private void printHeaderBigEndian(int nSamples) {
        try {
            // 1
            String str1 = new String(m_objHeader.RIFF_ID, "ISO-8859-1");
            System.out.println("Riff Id: " + str1);
            // 2
            System.out.println("Size: " + m_objHeader.SIZE);
            // 3
            String str2 = new String(m_objHeader.WAV_ID, "ISO-8859-1");
            System.out.println("Wav Id: " + str2);
            // 3
            String str3 = new String(m_objHeader.FMT_ID, "ISO-8859-1");
            System.out.println("Fmt Id: " + str3);
            // 4
            System.out.println("Format: " + m_objHeader.FORMAT);
            // 5
            System.out.println("Channels: " + m_objHeader.CHANNELS);
            // 6
            System.out.println("Sample per sec: " + m_objHeader.SAMPLE_PER_SEC);
            // 7
            System.out.println("Avg Byte per sec: "
                    + m_objHeader.AVGBYTE_PER_SEC);
            // 8
            System.out.println("Block Sz: " + m_objHeader.BLOCK_SZ);
            // 9
            System.out.println("Bit: " + m_objHeader.BIT);
            // 10
            String str4 = new String(m_objHeader.DATA_ID, "ISO-8859-1");
            System.out.println("Data Id: " + str4);
            // 11
            System.out.println("Data Sz: " + m_objHeader.DATA_SZ);
            // 12
            System.out.println("Samples: " + nSamples);
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    // ////////////////////////////////////////////////////////////////////////////////////
    //
    public void ReadUsingDataInputStream() {
        try {
            File in = new File(m_strFileName);
            FileInputStream fis = new FileInputStream(in);
            DataInputStream dis = new DataInputStream(fis);

            dis.read(m_objHeader.RIFF_ID, 0, 4);
            m_objHeader.SIZE = Integer.reverseBytes(dis.readInt());
            dis.read(m_objHeader.WAV_ID, 0, 4);
            dis.read(m_objHeader.FMT_ID, 0, 4);
            m_objHeader.FMT_SZ = Integer.reverseBytes(dis.readInt());
            m_objHeader.FORMAT = Short.reverseBytes(dis.readShort());
            m_objHeader.CHANNELS = Short.reverseBytes(dis.readShort());
            m_objHeader.SAMPLE_PER_SEC = Integer.reverseBytes(dis.readInt());
            m_objHeader.AVGBYTE_PER_SEC = Integer.reverseBytes(dis.readInt());
            m_objHeader.BLOCK_SZ = Short.reverseBytes(dis.readShort());
            m_objHeader.BIT = Short.reverseBytes(dis.readShort());
            dis.read(m_objHeader.DATA_ID, 0, 4);
            m_objHeader.DATA_SZ = Integer.reverseBytes(dis.readInt());

            int nSamples = m_objHeader.DATA_SZ / m_objHeader.BLOCK_SZ;
            printHeaderBigEndian(nSamples);

            String strCsvFileName = in.getParent() + "//" + in.getName()
                    + ".csv";

            String strLine[] = new String[3];

            File out = new File(strCsvFileName);
            out.createNewFile();
            FileWriter fw = new FileWriter(out);
            CSVWriter csvW = new CSVWriter(fw);

            for (int n = 1; n < nSamples; n++) {
                strLine[0] = Integer.toString(n);
                strLine[1] = Short.toString(Short.reverseBytes(dis.readShort()));
                strLine[2] = Short.toString(Short.reverseBytes(dis.readShort()));
                csvW.writeNext(strLine);
            }

            dis.close();
            csvW.Close();

            System.out.println("Done.....");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

关于java - 音频文件获取左/右声道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39132063/

相关文章:

java - 测试成绩评分器 - Java 初学者

android - 如何限制 AutoCompleteTextView 下拉菜单关闭?

audio - 如何使音频从视频中的指定点和最后指定的时间开始

java - RecyclerView 只在 List 中添加一项,而不是添加所有条目

java - 数组列表比较

android - Android电子市场-替换apk而不通知/强制用户更新

java - 音频文件的语音转换器

audio - XAudio2 遮挡处理

java - 执行外部程序

android - 圆形图像切割形式所有侧面