javascript - Web 音频 API 中的自定义波形

标签 javascript audio signal-processing web-audio-api

我正在研究这篇很棒的文章:https://jackschaedler.github.io/circles-sines-signals/dft_introduction.html

我想使用 Web Audio API 的 PeriodicWave 对象来实现这个演示:enter image description here

但是,当我使用这些设置设置周期波时:

 var real = new Float32Array([0,0,1,0,1]);
 var imag = new Float32Array(real.length);
 var customWave = context.createPeriodicWave(real,imag);
 osc.setPeriodicWave(customWave);

我输出一个看起来像这样的波:

enter image description here 这是完整的代码:http://jsbin.com/zaqojavixo/4/edit 要查看波形,请按几次播放声音。

我相信这些应该匹配,所以这是我的问题:

  1. 我是否遗漏了一些关于理论的基本知识,或者我只是错误地实现了它? PeriodicWave 对象是否应该做与文章中说明的相同的事情?
  2. 如果我采用了错误的方法,我将如何在 Web Audio API 中实现此图表?通过将两个不同频率的不同正弦波连接到同一增益节点,我已经能够在下面进行匹配 - 这与使用 PeriodicWave 对象有何不同?
  3. 我是 DSP 和 Web Audio API 的新手 - 如果有任何建议阅读,我将不胜感激!
  4. 其次,在我的示例中,在将正确的数据绘制到 Canvas 之前,我必须按下“播放声音”按钮几次 - 分析器似乎在振荡器后面,即使 analyser.getFloatTimeDomainData() 是在我启动振荡器后调用我,对这里发生的事情有什么想法吗?

编辑:如评论中所述,我的图表是颠倒的(在 Canvas 上 0,0 是左上角)。

最佳答案

请注意,第一个数组定义余弦项,第二个数组定义正弦项:

The real parameter represents an array of cosine terms (traditionally the A terms). In audio terminology, the first element (index 0) is the DC-offset of the periodic waveform. The second element (index 1) represents the fundamental frequency. The third element represents the first overtone, and so on. The first element is ignored and implementations must set it to zero internally.

The imag parameter represents an array of sine terms (traditionally the B terms). The first element (index 0) should be set to zero (and will be ignored) since this term does not exist in the Fourier series. The second element (index 1) represents the fundamental frequency. The third element represents the first overtone, and so on.

Source

你会看到你得到了预期的波形但是“颠倒了”(由于@Julian 在他的回答中指出了这一点而被颠倒了 - 在下面修复):

snap

(我在这里内联了你的代码,交换了数组:)
更新修复了原始代码中的绘图问题

//setup audio context
window.AudioContext = window.AudioContext || window.webkitAudioContext;
var context = new window.AudioContext();

//create nodes
var osc; //create in event listener so we can press the button more than once
var masterGain = context.createGain();
var analyser = context.createAnalyser();

//routing
masterGain.connect(analyser);
analyser.connect(context.destination);

var isPlaying = false;

//draw function for canvas
function drawWave(analyser, ctx) {
  
  var buffer = new Float32Array(1024),
      w = ctx.canvas.width;
  
  ctx.strokeStyle = "#777";
  ctx.setTransform(1,0,0,-1,0,100.5); // flip y-axis and translate to center
  ctx.lineWidth = 2;
  
  (function loop() {
    analyser.getFloatTimeDomainData(buffer);
    
    ctx.clearRect(0, -100, w, ctx.canvas.height);

    ctx.beginPath();
    ctx.moveTo(0, buffer[0] * 90);
    for (var x = 2; x < w; x += 2) ctx.lineTo(x, buffer[x] * 90);
    ctx.stroke();
    
    if (isPlaying) requestAnimationFrame(loop)
  })();
}

//button trigger
$(function() {  
  var c = document.getElementById('scope'),
      ctx = c.getContext("2d");
  
  c.height = 200;
  c.width = 600;
  
  // make 0-line permanent as background
  ctx.moveTo(0, 100.5);
  ctx.lineTo(c.width, 100.5);
  ctx.stroke();
  c.style.backgroundImage = "url(" + c.toDataURL() + ")";
  
  $('button').on('mousedown', function() {
    osc = context.createOscillator();
    //osc settings
    osc.frequency.value = 220;
    var imag= new Float32Array([0,0,1,0,1]);   // sine
    var real = new Float32Array(imag.length);  // cos
    var customWave = context.createPeriodicWave(real, imag);  // cos,sine
    osc.setPeriodicWave(customWave);

    osc.connect(masterGain);
    osc.start();
    isPlaying = true;
    
    drawWave(analyser, ctx);
  });

  $('button').on('mouseup', function() {
    isPlaying = false;
    osc.stop();
  }); 
});
button {position:fixed;left:10px;top:10px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Play the sound</button>
<canvas id='scope'></canvas>

关于javascript - Web 音频 API 中的自定义波形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30631595/

相关文章:

c++ - 在 C++ 中在 Windows 中播放样本缓冲区的最常见方法是什么?

machine-learning - 语音识别实验在训练期间崩溃

javascript - 在 JavaScript 中使用 XMLHttpRequest 加载音频

javascript - 允许 typeahead,js 自动完成文本中的单词,而不仅仅是下拉列表中的单个值

Python 将音频文件转换为 MP3

javascript - Javascript HTML5播放器-添加停止

c# - 没有从 Exocortex FFT 获得预期的输出

linux - 比较录音

c# - 将 C# 二维数组格式化为 Javascript

javascript - 排序时使空值始终在最后