Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.         synth.h: generic synth functions
  3.  
  4.         copyright 1995-2008 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 Michael Hipp, generalized by Thomas Orgis
  7.  
  8.         This header is used multiple times to create different variants of these functions.
  9.         See decode.c and friends.
  10.         Hint: BLOCK, MONO_NAME, MONO2STEREO_NAME, SYNTH_NAME and SAMPLE_T as well as WRITE_SAMPLE do vary.
  11.  
  12.         Thomas looked closely at the decode_1to1, decode_2to1 and decode_4to1 contents, seeing that they are too similar to be separate files.
  13.         This is what resulted...
  14.  
  15.         Basically, you need one set of these functions for each output sample type.
  16.         That currently means signed short, 8bit or float/double; though unsigned short may come, too.
  17.  
  18.         Define NO_AUTOINCREMENT i386 code that shall not rely on autoincrement.
  19.         Actual benefit of this has to be examined; may apply to specific (old) compilers, only.
  20. */
  21.  
  22.  
  23. /* Main synth function, uses the plain dct64 or dct64_i386. */
  24. int SYNTH_NAME(real *bandPtr, int channel, mpg123_handle *fr, int final)
  25. {
  26. #ifndef NO_AUTOINCREMENT
  27. #define BACKPEDAL 0x10 /* We use autoincrement and thus need this re-adjustment for window/b0. */
  28. #define MY_DCT64 dct64
  29. #else
  30. #define BACKPEDAL 0x00 /* i386 code does not need that. */
  31. #define MY_DCT64 dct64_i386
  32. #endif
  33.         static const int step = 2;
  34.         SAMPLE_T *samples = (SAMPLE_T *) (fr->buffer.data + fr->buffer.fill);
  35.  
  36.         real *b0, **buf; /* (*buf)[0x110]; */
  37.         int clip = 0;
  38.         int bo1;
  39.  
  40.         if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
  41.  
  42.         if(!channel)
  43.         {
  44.                 fr->bo--;
  45.                 fr->bo &= 0xf;
  46.                 buf = fr->real_buffs[0];
  47.         }
  48.         else
  49.         {
  50. #ifdef USE_DITHER
  51.                 /* We always go forward 32 dither points (and back again for the second channel),
  52.                    (re)sampling the noise the same way as the original signal. */
  53.                 fr->ditherindex -= 32;
  54. #endif
  55.                 samples++;
  56.                 buf = fr->real_buffs[1];
  57.         }
  58. #ifdef USE_DITHER
  59.         /* We check only once for the overflow of dither index here ...
  60.            this wraps differently than the original i586 dither code, in theory (but when DITHERSIZE % BLOCK/2 == 0 it's the same). */
  61.         if(DITHERSIZE-fr->ditherindex < 32) fr->ditherindex = 0;
  62.         /* And we define a macro for the dither action... */
  63.         #define ADD_DITHER(fr,sum) sum+=fr->dithernoise[fr->ditherindex]; fr->ditherindex += 64/BLOCK;
  64. #else
  65.         #define ADD_DITHER(fr,sum)
  66. #endif
  67.  
  68.         if(fr->bo & 0x1)
  69.         {
  70.                 b0 = buf[0];
  71.                 bo1 = fr->bo;
  72.                 MY_DCT64(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
  73.         }
  74.         else
  75.         {
  76.                 b0 = buf[1];
  77.                 bo1 = fr->bo+1;
  78.                 MY_DCT64(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
  79.         }
  80.  
  81.         {
  82.                 register int j;
  83.                 real *window = fr->decwin + 16 - bo1;
  84.  
  85.                 for(j=(BLOCK/4); j; j--, b0+=0x400/BLOCK-BACKPEDAL, window+=0x800/BLOCK-BACKPEDAL, samples+=step)
  86.                 {
  87.                         real sum;
  88. #ifndef NO_AUTOINCREMENT
  89.                         sum  = REAL_MUL_SYNTH(*window++, *b0++);
  90.                         sum -= REAL_MUL_SYNTH(*window++, *b0++);
  91.                         sum += REAL_MUL_SYNTH(*window++, *b0++);
  92.                         sum -= REAL_MUL_SYNTH(*window++, *b0++);
  93.                         sum += REAL_MUL_SYNTH(*window++, *b0++);
  94.                         sum -= REAL_MUL_SYNTH(*window++, *b0++);
  95.                         sum += REAL_MUL_SYNTH(*window++, *b0++);
  96.                         sum -= REAL_MUL_SYNTH(*window++, *b0++);
  97.                         sum += REAL_MUL_SYNTH(*window++, *b0++);
  98.                         sum -= REAL_MUL_SYNTH(*window++, *b0++);
  99.                         sum += REAL_MUL_SYNTH(*window++, *b0++);
  100.                         sum -= REAL_MUL_SYNTH(*window++, *b0++);
  101.                         sum += REAL_MUL_SYNTH(*window++, *b0++);
  102.                         sum -= REAL_MUL_SYNTH(*window++, *b0++);
  103.                         sum += REAL_MUL_SYNTH(*window++, *b0++);
  104.                         sum -= REAL_MUL_SYNTH(*window++, *b0++);
  105. #else
  106.                         sum  = REAL_MUL_SYNTH(window[0x0], b0[0x0]);
  107.                         sum -= REAL_MUL_SYNTH(window[0x1], b0[0x1]);
  108.                         sum += REAL_MUL_SYNTH(window[0x2], b0[0x2]);
  109.                         sum -= REAL_MUL_SYNTH(window[0x3], b0[0x3]);
  110.                         sum += REAL_MUL_SYNTH(window[0x4], b0[0x4]);
  111.                         sum -= REAL_MUL_SYNTH(window[0x5], b0[0x5]);
  112.                         sum += REAL_MUL_SYNTH(window[0x6], b0[0x6]);
  113.                         sum -= REAL_MUL_SYNTH(window[0x7], b0[0x7]);
  114.                         sum += REAL_MUL_SYNTH(window[0x8], b0[0x8]);
  115.                         sum -= REAL_MUL_SYNTH(window[0x9], b0[0x9]);
  116.                         sum += REAL_MUL_SYNTH(window[0xA], b0[0xA]);
  117.                         sum -= REAL_MUL_SYNTH(window[0xB], b0[0xB]);
  118.                         sum += REAL_MUL_SYNTH(window[0xC], b0[0xC]);
  119.                         sum -= REAL_MUL_SYNTH(window[0xD], b0[0xD]);
  120.                         sum += REAL_MUL_SYNTH(window[0xE], b0[0xE]);
  121.                         sum -= REAL_MUL_SYNTH(window[0xF], b0[0xF]);
  122. #endif
  123.  
  124.                         ADD_DITHER(fr,sum)
  125.                         WRITE_SAMPLE(samples,sum,clip);
  126.                 }
  127.  
  128.                 {
  129.                         real sum;
  130.                         sum  = REAL_MUL_SYNTH(window[0x0], b0[0x0]);
  131.                         sum += REAL_MUL_SYNTH(window[0x2], b0[0x2]);
  132.                         sum += REAL_MUL_SYNTH(window[0x4], b0[0x4]);
  133.                         sum += REAL_MUL_SYNTH(window[0x6], b0[0x6]);
  134.                         sum += REAL_MUL_SYNTH(window[0x8], b0[0x8]);
  135.                         sum += REAL_MUL_SYNTH(window[0xA], b0[0xA]);
  136.                         sum += REAL_MUL_SYNTH(window[0xC], b0[0xC]);
  137.                         sum += REAL_MUL_SYNTH(window[0xE], b0[0xE]);
  138.  
  139.                         ADD_DITHER(fr,sum)
  140.                         WRITE_SAMPLE(samples,sum,clip);
  141.                         samples += step;
  142.                         b0-=0x400/BLOCK;
  143.                         window-=0x800/BLOCK;
  144.                 }
  145.                 window += bo1<<1;
  146.  
  147.                 for(j=(BLOCK/4)-1; j; j--, b0-=0x400/BLOCK+BACKPEDAL, window-=0x800/BLOCK-BACKPEDAL, samples+=step)
  148.                 {
  149.                         real sum;
  150. #ifndef NO_AUTOINCREMENT
  151.                         sum = -REAL_MUL_SYNTH(*(--window), *b0++);
  152.                         sum -= REAL_MUL_SYNTH(*(--window), *b0++);
  153.                         sum -= REAL_MUL_SYNTH(*(--window), *b0++);
  154.                         sum -= REAL_MUL_SYNTH(*(--window), *b0++);
  155.                         sum -= REAL_MUL_SYNTH(*(--window), *b0++);
  156.                         sum -= REAL_MUL_SYNTH(*(--window), *b0++);
  157.                         sum -= REAL_MUL_SYNTH(*(--window), *b0++);
  158.                         sum -= REAL_MUL_SYNTH(*(--window), *b0++);
  159.                         sum -= REAL_MUL_SYNTH(*(--window), *b0++);
  160.                         sum -= REAL_MUL_SYNTH(*(--window), *b0++);
  161.                         sum -= REAL_MUL_SYNTH(*(--window), *b0++);
  162.                         sum -= REAL_MUL_SYNTH(*(--window), *b0++);
  163.                         sum -= REAL_MUL_SYNTH(*(--window), *b0++);
  164.                         sum -= REAL_MUL_SYNTH(*(--window), *b0++);
  165.                         sum -= REAL_MUL_SYNTH(*(--window), *b0++);
  166.                         sum -= REAL_MUL_SYNTH(*(--window), *b0++);
  167. #else
  168.                         sum = -REAL_MUL_SYNTH(window[-0x1], b0[0x0]);
  169.                         sum -= REAL_MUL_SYNTH(window[-0x2], b0[0x1]);
  170.                         sum -= REAL_MUL_SYNTH(window[-0x3], b0[0x2]);
  171.                         sum -= REAL_MUL_SYNTH(window[-0x4], b0[0x3]);
  172.                         sum -= REAL_MUL_SYNTH(window[-0x5], b0[0x4]);
  173.                         sum -= REAL_MUL_SYNTH(window[-0x6], b0[0x5]);
  174.                         sum -= REAL_MUL_SYNTH(window[-0x7], b0[0x6]);
  175.                         sum -= REAL_MUL_SYNTH(window[-0x8], b0[0x7]);
  176.                         sum -= REAL_MUL_SYNTH(window[-0x9], b0[0x8]);
  177.                         sum -= REAL_MUL_SYNTH(window[-0xA], b0[0x9]);
  178.                         sum -= REAL_MUL_SYNTH(window[-0xB], b0[0xA]);
  179.                         sum -= REAL_MUL_SYNTH(window[-0xC], b0[0xB]);
  180.                         sum -= REAL_MUL_SYNTH(window[-0xD], b0[0xC]);
  181.                         sum -= REAL_MUL_SYNTH(window[-0xE], b0[0xD]);
  182.                         sum -= REAL_MUL_SYNTH(window[-0xF], b0[0xE]);
  183.                         sum -= REAL_MUL_SYNTH(window[-0x0], b0[0xF]); /* Is that right? 0x0? Just wondering... */
  184. #endif
  185.                         ADD_DITHER(fr,sum)
  186.                         WRITE_SAMPLE(samples,sum,clip);
  187.                 }
  188.         }
  189.  
  190.         if(final) fr->buffer.fill += BLOCK*sizeof(SAMPLE_T);
  191.  
  192.         return clip;
  193. #undef ADD_DITHER
  194. #undef BACKPEDAL
  195. #undef MY_DCT64
  196. }
  197.