Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaSound:提取立体声音频的一个通道_Java_Audio_Javasound - Fatal编程技术网

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

JavaSound:提取立体声音频的一个通道,java,audio,javasound,Java,Audio,Javasound,我有一个立体声文件,我需要读取和播放只选定的频道。实现这一目标的最佳方式是什么 通过AudioInputStream导入wav文件时,请使用AudioFileFormat信息将字节转换为PCM。左右两侧的数据交替显示。因此,如果行是16位,那么每帧将有4个字节。前两个将组装到左通道中,后两个将组装到右通道中。(反之亦然——我很难准确地记住哪个频道是左频道还是右频道。) 下面是一个关于如何阅读一行的很好的教程和示例: 可能需要一些早期的教程来帮助澄清。此外,如果您对如何将字节转换为PCM或转换回

我有一个立体声文件,我需要读取和播放只选定的频道。实现这一目标的最佳方式是什么

通过AudioInputStream导入wav文件时,请使用AudioFileFormat信息将字节转换为PCM。左右两侧的数据交替显示。因此,如果行是16位,那么每帧将有4个字节。前两个将组装到左通道中,后两个将组装到右通道中。(反之亦然——我很难准确地记住哪个频道是左频道还是右频道。)

下面是一个关于如何阅读一行的很好的教程和示例:


可能需要一些早期的教程来帮助澄清。此外,如果您对如何将字节转换为PCM或转换回PCM有疑问,可以参考StackOverflow中的一些解释。应该不太难找到它们。

这里有一个简单的方法,可以从多声道直接音频线路(JavaSound)中提取单声道。在我的Line6(r)Helix(r)吉他音效板(8个通道)上试用过,效果非常好。我想它适用于任何类型的DataTargetLine。在本例中,我们基于承载16位样本的音频格式处理数据。希望能有帮助

    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 container which will receive our "per channel" buffers */

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

    /* take care of adjusting the size of the audioBuffer so that 
     * audioBuffer % channels == 0 is true ... because :        
     */

    final int channelLength=audioBuffer.length/channels;

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

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

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

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

    int byteIndex=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[byteIndex];   // 1st Byte
            byteIndex++;
            channelsData.get(c)[i+1]=audioBuffer[byteIndex]; // 2nd Byte
            byteIndex++;
        }

    }

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

    return channelsData;   

}
公共阵列列表提取16位单通道(字节[]音频缓冲区,int通道){
/*参数:
* 
*audioBuffer:刚由生成的缓冲区
*您的targetDataLine.read();
*channels:您使用的AudioFormat中定义的频道数
*与线路一起使用
* 
*我测试的音频格式:
*浮式取样器=44100;
*int sampleSizeInBits=16;
*int通道=8;
*布尔符号=真;
*布尔bigEndian=true;
*/
/*让我们创建一个容器来接收“每通道”缓冲区*/
ArrayList channelsData=新的ArrayList();
/*注意调整音频缓冲区的大小,以便
*audioBuffer%Channel==0为真…因为:
*/
最终int channelLength=audioBuffer.length/通道;
/*让我们为每个通道创建一个缓冲区,并将它们放置在
*容器
*/
对于(int c=0;c
谢谢你,菲尔!现在正在查看教程。你能详细说明一下“转换为DSP”吗?这对我来说是一个令人毛骨悚然的问题。我应该说PCM!!对此我很抱歉。我更正了原来的帖子。4字节帧中的0字节和1字节是左通道。谢谢你的帮助!