Subversion Repositories Kolibri OS

Rev

Rev 1905 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.         synth.c: The functions for synthesizing samples, at the end of decoding.
  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, heavily dissected and rearranged by Thomas Orgis
  7. */
  8.  
  9. #include "mpg123lib_intern.h"
  10. #include "sample.h"
  11. #include "debug.h"
  12.  
  13. /*
  14.         Part 1: All synth functions that produce signed short.
  15.         That is:
  16.                 - synth_1to1 with cpu-specific variants (synth_1to1_i386, synth_1to1_i586 ...)
  17.                 - synth_1to1_mono and synth_1to1_m2s; which use fr->synths.plain[r_1to1][f_16].
  18.         Nearly every decoder variant has it's own synth_1to1, while the mono conversion is shared.
  19. */
  20.  
  21. #define SAMPLE_T short
  22. #define WRITE_SAMPLE(samples,sum,clip) WRITE_SHORT_SAMPLE(samples,sum,clip)
  23.  
  24. /* Part 1a: All straight 1to1 decoding functions */
  25. #define BLOCK 0x40 /* One decoding block is 64 samples. */
  26.  
  27. #define SYNTH_NAME synth_1to1
  28. #include "synth.h"
  29. #undef SYNTH_NAME
  30.  
  31. /* Mono-related synths; they wrap over _some_ synth_1to1. */
  32. #define SYNTH_NAME       fr->synths.plain[r_1to1][f_16]
  33. #define MONO_NAME        synth_1to1_mono
  34. #define MONO2STEREO_NAME synth_1to1_m2s
  35. #include "synth_mono.h"
  36. #undef SYNTH_NAME
  37. #undef MONO_NAME
  38. #undef MONO2STEREO_NAME
  39.  
  40. /* Now we have possibly some special synth_1to1 ...
  41.    ... they produce signed short; the mono functions defined above work on the special synths, too. */
  42.  
  43. #ifdef OPT_GENERIC_DITHER
  44. #define SYNTH_NAME synth_1to1_dither
  45. /* We need the accurate sample writing... */
  46. #undef WRITE_SAMPLE
  47. #define WRITE_SAMPLE(samples,sum,clip) WRITE_SHORT_SAMPLE_ACCURATE(samples,sum,clip)
  48.  
  49. #define USE_DITHER
  50. #include "synth.h"
  51. #undef USE_DITHER
  52. #undef SYNTH_NAME
  53.  
  54. #undef WRITE_SAMPLE
  55. #define WRITE_SAMPLE(samples,sum,clip) WRITE_SHORT_SAMPLE(samples,sum,clip)
  56.  
  57. #endif
  58.  
  59. #ifdef OPT_X86
  60. /* The i386-specific C code, here as short variant, later 8bit and float. */
  61. #define NO_AUTOINCREMENT
  62. #define SYNTH_NAME synth_1to1_i386
  63. #include "synth.h"
  64. #undef SYNTH_NAME
  65. /* i386 uses the normal mono functions. */
  66. #undef NO_AUTOINCREMENT
  67. #endif
  68.  
  69. #undef BLOCK /* Following functions are so special that they don't need this. */
  70.  
  71. #ifdef OPT_I586
  72. /* This is defined in assembler. */
  73. int synth_1to1_i586_asm(real *bandPtr, int channel, unsigned char *out, unsigned char *buffs, int *bo, real *decwin);
  74. /* This is just a hull to use the mpg123 handle. */
  75. int synth_1to1_i586(real *bandPtr, int channel, mpg123_handle *fr, int final)
  76. {
  77.         int ret;
  78.         if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
  79.  
  80.         ret = synth_1to1_i586_asm(bandPtr, channel, fr->buffer.data+fr->buffer.fill, fr->rawbuffs, &fr->bo, fr->decwin);
  81.         if(final) fr->buffer.fill += 128;
  82.         return ret;
  83. }
  84. #endif
  85.  
  86. #ifdef OPT_I586_DITHER
  87. /* This is defined in assembler. */
  88. int synth_1to1_i586_asm_dither(real *bandPtr, int channel, unsigned char *out, unsigned char *buffs, int *bo, real *decwin, float *dithernoise);
  89. /* This is just a hull to use the mpg123 handle. */
  90. int synth_1to1_i586_dither(real *bandPtr, int channel, mpg123_handle *fr, int final)
  91. {
  92.         int ret;
  93.         int bo_dither[2]; /* Temporary workaround? Could expand the asm code. */
  94.         if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
  95.  
  96.         /* Applying this hack, to change the asm only bit by bit (adding dithernoise pointer). */
  97.         bo_dither[0] = fr->bo;
  98.         bo_dither[1] = fr->ditherindex;
  99.         ret = synth_1to1_i586_asm_dither(bandPtr, channel, fr->buffer.data+fr->buffer.fill, fr->rawbuffs, bo_dither, fr->decwin, fr->dithernoise);
  100.         fr->bo          = bo_dither[0];
  101.         fr->ditherindex = bo_dither[1];
  102.  
  103.         if(final) fr->buffer.fill += 128;
  104.         return ret;
  105. }
  106. #endif
  107.  
  108. #ifdef OPT_3DNOW
  109. /* Those are defined in assembler. */
  110. void do_equalizer_3dnow(real *bandPtr,int channel, real equalizer[2][32]);
  111. int synth_1to1_3dnow_asm(real *bandPtr, int channel, unsigned char *out, unsigned char *buffs, int *bo, real *decwin);
  112. /* This is just a hull to use the mpg123 handle. */
  113. int synth_1to1_3dnow(real *bandPtr, int channel, mpg123_handle *fr, int final)
  114. {
  115.         int ret;
  116.  
  117.         if(fr->have_eq_settings) do_equalizer_3dnow(bandPtr,channel,fr->equalizer);
  118.  
  119.         /* this is in asm, can be dither or not */
  120.         /* uh, is this return from pointer correct? */
  121.         ret = (int) synth_1to1_3dnow_asm(bandPtr, channel, fr->buffer.data+fr->buffer.fill, fr->rawbuffs, &fr->bo, fr->decwin);
  122.         if(final) fr->buffer.fill += 128;
  123.         return ret;
  124. }
  125. #endif
  126.  
  127. #ifdef OPT_MMX
  128. /* This is defined in assembler. */
  129. int synth_1to1_MMX(real *bandPtr, int channel, short *out, short *buffs, int *bo, float *decwins);
  130. /* This is just a hull to use the mpg123 handle. */
  131. int synth_1to1_mmx(real *bandPtr, int channel, mpg123_handle *fr, int final)
  132. {
  133.         if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
  134.  
  135.         /* in asm */
  136.         synth_1to1_MMX(bandPtr, channel, (short*) (fr->buffer.data+fr->buffer.fill), (short *) fr->rawbuffs, &fr->bo, fr->decwins);
  137.         if(final) fr->buffer.fill += 128;
  138.         return 0;
  139. }
  140. #endif
  141.  
  142. #ifdef OPT_SSE
  143. #ifdef ACCURATE_ROUNDING
  144. /* This is defined in assembler. */
  145. int synth_1to1_sse_accurate_asm(real *window, real *b0, short *samples, int bo1);
  146. int synth_1to1_s_sse_accurate_asm(real *window, real *b0l, real *b0r, short *samples, int bo1);
  147. void dct64_real_sse(real *out0, real *out1, real *samples);
  148. /* This is just a hull to use the mpg123 handle. */
  149. int synth_1to1_sse(real *bandPtr,int channel, mpg123_handle *fr, int final)
  150. {
  151.         short *samples = (short *) (fr->buffer.data+fr->buffer.fill);  
  152.         real *b0, **buf;
  153.         int clip;
  154.         int bo1;
  155.  
  156.         if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
  157.  
  158.         if(!channel)
  159.         {
  160.                 fr->bo--;
  161.                 fr->bo &= 0xf;
  162.                 buf = fr->real_buffs[0];
  163.         }
  164.         else
  165.         {
  166.                 samples++;
  167.                 buf = fr->real_buffs[1];
  168.         }
  169.  
  170.         if(fr->bo & 0x1)
  171.         {
  172.                 b0 = buf[0];
  173.                 bo1 = fr->bo;
  174.                 dct64_real_sse(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
  175.         }
  176.         else
  177.         {
  178.                 b0 = buf[1];
  179.                 bo1 = fr->bo+1;
  180.                 dct64_real_sse(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
  181.         }
  182.  
  183.         clip = synth_1to1_sse_accurate_asm(fr->decwin, b0, samples, bo1);
  184.  
  185.         if(final) fr->buffer.fill += 128;
  186.  
  187.         return clip;
  188. }
  189.  
  190. int synth_1to1_stereo_sse(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)
  191. {
  192.         short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
  193.  
  194.         real *b0l, *b0r, **bufl, **bufr;
  195.         int bo1;
  196.         int clip;
  197.  
  198.         if(fr->have_eq_settings)
  199.         {
  200.                 do_equalizer(bandPtr_l,0,fr->equalizer);
  201.                 do_equalizer(bandPtr_r,1,fr->equalizer);
  202.         }
  203.  
  204.         fr->bo--;
  205.         fr->bo &= 0xf;
  206.         bufl = fr->real_buffs[0];
  207.         bufr = fr->real_buffs[1];
  208.  
  209.         if(fr->bo & 0x1)
  210.         {
  211.                 b0l = bufl[0];
  212.                 b0r = bufr[0];
  213.                 bo1 = fr->bo;
  214.                 dct64_real_sse(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);
  215.                 dct64_real_sse(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);
  216.         }
  217.         else
  218.         {
  219.                 b0l = bufl[1];
  220.                 b0r = bufr[1];
  221.                 bo1 = fr->bo+1;
  222.                 dct64_real_sse(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);
  223.                 dct64_real_sse(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
  224.         }
  225.  
  226.         clip = synth_1to1_s_sse_accurate_asm(fr->decwin, b0l, b0r, samples, bo1);
  227.  
  228.         fr->buffer.fill += 128;
  229.  
  230.         return clip;
  231. }
  232. #else
  233. /* This is defined in assembler. */
  234. void synth_1to1_sse_asm(real *bandPtr, int channel, short *samples, short *buffs, int *bo, real *decwin);
  235. /* This is just a hull to use the mpg123 handle. */
  236. int synth_1to1_sse(real *bandPtr, int channel, mpg123_handle *fr, int final)
  237. {
  238.         if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
  239.  
  240.         synth_1to1_sse_asm(bandPtr, channel, (short*) (fr->buffer.data+fr->buffer.fill), (short *) fr->rawbuffs, &fr->bo, fr->decwins);
  241.         if(final) fr->buffer.fill += 128;
  242.         return 0;
  243. }
  244. #endif
  245. #endif
  246.  
  247. #ifdef OPT_3DNOWEXT
  248. /* This is defined in assembler. */
  249. void synth_1to1_3dnowext_asm(real *bandPtr, int channel, short *samples, short *buffs, int *bo, real *decwin);
  250. /* This is just a hull to use the mpg123 handle. */
  251. int synth_1to1_3dnowext(real *bandPtr, int channel, mpg123_handle *fr, int final)
  252. {
  253.         if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
  254.  
  255.         synth_1to1_3dnowext_asm(bandPtr, channel, (short*) (fr->buffer.data+fr->buffer.fill), (short *) fr->rawbuffs, &fr->bo, fr->decwins);
  256.         if(final) fr->buffer.fill += 128;
  257.         return 0;
  258. }
  259. #endif
  260.  
  261. #ifdef OPT_X86_64
  262. #ifdef ACCURATE_ROUNDING
  263. /* Assembler routines. */
  264. int synth_1to1_x86_64_accurate_asm(real *window, real *b0, short *samples, int bo1);
  265. int synth_1to1_s_x86_64_accurate_asm(real *window, real *b0l, real *b0r, short *samples, int bo1);
  266. void dct64_real_x86_64(real *out0, real *out1, real *samples);
  267. /* Hull for C mpg123 API */
  268. int synth_1to1_x86_64(real *bandPtr,int channel, mpg123_handle *fr, int final)
  269. {
  270.         short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
  271.  
  272.         real *b0, **buf;
  273.         int bo1;
  274.         int clip;
  275.  
  276.         if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
  277.  
  278.         if(!channel)
  279.         {
  280.                 fr->bo--;
  281.                 fr->bo &= 0xf;
  282.                 buf = fr->real_buffs[0];
  283.         }
  284.         else
  285.         {
  286.                 samples++;
  287.                 buf = fr->real_buffs[1];
  288.         }
  289.  
  290.         if(fr->bo & 0x1)
  291.         {
  292.                 b0 = buf[0];
  293.                 bo1 = fr->bo;
  294.                 dct64_real_x86_64(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
  295.         }
  296.         else
  297.         {
  298.                 b0 = buf[1];
  299.                 bo1 = fr->bo+1;
  300.                 dct64_real_x86_64(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
  301.         }
  302.  
  303.         clip = synth_1to1_x86_64_accurate_asm(fr->decwin, b0, samples, bo1);
  304.  
  305.         if(final) fr->buffer.fill += 128;
  306.  
  307.         return clip;
  308. }
  309.  
  310. int synth_1to1_stereo_x86_64(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)
  311. {
  312.         short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
  313.  
  314.         real *b0l, *b0r, **bufl, **bufr;
  315.         int bo1;
  316.         int clip;
  317.  
  318.         if(fr->have_eq_settings)
  319.         {
  320.                 do_equalizer(bandPtr_l,0,fr->equalizer);
  321.                 do_equalizer(bandPtr_r,1,fr->equalizer);
  322.         }
  323.  
  324.         fr->bo--;
  325.         fr->bo &= 0xf;
  326.         bufl = fr->real_buffs[0];
  327.         bufr = fr->real_buffs[1];
  328.  
  329.         if(fr->bo & 0x1)
  330.         {
  331.                 b0l = bufl[0];
  332.                 b0r = bufr[0];
  333.                 bo1 = fr->bo;
  334.                 dct64_real_x86_64(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);
  335.                 dct64_real_x86_64(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);
  336.         }
  337.         else
  338.         {
  339.                 b0l = bufl[1];
  340.                 b0r = bufr[1];
  341.                 bo1 = fr->bo+1;
  342.                 dct64_real_x86_64(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);
  343.                 dct64_real_x86_64(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
  344.         }
  345.  
  346.         clip = synth_1to1_s_x86_64_accurate_asm(fr->decwin, b0l, b0r, samples, bo1);
  347.  
  348.         fr->buffer.fill += 128;
  349.  
  350.         return clip;
  351. }
  352. #else
  353. /* This is defined in assembler. */
  354. int synth_1to1_x86_64_asm(short *window, short *b0, short *samples, int bo1);
  355. int synth_1to1_s_x86_64_asm(short *window, short *b0l, short *b0r, short *samples, int bo1);
  356. void dct64_x86_64(short *out0, short *out1, real *samples);
  357. /* This is just a hull to use the mpg123 handle. */
  358. int synth_1to1_x86_64(real *bandPtr,int channel, mpg123_handle *fr, int final)
  359. {
  360.         short *samples = (short *) (fr->buffer.data+fr->buffer.fill);  
  361.         short *b0, **buf;
  362.         int clip;
  363.         int bo1;
  364.  
  365.         if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
  366.  
  367.         if(!channel)
  368.         {
  369.                 fr->bo--;
  370.                 fr->bo &= 0xf;
  371.                 buf = fr->short_buffs[0];
  372.         }
  373.         else
  374.         {
  375.                 samples++;
  376.                 buf = fr->short_buffs[1];
  377.         }
  378.  
  379.         if(fr->bo & 0x1)
  380.         {
  381.                 b0 = buf[0];
  382.                 bo1 = fr->bo;
  383.                 dct64_x86_64(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
  384.         }
  385.         else
  386.         {
  387.                 b0 = buf[1];
  388.                 bo1 = fr->bo+1;
  389.                 dct64_x86_64(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
  390.         }
  391.  
  392.         clip = synth_1to1_x86_64_asm((short *)fr->decwins, b0, samples, bo1);
  393.  
  394.         if(final) fr->buffer.fill += 128;
  395.  
  396.         return clip;
  397. }
  398.  
  399. int synth_1to1_stereo_x86_64(real *bandPtr_l,real *bandPtr_r, mpg123_handle *fr)
  400. {
  401.         short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
  402.         short *b0l, *b0r, **bufl, **bufr;
  403.         int clip;
  404.         int bo1;
  405.  
  406.         if(fr->have_eq_settings)
  407.         {
  408.                 do_equalizer(bandPtr_l,0,fr->equalizer);
  409.                 do_equalizer(bandPtr_r,1,fr->equalizer);
  410.         }
  411.  
  412.         fr->bo--;
  413.         fr->bo &= 0xf;
  414.         bufl = fr->short_buffs[0];
  415.         bufr = fr->short_buffs[1];
  416.  
  417.         if(fr->bo & 0x1)
  418.         {
  419.                 b0l = bufl[0];
  420.                 b0r = bufr[0];
  421.                 bo1 = fr->bo;
  422.                 dct64_x86_64(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);
  423.                 dct64_x86_64(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);
  424.         }
  425.         else
  426.         {
  427.                 b0l = bufl[1];
  428.                 b0r = bufr[1];
  429.                 bo1 = fr->bo+1;
  430.                 dct64_x86_64(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);
  431.                 dct64_x86_64(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
  432.         }
  433.  
  434.         clip = synth_1to1_s_x86_64_asm((short *)fr->decwins, b0l, b0r, samples, bo1);
  435.  
  436.         fr->buffer.fill += 128;
  437.  
  438.         return clip;
  439. }
  440. #endif
  441. #endif
  442.  
  443. #ifdef OPT_ARM
  444. #ifdef ACCURATE_ROUNDING
  445. /* Assembler routines. */
  446. int synth_1to1_arm_accurate_asm(real *window, real *b0, short *samples, int bo1);
  447. /* Hull for C mpg123 API */
  448. int synth_1to1_arm(real *bandPtr,int channel, mpg123_handle *fr, int final)
  449. {
  450.         short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
  451.  
  452.         real *b0, **buf;
  453.         int bo1;
  454.         int clip;
  455.  
  456.         if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
  457.  
  458.         if(!channel)
  459.         {
  460.                 fr->bo--;
  461.                 fr->bo &= 0xf;
  462.                 buf = fr->real_buffs[0];
  463.         }
  464.         else
  465.         {
  466.                 samples++;
  467.                 buf = fr->real_buffs[1];
  468.         }
  469.  
  470.         if(fr->bo & 0x1)
  471.         {
  472.                 b0 = buf[0];
  473.                 bo1 = fr->bo;
  474.                 dct64(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
  475.         }
  476.         else
  477.         {
  478.                 b0 = buf[1];
  479.                 bo1 = fr->bo+1;
  480.                 dct64(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
  481.         }
  482.  
  483.         clip = synth_1to1_arm_accurate_asm(fr->decwin, b0, samples, bo1);
  484.  
  485.         if(final) fr->buffer.fill += 128;
  486.  
  487.         return clip;
  488. }
  489. #else
  490. /* Assembler routines. */
  491. int synth_1to1_arm_asm(real *window, real *b0, short *samples, int bo1);
  492. /* Hull for C mpg123 API */
  493. int synth_1to1_arm(real *bandPtr,int channel, mpg123_handle *fr, int final)
  494. {
  495.         short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
  496.  
  497.         real *b0, **buf;
  498.         int bo1;
  499.         int clip;
  500.  
  501.         if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
  502.  
  503.         if(!channel)
  504.         {
  505.                 fr->bo--;
  506.                 fr->bo &= 0xf;
  507.                 buf = fr->real_buffs[0];
  508.         }
  509.         else
  510.         {
  511.                 samples++;
  512.                 buf = fr->real_buffs[1];
  513.         }
  514.  
  515.         if(fr->bo & 0x1)
  516.         {
  517.                 b0 = buf[0];
  518.                 bo1 = fr->bo;
  519.                 dct64(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
  520.         }
  521.         else
  522.         {
  523.                 b0 = buf[1];
  524.                 bo1 = fr->bo+1;
  525.                 dct64(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
  526.         }
  527.  
  528.         clip = synth_1to1_arm_asm(fr->decwin, b0, samples, bo1);
  529.  
  530.         if(final) fr->buffer.fill += 128;
  531.  
  532.         return clip;
  533. }
  534. #endif
  535. #endif
  536.  
  537. #ifdef OPT_NEON
  538. #ifdef ACCURATE_ROUNDING
  539. /* This is defined in assembler. */
  540. int synth_1to1_neon_accurate_asm(real *window, real *b0, short *samples, int bo1);
  541. int synth_1to1_s_neon_accurate_asm(real *window, real *b0l, real *b0r, short *samples, int bo1);
  542. void dct64_real_neon(real *out0, real *out1, real *samples);
  543. /* Hull for C mpg123 API */
  544. int synth_1to1_neon(real *bandPtr,int channel, mpg123_handle *fr, int final)
  545. {
  546.         short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
  547.  
  548.         real *b0, **buf;
  549.         int bo1;
  550.         int clip;
  551.  
  552.         if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
  553.  
  554.         if(!channel)
  555.         {
  556.                 fr->bo--;
  557.                 fr->bo &= 0xf;
  558.                 buf = fr->real_buffs[0];
  559.         }
  560.         else
  561.         {
  562.                 samples++;
  563.                 buf = fr->real_buffs[1];
  564.         }
  565.  
  566.         if(fr->bo & 0x1)
  567.         {
  568.                 b0 = buf[0];
  569.                 bo1 = fr->bo;
  570.                 dct64_real_neon(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
  571.         }
  572.         else
  573.         {
  574.                 b0 = buf[1];
  575.                 bo1 = fr->bo+1;
  576.                 dct64_real_neon(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
  577.         }
  578.  
  579.         clip = synth_1to1_neon_accurate_asm(fr->decwin, b0, samples, bo1);
  580.  
  581.         if(final) fr->buffer.fill += 128;
  582.  
  583.         return clip;
  584. }
  585.  
  586. int synth_1to1_stereo_neon(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)
  587. {
  588.         short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
  589.  
  590.         real *b0l, *b0r, **bufl, **bufr;
  591.         int bo1;
  592.         int clip;
  593.  
  594.         if(fr->have_eq_settings)
  595.         {
  596.                 do_equalizer(bandPtr_l,0,fr->equalizer);
  597.                 do_equalizer(bandPtr_r,1,fr->equalizer);
  598.         }
  599.  
  600.         fr->bo--;
  601.         fr->bo &= 0xf;
  602.         bufl = fr->real_buffs[0];
  603.         bufr = fr->real_buffs[1];
  604.  
  605.         if(fr->bo & 0x1)
  606.         {
  607.                 b0l = bufl[0];
  608.                 b0r = bufr[0];
  609.                 bo1 = fr->bo;
  610.                 dct64_real_neon(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);
  611.                 dct64_real_neon(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);
  612.         }
  613.         else
  614.         {
  615.                 b0l = bufl[1];
  616.                 b0r = bufr[1];
  617.                 bo1 = fr->bo+1;
  618.                 dct64_real_neon(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);
  619.                 dct64_real_neon(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
  620.         }
  621.  
  622.         clip = synth_1to1_s_neon_accurate_asm(fr->decwin, b0l, b0r, samples, bo1);
  623.  
  624.         fr->buffer.fill += 128;
  625.  
  626.         return clip;
  627. }
  628. #else
  629. /* This is defined in assembler. */
  630. int synth_1to1_neon_asm(short *window, short *b0, short *samples, int bo1);
  631. int synth_1to1_s_neon_asm(short *window, short *b0l, short *b0r, short *samples, int bo1);
  632. void dct64_neon(short *out0, short *out1, real *samples);
  633. /* Hull for C mpg123 API */
  634. int synth_1to1_neon(real *bandPtr,int channel, mpg123_handle *fr, int final)
  635. {
  636.         short *samples = (short *) (fr->buffer.data+fr->buffer.fill);  
  637.         short *b0, **buf;
  638.         int clip;
  639.         int bo1;
  640.  
  641.         if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
  642.  
  643.         if(!channel)
  644.         {
  645.                 fr->bo--;
  646.                 fr->bo &= 0xf;
  647.                 buf = fr->short_buffs[0];
  648.         }
  649.         else
  650.         {
  651.                 samples++;
  652.                 buf = fr->short_buffs[1];
  653.         }
  654.  
  655.         if(fr->bo & 0x1)
  656.         {
  657.                 b0 = buf[0];
  658.                 bo1 = fr->bo;
  659.                 dct64_neon(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
  660.         }
  661.         else
  662.         {
  663.                 b0 = buf[1];
  664.                 bo1 = fr->bo+1;
  665.                 dct64_neon(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
  666.         }
  667.  
  668.         clip = synth_1to1_neon_asm((short *)fr->decwins, b0, samples, bo1);
  669.  
  670.         if(final) fr->buffer.fill += 128;
  671.  
  672.         return clip;
  673. }
  674.  
  675. int synth_1to1_stereo_neon(real *bandPtr_l,real *bandPtr_r, mpg123_handle *fr)
  676. {
  677.         short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
  678.         short *b0l, *b0r, **bufl, **bufr;
  679.         int clip;
  680.         int bo1;
  681.  
  682.         if(fr->have_eq_settings)
  683.         {
  684.                 do_equalizer(bandPtr_l,0,fr->equalizer);
  685.                 do_equalizer(bandPtr_r,1,fr->equalizer);
  686.         }
  687.  
  688.         fr->bo--;
  689.         fr->bo &= 0xf;
  690.         bufl = fr->short_buffs[0];
  691.         bufr = fr->short_buffs[1];
  692.  
  693.         if(fr->bo & 0x1)
  694.         {
  695.                 b0l = bufl[0];
  696.                 b0r = bufr[0];
  697.                 bo1 = fr->bo;
  698.                 dct64_neon(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);
  699.                 dct64_neon(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);
  700.         }
  701.         else
  702.         {
  703.                 b0l = bufl[1];
  704.                 b0r = bufr[1];
  705.                 bo1 = fr->bo+1;
  706.                 dct64_neon(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);
  707.                 dct64_neon(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
  708.         }
  709.  
  710.         clip = synth_1to1_s_neon_asm((short *)fr->decwins, b0l, b0r, samples, bo1);
  711.  
  712.         fr->buffer.fill += 128;
  713.  
  714.         return clip;
  715. }
  716. #endif
  717. #endif
  718.  
  719. #ifndef NO_DOWNSAMPLE
  720.  
  721. /*
  722.         Part 1b: 2to1 synth.
  723.         Only generic and i386 functions this time.
  724. */
  725. #define BLOCK 0x20 /* One decoding block is 32 samples. */
  726.  
  727. #define SYNTH_NAME synth_2to1
  728. #include "synth.h"
  729. #undef SYNTH_NAME
  730.  
  731. #ifdef OPT_DITHER /* Used for generic_dither and as fallback for i586_dither. */
  732. #define SYNTH_NAME synth_2to1_dither
  733. #define USE_DITHER
  734. #include "synth.h"
  735. #undef USE_DITHER
  736. #undef SYNTH_NAME
  737. #endif
  738.  
  739. #define SYNTH_NAME       fr->synths.plain[r_2to1][f_16]
  740. #define MONO_NAME        synth_2to1_mono
  741. #define MONO2STEREO_NAME synth_2to1_m2s
  742. #include "synth_mono.h"
  743. #undef SYNTH_NAME
  744. #undef MONO_NAME
  745. #undef MONO2STEREO_NAME
  746.  
  747. #ifdef OPT_X86
  748. #define NO_AUTOINCREMENT
  749. #define SYNTH_NAME synth_2to1_i386
  750. #include "synth.h"
  751. #undef SYNTH_NAME
  752. /* i386 uses the normal mono functions. */
  753. #undef NO_AUTOINCREMENT
  754. #endif
  755.  
  756. #undef BLOCK
  757.  
  758. /*
  759.         Part 1c: 4to1 synth.
  760.         Same procedure as above...
  761. */
  762. #define BLOCK 0x10 /* One decoding block is 16 samples. */
  763.  
  764. #define SYNTH_NAME synth_4to1
  765. #include "synth.h"
  766. #undef SYNTH_NAME
  767.  
  768. #ifdef OPT_DITHER
  769. #define SYNTH_NAME synth_4to1_dither
  770. #define USE_DITHER
  771. #include "synth.h"
  772. #undef USE_DITHER
  773. #undef SYNTH_NAME
  774. #endif
  775.  
  776. #define SYNTH_NAME       fr->synths.plain[r_4to1][f_16] /* This is just for the _i386 one... gotta check if it is really useful... */
  777. #define MONO_NAME        synth_4to1_mono
  778. #define MONO2STEREO_NAME synth_4to1_m2s
  779. #include "synth_mono.h"
  780. #undef SYNTH_NAME
  781. #undef MONO_NAME
  782. #undef MONO2STEREO_NAME
  783.  
  784. #ifdef OPT_X86
  785. #define NO_AUTOINCREMENT
  786. #define SYNTH_NAME synth_4to1_i386
  787. #include "synth.h"
  788. #undef SYNTH_NAME
  789. /* i386 uses the normal mono functions. */
  790. #undef NO_AUTOINCREMENT
  791. #endif
  792.  
  793. #undef BLOCK
  794.  
  795. #endif /* NO_DOWNSAMPLE */
  796.  
  797. #ifndef NO_NTOM
  798. /*
  799.         Part 1d: ntom synth.
  800.         Same procedure as above... Just no extra play anymore, straight synth that uses the plain dct64.
  801. */
  802.  
  803. /* These are all in one header, there's no flexibility to gain. */
  804. #define SYNTH_NAME       synth_ntom
  805. #define MONO_NAME        synth_ntom_mono
  806. #define MONO2STEREO_NAME synth_ntom_m2s
  807. #include "synth_ntom.h"
  808. #undef SYNTH_NAME
  809. #undef MONO_NAME
  810. #undef MONO2STEREO_NAME
  811.  
  812. #endif
  813.  
  814. /* Done with short output. */
  815. #undef SAMPLE_T
  816. #undef WRITE_SAMPLE
  817.