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