JavaSound:提取立体声音频的一个通道

问题描述 投票:1回答:2

我有一个立体声波文件,我只需要读取和播放所选的通道。做到这一点的最佳方法是什么?

java audio javasound
2个回答
2
投票

当您通过AudioInputStream导入wav文件时,请使用AudioFileFormat信息将字节转换为PCM。左右的数据交替出现。因此,如果该行是16位,则每帧将有4个字节。前两个将组装到左侧通道中,后两个将组装在右侧通道中。 (反之亦然,我很难确定哪个频道是左侧还是右侧。)

这是一个很好的教程,其中包含有关如何读取一行的示例:http://docs.oracle.com/javase/tutorial/sound/converters.html

可能需要本教程中的一些较早的教程来帮助阐明。另外,如果您对将字节转换为PCM有疑问,请在StackOverflow上进行一些解释以供参考。应该不太难找到它们。


0
投票

这是从多通道直接音频线路(JavaSound)中提取单个通道的简单方法。在我的Line6(r)Helix(r)吉他音效板(8通道)中进行了尝试,效果很好。我猜它可以与任何类型的DataTargetLine一起使用。在这种情况下,我们基于假设16位样本的AudioFormat处理数据。希望对您有所帮助。

    public ArrayList<byte[]> extract16BitsSingleChannels(byte[] audioBuffer, int channels) {

    /* Parameters :
     * 
     * audioBuffer : the buffer that has just been produced by
     * your targetDataLine.read();
     * channels : the number of channels defined in the AudioFormat you 
     * use with the line
     * 
     *  the AudioFormat which i tested :
     *       float sampleRate = 44100; 
     *       int sampleSizeInBits = 16;
     *       int channels = 8;
     *       boolean signed = true;
     *       boolean bigEndian = true;
     */


    /* let's create a simple container which will receive our channels buffers */

    ArrayList<byte[]> channelsData = new ArrayList<byte[]>();

    /* take care of adjusting the size of each channel buffer */

    final int channelLength=audioBuffer.length/channels;

    /* let's create one buffer per channel and place them in the container */

    for (int channelIndex=0 ; channelIndex<channels ;channelIndex++) 

    {
        byte[] channel=new byte[channelLength];
        channelsData.add(channel);
    }

    /* then process bytes and copy each channels byte in its buffer */

    int index=0; 

    for(int i = 0; i < channelLength; i+=2) //i+=2 for 16 bits=2 Bytes samples
    {
        for (int c=0 ; c < channels ; c++) {
            channelsData.get(c)[i]=audioBuffer[index];   // 1st Byte
            index++;
            channelsData.get(c)[i+1]=audioBuffer[index]; // 2nd Byte
            index++;
        }

    }

    /* Returns each set of bytes of each channel in its buffer you can use to
       write on whatever Byte streamer you like. */

    return channelsData;   

}
© www.soinside.com 2019 - 2024. All rights reserved.