Sunday, 15 August 2010

noise - java SourceDataLine sine waves clicks -



noise - java SourceDataLine sine waves clicks -

i want generate plain sine waves using javax.sound.sampled.sourcedataline. 1 constant frequency, works fine, there kind of clicking noise when changing frequency. doing wrong, can avoid ?

line.start(); final byte[] tonebuffer = new byte[sample_chunk]; while(run) { createsinewavebuffer(frequency, tonebuffer); line.write(tonebuffer, 0, tonebuffer.length); } line.drain(); line.close();

where

private double alpha = 0.0; private static final double step_alpha = (2.0*math.pi)/sample_rate; private void createsinewavebuffer(final double freq, final byte[] buffer) { for(int = 0; < buffer.length; ++i) { buffer[i] = (byte)(math.sin(freq*alpha)*127.0); alpha += step_alpha; if(alpha >= 2.0*math.pi) { alpha = 0.0; } } }

you experience click because when freq changes, whole sine wave shifted. illustration easier-to-draw triangle wave:

1 hz /\ /\ / / \ / \ / / \/ \/ .5 hz_ / \ / \ / / \_/

if switch between these @ arbitrary time:

/\ |\ / \ | \ / / \| \_/

there discontinuity, hear click.

this fundamentally because causing sudden jump sin(freq*alpha) sin(.5*freq*(alpha+step_alpha)). not derivative of input sin() changing discontinuously (which need alter frequency), value changing discontinuously.

the way around alter derivative of input sin(). can keeping counter increments based on frequency:

private void createsinewavebuffer(final double freq, final byte[] buffer) { for(int = 0; < buffer.length; ++i) { buffer[i] = (byte)(math.sin(alpha)*127.0); alpha += freq*step_alpha; if(alpha >= 2.0*math.pi) { alpha -= 2.0*math.pi; } } homecoming t; }

here have changed alpha increment @ rate controlled current freq.

back triangle example, like:

_ /\ / \ / \ / \ / \/ \

java noise javax.sound.sampled clicking

No comments:

Post a Comment