Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.         dither: Generate shaped noise for dithering
  3.  
  4.         copyright 2009 by the mpg123 project - free software under the terms of the LGPL 2.1
  5.         see COPYING and AUTHORS files in distribution or http://mpg123.org
  6.         initially written by Taihei Monma
  7. */
  8.  
  9. #include "config.h"
  10. #include "compat.h"
  11. #include "dither.h"
  12.  
  13. static const uint32_t init_seed = 2463534242UL;
  14.  
  15. #define LAP 100
  16.  
  17. /*
  18.         xorshift random number generator, with output scaling to [-0.5, 0.5]
  19.         This is the white noise...
  20.         See http://www.jstatsoft.org/v08/i14/paper on XOR shift random number generators.
  21. */
  22. static float rand_xorshift32(uint32_t *seed)
  23. {
  24.         union
  25.         {
  26.                 uint32_t i;
  27.                 float f;
  28.         } fi;
  29.        
  30.         fi.i = *seed;
  31.         fi.i ^= (fi.i<<13);
  32.         fi.i ^= (fi.i>>17);
  33.         fi.i ^= (fi.i<<5);
  34.         *seed = fi.i;
  35.        
  36.         /* scale the number to [-0.5, 0.5] */
  37. #ifdef IEEE_FLOAT
  38.         fi.i = (fi.i>>9)|0x3f800000;
  39.         fi.f -= 1.5f;
  40. #else
  41.         fi.f = (double)fi.i / 4294967295.0;
  42.         fi.f -= 0.5f;
  43. #endif
  44.         return fi.f;
  45. }
  46.  
  47. static void white_noise(float *table, size_t count)
  48. {
  49.         size_t i;
  50.         uint32_t seed = init_seed;
  51.        
  52.         for(i=0; i<count; ++i)
  53.         table[i] = rand_xorshift32(&seed);
  54. }
  55.  
  56. static void tpdf_noise(float *table, size_t count)
  57. {
  58.         size_t i;
  59.         uint32_t seed = init_seed;
  60.        
  61.         for(i=0; i<count; ++i)
  62.         table[i] = rand_xorshift32(&seed) + rand_xorshift32(&seed);
  63. }
  64.  
  65. static void highpass_tpdf_noise(float *table, size_t count)
  66. {
  67.         size_t i;
  68.         uint32_t seed = init_seed;
  69.         /* Ensure some minimum lap for keeping the high-pass filter circular. */
  70.         size_t lap = count > 2*LAP ? LAP : count/2;
  71.  
  72.         float input_noise;
  73.         float xv[9], yv[9];
  74.  
  75.         for(i=0;i<9;i++)
  76.         {
  77.                 xv[i] = yv[i] = 0.0f;
  78.         }
  79.  
  80.         for(i=0;i<count+lap;i++)
  81.         {
  82.                 if(i==count) seed=init_seed;
  83.                
  84.                 /* generate and add 2 random numbers, to make a TPDF noise distribution */
  85.                 input_noise = rand_xorshift32(&seed) + rand_xorshift32(&seed);
  86.  
  87.                 /* apply 8th order Chebyshev high-pass IIR filter */
  88.                 /* Coefficients are from http://www-users.cs.york.ac.uk/~fisher/mkfilter/trad.html
  89.                    Given parameters are: Chebyshev, Highpass, ripple=-1, order=8, samplerate=44100, corner1=19000 */
  90.                 xv[0] = xv[1]; xv[1] = xv[2]; xv[2] = xv[3]; xv[3] = xv[4]; xv[4] = xv[5]; xv[5] = xv[6]; xv[6] = xv[7]; xv[7] = xv[8];
  91.                 xv[8] = input_noise / 1.382814179e+07;
  92.                 yv[0] = yv[1]; yv[1] = yv[2]; yv[2] = yv[3]; yv[3] = yv[4]; yv[4] = yv[5]; yv[5] = yv[6]; yv[6] = yv[7]; yv[7] = yv[8];
  93.                 yv[8] = (xv[0] + xv[8]) - 8 * (xv[1] + xv[7]) + 28 * (xv[2] + xv[6])
  94.                                 - 56 * (xv[3] + xv[5]) + 70 * xv[4]
  95.                                 + ( -0.6706204984 * yv[0]) + ( -5.3720827038 * yv[1])
  96.                                 + (-19.0865382480 * yv[2]) + (-39.2831607860 * yv[3])
  97.                                 + (-51.2308985070 * yv[4]) + (-43.3590135780 * yv[5])
  98.                                 + (-23.2632305320 * yv[6]) + ( -7.2370122050 * yv[7]);
  99.                 if(i>=lap) table[i-lap] = yv[8] * 3.0f;
  100.         }
  101. }
  102.  
  103. void mpg123_noise(float* table, size_t count, enum mpg123_noise_type noisetype)
  104. {
  105.         switch(noisetype)
  106.         {
  107.                 case mpg123_white_noise: white_noise(table, count); break;
  108.                 case mpg123_tpdf_noise:  tpdf_noise(table, count);  break;
  109.                 case mpg123_highpass_tpdf_noise:
  110.                         highpass_tpdf_noise(table, count);
  111.                 break;
  112.         }
  113. }
  114.  
  115. /* Generate white noise and shape it with a high pass filter. */
  116. void dither_table_init(float *dithertable)
  117. {
  118.         highpass_tpdf_noise(dithertable, DITHERSIZE);
  119. }
  120.