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



如何将立体声音频文件(我目前正在使用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.js专家,但我已经和它做了足够多的工作,我认为必须有一种方法来做到这一点,而不需要整个blobs/文件读取。文档对复杂的处理没有太大帮助,所以我在p5.Sound源代码中进行了一些挖掘,这就是我想到的:

// left channel
sound.setBuffer([sound.buffer.getChannelData(0)]);
// right channel
sound.setBuffer([sound.buffer.getChannelData(1)]);

下面是一个工作示例-单击画布可以在L/立体声/R音频播放和FFT视觉效果之间切换。


说明:

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

在整个源代码中,有通过sound.buffer.getChannelData()进行单独通道操作的示例。起初,我对访问未记录的属性很谨慎,但事实证明,由于p5.Sound在后台使用WebAudio API,因此buffer实际上只是一个普通的旧WebAudio AudioBuffer,getChannelData方法也有很好的文档记录。

上述方法唯一的缺点是setBuffer直接作用于SoundFile,所以我会为您想要分离的每个通道再次加载文件,但我相信有一个解决方法。

快乐的分手!

最新更新