javascript - 将立体声音频文件拆分为每个 channel 的 AudioNodes

标签 javascript audio p5.js javascript-audio-api

我如何将立体声音频文件(我目前正在使用 WAV,但我也对如何将其用于 MP3,如果不同的话)拆分为左右声道以馈送到两个独立的声道来自 P5.sound.js 库的快速傅立叶变换 (FFT)。

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

我将在下面分享我所拥有的,但老实说,并不多。有问题的所有内容都会在设置函数中进行,我已经在其中做了注释:

//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 专家,但我已经使用它足够多了,所以我认为必须有一种方法可以做到这一点,而无需整个 blob/文件读取。这些文档对于复杂的处理不是很有帮助,所以我在 p5.Sound 源代码中挖掘了一下,这就是我想出的:

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

Here's a working example - 单击 Canvas 可在 L/stereo/R 音频播放和 FFT 视觉效果之间切换。


说明:

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

在整个源代码中,有通过 sound.buffer.getChannelData() 进行单个 channel 操作的示例.起初我对访问未记录的属性持谨慎态度,但事实证明,由于 p5.Sound 在后台使用 WebAudio API,因此这个 buffer 实际上只是普通的旧 WebAudio AudioBuffer , getChannelData 方法是 well-documented .

上述方法的唯一缺点是 setBuffer 直接作用于 SoundFile 所以我要为每个要分离的 channel 再次加载文件,但是我'我确定有解决方法。

split 快乐!

关于javascript - 将立体声音频文件拆分为每个 channel 的 AudioNodes,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58826117/

相关文章:

javascript - polymer 中的 Firebase 共享身份验证

android - OpenSL - 音频播放器对象搜索不佳

javascript - 构造函数不起作用? P5.JS

javascript - 无法引用 setup() 中声明的变量

flash - ActionScript 3.0加载和播放多种声音

javascript - 如何在p5.js中动态调整绘图的高度和宽度?

javascript - 当某些字母发生变化时,如何在复数中找到单数?最好的方法是什么?

javascript - jQuery 基于单选验证输入文本控件

javascript - 您如何以编程方式告诉 HTML SELECT 下拉(例如,由于鼠标悬停)?

java - 如何使用 sleep 方法重复声音