How to set phase offset for OscillatorNode in web audio API?

I am trying to implement Stereo Phase as described here: http://www.image-line.com/support/FLHelp/html/plugins/3x%20OSC.htm

"Stereo Phase (SP) - Allows you to set different phase offsets for the left and right channels of the oscillator. Offset causes the oscillator to start at a different point in the oscillator shape (for example, it starts at the highest sinusoidal value instead of the zero point). Stereo offset phase adds to the richness and stereo panorama of the audio signal. "

I am trying to achieve this for an OscillatorNode. My only idea is to use createPeriodicWave ( https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#dfn-createPeriodicWave ) However, the description of creating a periodic wave from the specification is above my understanding, and u I have not found examples through Google.

Any help in deciphering the createPeriodicWave description would be helpful, like any other ideas on how to achieve this effect.

Thanks!

+4
source share
5 answers

A simple fake way would be to add separate delay nodes to the left and right channels and give them user-controlled delay values. This will be my approach and will have more or less the same effect as setting the phase.

If you want to use createPeriodicWave , unfortunately, you will probably have to understand the complex math behind it.

Basically, you should first imagine your waveform as the sum of the "partial" sine waves. All periodic waves have some representation of this form. Then, as soon as you find the relative values โ€‹โ€‹of each partial, you will have to shift them individually along the left and right channels, multiplying them by a complex number. You can read more detailed information on representing periodic waves as sums of sine waves here: http://music.columbia.edu/cmc/musicandcomputers/chapter3/03_03.php

Using createPeriodicWave has a significant advantage over using BufferSourceNode : createPeriodicWave . The waveform will automatically avoid aliasing . It is quite difficult to avoid anti-aliasing if you generate signals โ€œmanuallyโ€ in the buffer.

+1
source

Mcclellan and others,

This answer helped and subsequently turned me into the world of Fourier. Using a related page and some Wikipedia, I think I got square and sawtooth patterns, but the triangle pattern still eludes me. Does anyone know?

It really gives you the ability to phase shift, as Nick Thompson explains this article (although he calls the AudioContext methods differently, the principle is the same).

Regarding square and sawtooth patterns:

 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 */ 

In this case, the activated pattern, square pattern will be played. What will be the formula of the triangle?

+4
source

I do not think it is possible to have a phase shift using OscillatorNode .

To do this, use context.createBuffer and create a sine wave buffer (or any type of wave you want), and set it as a buffer for BufferSourceNode , and then use the offset parameter in the start() method. But you need to calculate the sample offset in seconds.

 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); 
+2
source

According to the views of this article on Wolfram, a triangular wave can be installed as follows:

 /* 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); 

Also useful, by the way, is the Wikipedia page, which actually shows how the Fourier constructions work.

0
source
 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; } 
0
source

Source: https://habr.com/ru/post/1490142/


All Articles