[chuck-users] dithering with chuck
eduard aylon
eduard.aylon at gmail.com
Sun Dec 10 09:36:54 EST 2006
Hello list,
This is probably not a question about chuck, but as I am trying to
explain how dither works to other people by using chuck I thought I
might post the question anyway.
Please correct me if I am wrong... In principle dither is used in
order to make quantization noise not perceivable. So, taking a 16bit
audio file down by 60dB and then up again by 60dB without applying
dither will cause quantization errors to be very audible. However
when applying dither (both when de-amplifying and amplifying) a hiss
maybe perceived but the signal should be recovered in a better way,
or at least the quantization error should be less perceivable.
In order to achieve this, I have implemented the following function
in chuck (note that at the moment I am not interested in noise
shaping techniques, but just adding "pure" white noise )
fun void change_gain_with_dither( float dB, string input_filename,
string output_filename )
{
16 => int bit_reso;
1 << (bit_reso-1) => int max;
.5/max => float noise_floor; // noise level at half LSB
<<< "noise floor:", noise_floor >>>;
Math.pow( 10., dB/20.) => float gain_factor;
<<<"changing gain to file", input_filename>>>;
<<<" amount in dB:", dB >>>;
<<<" amount linear:", gain_factor >>>;
<<<" dither:", "yes">>>;
<<<" output file:" , output_filename >>>;
sndbuf buf => dac;
buf.read( input_filename );
impulse p => WvOut audio => blackhole;
audio.aifFilename( output_filename );
now => time begin;
buf.length() +=> begin;
while( now < begin )
{
std.rand2f(-noise_floor, noise_floor ) => float dither;
(buf.last() + dither )*gain_factor => p.next;
1::samp => now;
}
audio.closeFile( output_filename );
}
However, this function seems to not give better results than the one
below, which doesn't take dither into account:
fun void change_gain_without_dither( float dB, string input_filename,
string output_filename )
{
Math.pow( 10., dB/20.) => float gain_factor;
<<<"changing gain to file", input_filename>>>;
<<<" amount in dB:", dB >>>;
<<<" amount linear:", gain_factor >>>;
<<<" dither:", "no">>>;
<<<" output file:" , output_filename >>>;
sndbuf buf => dac;
buf.read( input_filename );
impulse p => WvOut audio => blackhole;
audio.aifFilename( output_filename );
now => time begin;
buf.length() +=> begin;
while( now < begin )
{
buf.last()*gain_factor => p.next;
1::samp => now;
}
audio.closeFile( output_filename );
}
So from the next two options:
A) change_gain_without_dither( -60, file1, file2 );
change_gain_without_dither( 60, file2, file4 );
and
B) change_gain_with_dither( -60, file1, file3 );
change_gain_with_dither( 60, file3, file5 );
I would have expected B) giving "better" results than A), but in fact
I obtain even worse results, i.e.: same quantisation error + hiss.
So, in the end, I am pretty sure that my understanding of dither
might not be the correct one. Could anyone shred some light on this
subject?
thanks,
eduard
More information about the chuck-users
mailing list