actionscript-3apihaxesound-synthesis

How to generate sin wave in AS3 without clicks?


I have started using sound to synthesis audio, I don't know why I get those noisy clicks sounds within the sounds?

My loops is:

for(i in 0...2048)
{
var phase:Float = position / 44100.0 * Math.PI * 2;
position+=1;
sample = Math.sin(phase * v);   // where v varies between 200 to 400
event.data.writeFloat(sample); // left
event.data.writeFloat(sample); // right
}

Any idea?

EDIT

What I need to do is to interpolate frequency within the loop:

var phaserad:Float= 2*Math.PI/44100;
var delta:Float = current_v - new_v;
var p:Int= 2048;
for(i in 0...2048)
{
p--;
v = new_v + delta * (p / 2048); // v will interpolate from current_v to new_v
position += v * phaserad;
sample = Math.sin(position);    
event.data.writeFloat(sample); // left
event.data.writeFloat(sample); // right
}

current_v = new_v;

but, I couldn't hear anything, I tried another approach:

var delta:Float = current_v - new_v;
var p:Int= 2048;

for(i in 0...2048)
{
var phase:Float = position / 44100.0 * Math.PI * 2;
position+=1;

p--;
v = new_v + delta * (p / 2048); // v will interpolate from current_v to new_v

sample = Math.sin(phase * v);   // where v varies between 200 to 400
event.data.writeFloat(sample); // left
event.data.writeFloat(sample); // right
}

but, the frequency will keep going up, and it won't stop at expected new_v


Solution

  • You have your wave generator set about right, but the approach with saved position requires your v to be constant and position unaltered. Given your description of v, you change it during your playback somehow, but changing v results in sine form to be disrupted. So, instead of recalculating position from scratch, you should accumulate phase and add current shift based on v to receive an uninterrupted waveform.

    const phaserad:Number=2*Math.PI/44100;
    for(var i:int=0;i<2048;i++)
    {
        position+=v*phaserad; // requires this var to be "Number" type
        sample = Math.sin(position);   // where v varies between 200 to 400
        event.data.writeFloat(sample); // left
        event.data.writeFloat(sample); // right
    }