ima_enc.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. #include "ima_enc.h"
  2. CodecState mg;
  3. static int indexTable[16] = {
  4. -1, -1, -1, -1, 2, 4, 6, 8,
  5. -1, -1, -1, -1, 2, 4, 6, 8,
  6. };
  7. static int stepsizeTable[89] = {
  8. 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
  9. 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
  10. 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
  11. 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
  12. 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
  13. 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
  14. 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
  15. 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
  16. 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
  17. };
  18. void adpcm_init()
  19. {
  20. mg.index = 0;
  21. mg.valprev = 0;
  22. }
  23. void encode(CodecState* state, s16* input, int numSamples, u8* output)
  24. {
  25. s16 *inp; /* Input buffer pointer */
  26. u8 *outp; /* output buffer pointer */
  27. int val; /* Current input sample value */
  28. int sign; /* Current adpcm sign bit */
  29. int delta; /* Current adpcm output value */
  30. int diff; /* Difference between val and valprev */
  31. int step; /* Stepsize */
  32. int valpred; /* Predicted output value */
  33. int vpdiff; /* Current change to valpred */
  34. int index; /* Current step change index */
  35. int outputbuffer; /* place to keep previous 4-bit value */
  36. int bufferstep; /* toggle between outputbuffer/output */
  37. outp = output;
  38. inp = input;
  39. valpred = state->valprev;
  40. index = state->index;
  41. step = stepsizeTable[index];
  42. bufferstep = 1;
  43. for ( ; numSamples > 0 ; numSamples-- ) {
  44. val = *inp++;
  45. /* Step 1 - compute difference with previous value */
  46. diff = val - valpred;
  47. sign = (diff < 0) ? 8 : 0;
  48. if ( sign ) diff = (-diff);
  49. /* Step 2 - Divide and clamp */
  50. /* Note:
  51. ** This code *approximately* computes:
  52. ** delta = diff*4/step;
  53. ** vpdiff = (delta+0.5)*step/4;
  54. ** but in shift step bits are dropped. The net result of this is
  55. ** that even if you have fast mul/div hardware you cannot put it to
  56. ** good use since the fixup would be too expensive.
  57. */
  58. delta = 0;
  59. vpdiff = (step >> 3);
  60. if ( diff >= step ) {
  61. delta = 4;
  62. diff -= step;
  63. vpdiff += step;
  64. }
  65. step >>= 1;
  66. if ( diff >= step ) {
  67. delta |= 2;
  68. diff -= step;
  69. vpdiff += step;
  70. }
  71. step >>= 1;
  72. if ( diff >= step ) {
  73. delta |= 1;
  74. vpdiff += step;
  75. }
  76. /* Step 3 - Update previous value */
  77. if ( sign )
  78. valpred -= vpdiff;
  79. else
  80. valpred += vpdiff;
  81. /* Step 4 - Clamp previous value to 16 bits */
  82. if ( valpred > 32767 )
  83. valpred = 32767;
  84. else if ( valpred < -32768 )
  85. valpred = -32768;
  86. /* Step 5 - Assemble value, update index and step values */
  87. delta |= sign;
  88. index += indexTable[delta];
  89. if ( index < 0 ) index = 0;
  90. if ( index > 88 ) index = 88;
  91. step = stepsizeTable[index];
  92. /* Step 6 - Output value */
  93. #if 0
  94. if ( bufferstep ) {
  95. outputbuffer = (delta << 4) & 0xf0;
  96. } else {
  97. *outp++ = (delta & 0x0f) | outputbuffer;
  98. }
  99. #else
  100. if(bufferstep){
  101. outputbuffer=(delta&0x0f);
  102. }else{
  103. *outp++=((delta<<4)&0xf0)|outputbuffer;
  104. }
  105. #endif
  106. bufferstep = !bufferstep;
  107. }
  108. /* Output last step, if needed */
  109. if ( !bufferstep )
  110. *outp++ = outputbuffer;
  111. state->valprev = valpred;
  112. state->index = index;
  113. }
  114. void decode(CodecState* state, u8* input, int numSamples, s16* output)
  115. {
  116. u8 *inp; /* Input buffer pointer */
  117. s16 *outp; /* output buffer pointer */
  118. int sign; /* Current adpcm sign bit */
  119. int delta; /* Current adpcm output value */
  120. int step; /* Stepsize */
  121. int valpred; /* Predicted value */
  122. int vpdiff; /* Current change to valpred */
  123. int index; /* Current step change index */
  124. int inputbuffer; /* place to keep next 4-bit value */
  125. int bufferstep; /* toggle between inputbuffer/input */
  126. outp = output;
  127. inp = input;
  128. valpred = state->valprev;
  129. index = state->index;
  130. step = stepsizeTable[index];
  131. bufferstep = 0;
  132. for ( ; numSamples > 0 ; numSamples-- ) {
  133. /* Step 1 - get the delta value */
  134. if ( bufferstep ) {
  135. delta = inputbuffer & 0xf;
  136. } else {
  137. inputbuffer = *inp++;
  138. delta = (inputbuffer >> 4) & 0xf;
  139. }
  140. bufferstep = !bufferstep;
  141. /* Step 2 - Find new index value (for later) */
  142. index += indexTable[delta];
  143. if ( index < 0 ) index = 0;
  144. if ( index > 88 ) index = 88;
  145. /* Step 3 - Separate sign and magnitude */
  146. sign = delta & 8;
  147. delta = delta & 7;
  148. /* Step 4 - Compute difference and new predicted value */
  149. /*
  150. ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
  151. ** in adpcm_coder.
  152. */
  153. vpdiff = step >> 3;
  154. if ( delta & 4 ) vpdiff += step;
  155. if ( delta & 2 ) vpdiff += step>>1;
  156. if ( delta & 1 ) vpdiff += step>>2;
  157. if ( sign )
  158. valpred -= vpdiff;
  159. else
  160. valpred += vpdiff;
  161. /* Step 5 - clamp output value */
  162. if ( valpred > 32767 )
  163. valpred = 32767;
  164. else if ( valpred < -32768 )
  165. valpred = -32768;
  166. /* Step 6 - Update step value */
  167. step = stepsizeTable[index];
  168. /* Step 7 - Output value */
  169. *outp++ = valpred;
  170. }
  171. state->valprev = valpred;
  172. state->index = index;
  173. }