6

我正在尝试实现立体声相位,如此处所述: http ://www.image-line.com/support/FLHelp/html/plugins/3x%20OSC.htm

“立体声相位 (SP) - 允许您为发生器的左右通道设置不同的相位偏移。偏移会导致振荡器从振荡器形状上的不同点开始(例如,从振荡器的最高值开始)正弦函数而不是在零点)。立体声相位偏移增加了所产生声音的丰富度和立体声全景。

我正在尝试为 OscillatorNode 实现这一目标。我唯一的想法是使用 createPeriodicWave (https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#dfn-createPeriodicWave)但是,从规范创建周期波的描述是超出我的理解,我没有通过谷歌找到任何例子。

破译 createPeriodicWave 描述的任何帮助都会有所帮助,就像有关如何实现此效果的任何其他想法一样。

谢谢!

4

6 回答 6

5

麦克莱伦等人,

这个答案帮助并随后让我进入了傅立叶的世界。在有关该主题的页面和一些维基百科的帮助下,我想我得到了方形和锯齿形图案,但三角形图案仍然让我望而却步。有人知道吗?

正如Nick Thompson 的这篇文章所解释的那样,它确实为您提供了相移的能力(尽管他对 AudioContext 方法的调用不同,但原理是相同的)。

至于方形和锯齿形图案:

var n = 4096;
var real = new Float32Array(n);
var imag = new Float32Array(n);
var ac = new AudioContext();
var osc = ac.createOscillator();

/* Pick a wave pattern */

/* Sine 
imag[1] = 1; */

/* Sawtooth 
for(x=1;x<n;x++)
    imag[x] = 2.0 / (Math.pow(-1, x) * Math.PI * x); */

/* Square */
for(x=1;x<n;x+=2)
    imag[x] = 4.0 / (Math.PI * x);

var wave = ac.createPeriodicWave(real, imag);

osc.setPeriodicWave(wave);  
osc.connect(ac.destination);
osc.start();
osc.stop(2); /* Have it stop after 2 seconds */

这将播放激活的模式,在这种情况下是方形模式。三角形公式会是什么样子?

于 2014-12-27T22:26:18.820 回答
3

一种简单的伪造方法是向左右通道添加单独的延迟节点,并为它们提供用户控制的延迟值。这将是我的方法,并且与相位设置具有或多或少相同的效果。

如果您想使用createPeriodicWave,不幸的是,您可能必须了解它背后有些困难的数学。

基本上,您首先必须将波形表示为正弦波“部分”的总和。所有的周期性波都有这种形式的一些表示。然后,一旦你找到了每个部分的相对幅度,你必须通过将每个部分乘以一个复数来分别对左右声道进行相移。您可以在此处阅读有关将周期波表示为正弦波总和的更多详细信息:http: //music.columbia.edu/cmc/musicandcomputers/chapter3/03_03.php

与使用 a 相比,使用createPeriodicWave具有显着优势BufferSourceNodecreatePeriodicWave波形将自动避免混叠。如果您在缓冲区中“手动”生成波形,则很难避免混叠。

于 2014-01-02T23:53:11.777 回答
2

我认为不可能使用OscillatorNode.

一种方法是使用context.createBuffer并生成一个正弦波缓冲区(或您想要的任何类型的波)并将其设置为 a 的缓冲区BufferSourceNode,然后offset在其start()方法中使用参数。但是您需要以秒为单位计算样本偏移量。

var buffer = context.createBuffer(1,1024,44100);

var data = buffer.getChannelData(0);

for(var i=0; i < data.length; i++){
    //generate waveform
}

var osc = context.createBufferSourceNode();
osc.buffer = buffer;
osc.loop = true;

osc.connect(context.destination);
osc.start(time, offset in seconds);
于 2013-09-04T16:26:01.847 回答
0

从这篇关于Wolfram的文章来看,三角波可以这样建立:

/* Triangle */
for(x=1;x<n;x+=2) 
    imag[x] = 8.0 / Math.pow(Math.PI, 2) * Math.pow(-1, (x-1)/2) / Math.pow(x, 2) * Math.sin(Math.PI * x);

顺便说一句,维基百科页面也很有帮助,它实际上显示了傅立叶结构的工作原理。

于 2014-12-27T22:44:50.883 回答
0

使用 Chrome 66 添加AudioWorklet的 's,您可以编写声音处理程序,就像现在不推荐使用的ScriptProcessorNode.

我使用它创建了一个便利库,它是一个普通的 WebAudio API OscillatorNode,它的相位(除其他外)也可以变化。你可以在这里找到

const context = new AudioContext()
context.audioWorklet.addModule("worklet.js").then(() => {
  const osc = new BetterOscillator(context)
  osc.parameters.get("phase").value = Math.PI / 4
  osc.connect(context.destination)
  osc.start()
}
于 2018-10-04T15:14:52.627 回答
0
function getTriangleWave(imag, n) {
    for (var i = 1; i < n; i+=2) {
      imag[i] = (8*Math.sin(i*Math.PI/2))/(Math.pow((Math.PI*i), 2));
    }
    return imag;
}
于 2017-07-05T21:17:37.800 回答