[chuck-users] dithering with chuck

Adam Tindale adamtindale at hotmail.com
Sun Dec 10 18:17:24 EST 2006


Hi,

I didn't look through the code too carefully, but you description of  
dither is great. What I think may be happening here is that most  
audio programs don't handle floats as 16 bit numbers, but rather 32  
bit. They do this exactly because of what you demonstrate here, if  
you turn the gain down and then back up it would sound terrible. The  
larger internal precision allows the data (in this case your sound)  
to stay in tact and not introduce errors.

There is another complication. Floating point numbers aren't stored  
the same way that integers are, they are stored as a mantissa and  
exponent. This technique also combats the precision problem. What  
will happen is that the mantissa will stay the same and you are just  
twiddling the exponent bits. No loss of precision. You could  
definitely do this demonstration in chuck, and it is excellent, but I  
think we will have to hear from Ge, Spencer or Perry about exactly  
how much you will need to turn the gain down in order to achieve the  
desired effect.

Wikipedia gives a pretty good rundown on floating point representation.

http://en.wikipedia.org/wiki/Floating_point

I hope this helps.

--art


On 10-Dec-06, at 6:36 AM, eduard aylon wrote:

> 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
>
> _______________________________________________
> chuck-users mailing list
> chuck-users at lists.cs.princeton.edu
> https://lists.cs.princeton.edu/mailman/listinfo/chuck-users





More information about the chuck-users mailing list