首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JavaSound:提取一个声道立体声

JavaSound:提取一个声道立体声
EN

Stack Overflow用户
提问于 2014-09-10 23:39:46
回答 2查看 2K关注 0票数 2

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-09-11 20:10:24

当您通过AudioInputStream导入wav文件时,使用AudioFileFormat信息将字节转换为PCM。右和左交替的数据。因此,如果行为16位,则每帧将有4个字节.前两个将组装到左侧通道,第二个将组装到右侧通道。(反之亦然-我很难直截了当地记住哪个频道是左还是右)

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

可能需要前面的一些教程来帮助澄清。另外,如果您有关于将字节转换为PCM和向后转换的问题,那么已经有几个关于StackOverflow的解释可供参考。应该不难找到他们。

票数 3
EN

Stack Overflow用户

发布于 2020-06-01 21:11:03

这是一种从多通道直接音频线路(JavaSound)中提取单通道的简单方法。在我的Line6(r),Helix(r)吉他音效板(8个频道)的尝试,它的工作相当好。我想它适用于任何类型的DataTargetLine。在这种情况下,我们处理基于AudioFormat的16位样本的数据。希望能帮上忙。

代码语言:javascript
复制
    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;   

}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25776803

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档