Javascript 将立体声音频文件拆分为每个频道的AudioNodes

Javascript 将立体声音频文件拆分为每个频道的AudioNodes,javascript,audio,p5.js,javascript-audio-api,Javascript,Audio,P5.js,Javascript Audio Api,如何将立体声音频文件(我目前正在使用WAV,但我对如何为MP3执行此操作感兴趣,如果不同的话)拆分为左声道和右声道,以从P5.sound.js库中输入两个独立的快速傅立叶变换(FFT) 我已经在下面的代码中写下了我认为我需要做的事情,但是我还没有找到任何人通过谷歌搜索这样做的例子,我的外行的所有尝试都一无所获 下面我将分享我所拥有的,但老实说,这并不多。所有问题都会进入设置功能,我在其中做了一个说明: //variable for the p5 sound object var sound =

如何将立体声音频文件(我目前正在使用WAV,但我对如何为MP3执行此操作感兴趣,如果不同的话)拆分为左声道和右声道,以从P5.sound.js库中输入两个独立的快速傅立叶变换(FFT)

我已经在下面的代码中写下了我认为我需要做的事情,但是我还没有找到任何人通过谷歌搜索这样做的例子,我的外行的所有尝试都一无所获

下面我将分享我所拥有的,但老实说,这并不多。所有问题都会进入设置功能,我在其中做了一个说明:

//variable for the p5 sound object
var sound = null;
var playing = false;

function preload(){
    sound = loadSound('assets/leftRight.wav');
}

function setup(){
    createCanvas(windowWidth, windowHeight);
    background(0);

    // I need to do something here to split the audio and return a AudioNode for just 
    // the left stereo channel. I have a feeling it's something like 
    // feeding audio.getBlob() to a FileReader() and some manipulation and then converting 
    // the result of FileReader() to a web audio API source node and feeding that into 
    // fft.setInput() like justTheLeftChannel is below, but I'm not understanding how to work 
    // with javascript audio methods and createChannelSplitter() and the attempts I've made 
    // have just turned up nothing.

    fft = new p5.FFT();
    fft.setInput(justTheLeftChannel);
}

function draw(){
    sound.pan(-1)
    background(0);
    push();
    noFill();
    stroke(255, 0, 0);
    strokeWeight(2);

    beginShape();
    //calculate the waveform from the fft.
    var wave = fft.waveform();
    for (var i = 0; i < wave.length; i++){
        //for each element of the waveform map it to screen 
        //coordinates and make a new vertex at the point.
        var x = map(i, 0, wave.length, 0, width);
        var y = map(wave[i], -1, 1, 0, height);

        vertex(x, y);
    }

    endShape();
    pop();
}

function mouseClicked(){
    if (!playing){
        sound.loop();
        playing = true;
    } else {
        sound.stop();
        playing = false;
    }
}
//p5声音对象的变量
var-sound=null;
var=false;
函数预加载(){
声音=加载声音('assets/leftRight.wav');
}
函数设置(){
createCanvas(窗口宽度、窗口高度);
背景(0);
//我需要在这里做一些事情来分割音频并返回一个AudioNode,只需
//左边的立体声频道,我感觉有点像
//将audio.getBlob()馈送到FileReader()并进行一些操作,然后转换
//FileReader()的结果发送到web audio API源节点并将其馈送到
//setInput()就像下面的左通道一样,但我不知道如何工作
//使用javascript音频方法和createChannelSplitter()以及我所做的尝试
//我什么也没发现。
fft=新的p5.fft();
fft.setInput(仅左通道);
}
函数绘图(){
声音。潘(-1)
背景(0);
推();
noFill();
冲程(255,0,0);
冲程重量(2);
beginShape();
//通过fft计算波形。
var波形=fft.波形();
对于(var i=0;i<波长;i++){
//对于波形的每个元素,将其映射到屏幕
//坐标并在该点上创建一个新顶点。
var x=映射(i,0,波长,0,宽度);
var y=映射(波[i],-1,1,0,高度);
顶点(x,y);
}
endShape();
pop();
}
函数mouseClicked(){
如果(!玩){
sound.loop();
玩=真;
}否则{
声音。停止();
玩=假;
}
}
解决方案: 我不是一个
p5.js
专家,但我已经和它打过很多交道了,我认为必须有一种方法可以做到这一点,而不必进行大量的blob/文件读取。这些文档对于复杂的处理不是很有帮助,所以我在
p5.Sound
源代码中进行了一些研究,我得出了以下结论:

// left channel
sound.setBuffer([sound.buffer.getChannelData(0)]);
// right channel
sound.setBuffer([sound.buffer.getChannelData(1)]);
-单击画布可在L/stereo/R音频播放和FFT视频之间切换


说明:
p5.SoundFile
有一种方法,可用于就地修改声音文件对象的音频内容。函数签名指定它接受一个缓冲区对象数组,如果该数组只有一个项,它将生成一个mono源-它已经以正确的格式提供给FFT!那么,我们如何生成只包含一个通道数据的缓冲区呢

在整个源代码中,都有单独通道操作的示例。起初我对访问未记录的属性很谨慎,但事实证明,由于
p5.Sound
在幕后使用了WebAudio API,所以这个
缓冲区实际上只是普通的旧WebAudio AudioBuffer,而
getChannelData
方法就是

上述方法唯一的缺点是,
setBuffer
直接作用于
声音文件
,因此我将为您想要分离的每个频道再次加载该文件,但我确信有一个解决方法


分手快乐

格雷厄姆,非常感谢你!这完美地解决了我的问题。上周,当我开始想弄明白这一点时,我应该来这里问一下:)这比我所尝试的一切都要简单得多!