1

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

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

我将在下面分享我所拥有的,但老实说,这并不多。有问题的所有内容都将进入我已记下的设置功能:

//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;
    }
}
4

1 回答 1

2

解决方案:

我不是p5.js专家,但我已经使用它足够多,我认为必须有一种方法可以做到这一点,而无需整个 blob/文件读取。这些文档对复杂的处理不是很有帮助,所以我在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所以我再次为您要分离的每个通道加载文件,但我确信有一个解决方法。

快乐分裂!

于 2019-11-13T01:59:54.860 回答