mix.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /*
  2. * some code for sample mixing
  3. * (C) notaz, 2006,2007
  4. *
  5. * This work is licensed under the terms of MAME license.
  6. * See COPYING file in the top-level directory.
  7. */
  8. #include "string.h"
  9. #define MAXOUT (+32767)
  10. #define MINOUT (-32768)
  11. /* limitter */
  12. #define Limit16(val) \
  13. if ((short)val != val) val = (val < 0 ? MINOUT : MAXOUT)
  14. int mix_32_to_16l_level;
  15. static struct iir2 { // 2-pole IIR
  16. int x[2]; // sample buffer
  17. int y[2]; // filter intermediates
  18. int i;
  19. } lfi2, rfi2;
  20. // NB ">>" rounds to -infinity, "/" to 0. To compensate the effect possibly use
  21. // "-(-y>>n)" (round to +infinity) instead of "y>>n" in places.
  22. // NB uses Q12 fixpoint; samples mustn't have more than 20 bits for this.
  23. #define QB 12
  24. // exponential moving average filter for DC filtering
  25. // y[n] = (x[n]-y[n-1])*(1/8192) (corner approx. 20Hz, gain 1)
  26. static inline int filter_exp(struct iir2 *fi2, int x)
  27. {
  28. int xf = (x<<QB) - fi2->y[0];
  29. fi2->y[0] += xf >> 13;
  30. xf -= xf >> 2; // level reduction to avoid clipping from overshoot
  31. return xf>>QB;
  32. }
  33. // unfiltered (for testing)
  34. static inline int filter_null(struct iir2 *fi2, int x)
  35. {
  36. return x;
  37. }
  38. #define mix_32_to_16l_stereo_core(dest, src, count, lv, fl) { \
  39. int l, r; \
  40. \
  41. for (; count > 0; count--) \
  42. { \
  43. l = r = *dest; \
  44. l += *src++ >> lv; \
  45. r += *src++ >> lv; \
  46. l = fl(&lfi2, l); \
  47. r = fl(&rfi2, r); \
  48. Limit16(l); \
  49. Limit16(r); \
  50. *dest++ = l; \
  51. *dest++ = r; \
  52. } \
  53. }
  54. void mix_32_to_16l_stereo_lvl(short *dest, int *src, int count)
  55. {
  56. mix_32_to_16l_stereo_core(dest, src, count, mix_32_to_16l_level, filter_exp);
  57. }
  58. void mix_32_to_16l_stereo(short *dest, int *src, int count)
  59. {
  60. mix_32_to_16l_stereo_core(dest, src, count, 0, filter_exp);
  61. }
  62. void mix_32_to_16_mono(short *dest, int *src, int count)
  63. {
  64. int l;
  65. for (; count > 0; count--)
  66. {
  67. l = *dest;
  68. l += *src++;
  69. l = filter_exp(&lfi2, l);
  70. Limit16(l);
  71. *dest++ = l;
  72. }
  73. }
  74. void mix_16h_to_32(int *dest_buf, short *mp3_buf, int count)
  75. {
  76. while (count--)
  77. {
  78. *dest_buf++ += *mp3_buf++ >> 1;
  79. }
  80. }
  81. void mix_16h_to_32_s1(int *dest_buf, short *mp3_buf, int count)
  82. {
  83. count >>= 1;
  84. while (count--)
  85. {
  86. *dest_buf++ += *mp3_buf++ >> 1;
  87. *dest_buf++ += *mp3_buf++ >> 1;
  88. mp3_buf += 1*2;
  89. }
  90. }
  91. void mix_16h_to_32_s2(int *dest_buf, short *mp3_buf, int count)
  92. {
  93. count >>= 1;
  94. while (count--)
  95. {
  96. *dest_buf++ += *mp3_buf++ >> 1;
  97. *dest_buf++ += *mp3_buf++ >> 1;
  98. mp3_buf += 3*2;
  99. }
  100. }
  101. void mix_reset(void)
  102. {
  103. memset(&lfi2, 0, sizeof(lfi2));
  104. memset(&rfi2, 0, sizeof(rfi2));
  105. }