首页 > 解决方案 > 在 p5.js 中使用 audiocontext 作为音频输入

问题描述

我正在实现一个合成器,它使用音频 api 的节点来生成声音,我的目标是使用 p5 将其可视化。

我目前有一个脚本,可以用 fft 分析音频并用条形图可视化频率。我目前的音频输入是一首本地保存的歌曲,但我需要更改它,因此它使用音频上下文作为输入。目前我可以使用 p5 自己的方法 getAudioContext() 获取音频上下文,但是我不知道如何将其设置为可视化的输入。

我知道 API 有一个 createBuffer() 方法,但我还没有找到一种方法将它用作 p5 的输入。

var fft;
var button;
var song;
var slider;
var audiocontext;
var out;
var prue;
var source;


function preload(){
  song = loadSound("src/media/Chopin - Nocturne op.9 No.2.mp3");
  button = createButton("Play");
  button.mousePressed(togglePlaying);
  slider = createSlider(0,1,0.5,0.01);
  this.audiocontext = getAudioContext();
}

function setup() {
  createCanvas(windowWidth,windowHeight);
  fft = new p5.FFT(0.8);
  source = context.createBufferSource();
  widthBand = (width / 128);
  source.connect(context.destination);

}


function draw() {
  background(61);
  var spectrum = fft.analyze();
  noStroke();
  for (var i = 0; i<spectrum.length; i++) {
    var amp = spectrum[i];
    var y = map(amp, 0, 256, height, 0);
    fill(i, 255, 255);
    rect(i*widthBand,y,widthBand-2, height - y );
  }

  //Set Volume according to slider
  audiocontext.setVolume(slider.value());


}


//Play/Pause Button
 function togglePlaying(){
   if(!song.isPlaying()){
     song.play();
     button.html("Pause");
   }else if(song.isPlaying()){
     song.pause();
     button.html("Play");
   }
 }

任何帮助将不胜感激!

标签: javascriptprocessingweb-audio-apip5.js

解决方案


Audiocontext 本身不是输入,而是包含一个或多个输入节点(以及输出和连接等等)。P5 创建自己的 Audiocontext 并在其中运行。

因此,选项一:仅使用 p5 功能构建您的应用程序。这是一个功能强大的库,所有需要的工具(例如 AudioIn()、MonoSynth() 等)都应该可用。

方案二:先初始化p5,然后使用p5创建的audiocontext添加额外的节点,以后可以被p5使用。

var cnv, fft, audiocontext, osc;
//p5 setup.
function setup() {
    cnv = createCanvas();
    fft = new p5.FFT(0.8);
    audiocontext = getAudioContext(); //if p5.Audiocontext doesn't exist
                                      // then new is created. Let's make
                                      // it global.

    myCustomSetup();  //now we can create our own input nodes, filters...

    fft.setInput(osc); //after which we can connect fft to those created
                       //nodes
}

function myCustomSetup() {
    //p5 audiocontext is usable here, allowing to use full WebAudioApi
    //and connect all nodes, created here or by some p5 function. 
    osc = audiocontext.createOscillator();

}

推荐阅读