dither_template.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /*
  2. * This file is part of libswresample
  3. *
  4. * libswresample is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2.1 of the License, or (at your option) any later version.
  8. *
  9. * libswresample is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public
  15. * License along with libswresample; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. #if defined(TEMPLATE_DITHER_DBL)
  19. # define RENAME(N) N ## _double
  20. # define DELEM double
  21. # define CLIP(v) while(0)
  22. #elif defined(TEMPLATE_DITHER_FLT)
  23. # define RENAME(N) N ## _float
  24. # define DELEM float
  25. # define CLIP(v) while(0)
  26. #elif defined(TEMPLATE_DITHER_S32)
  27. # define RENAME(N) N ## _int32
  28. # define DELEM int32_t
  29. # define CLIP(v) v = FFMAX(FFMIN(v, INT32_MAX), INT32_MIN)
  30. #elif defined(TEMPLATE_DITHER_S16)
  31. # define RENAME(N) N ## _int16
  32. # define DELEM int16_t
  33. # define CLIP(v) v = FFMAX(FFMIN(v, INT16_MAX), INT16_MIN)
  34. #else
  35. ERROR
  36. #endif
  37. void RENAME(swri_noise_shaping)(SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count){
  38. int pos = s->dither.ns_pos;
  39. int i, j, ch;
  40. int taps = s->dither.ns_taps;
  41. float S = s->dither.ns_scale;
  42. float S_1 = s->dither.ns_scale_1;
  43. av_assert2((taps&3) != 2);
  44. av_assert2((taps&3) != 3 || s->dither.ns_coeffs[taps] == 0);
  45. for (ch=0; ch<srcs->ch_count; ch++) {
  46. const float *noise = ((const float *)noises->ch[ch]) + s->dither.noise_pos;
  47. const DELEM *src = (const DELEM*)srcs->ch[ch];
  48. DELEM *dst = (DELEM*)dsts->ch[ch];
  49. float *ns_errors = s->dither.ns_errors[ch];
  50. const float *ns_coeffs = s->dither.ns_coeffs;
  51. pos = s->dither.ns_pos;
  52. for (i=0; i<count; i++) {
  53. double d1, d = src[i]*S_1;
  54. for(j=0; j<taps-2; j+=4) {
  55. d -= ns_coeffs[j ] * ns_errors[pos + j ]
  56. +ns_coeffs[j + 1] * ns_errors[pos + j + 1]
  57. +ns_coeffs[j + 2] * ns_errors[pos + j + 2]
  58. +ns_coeffs[j + 3] * ns_errors[pos + j + 3];
  59. }
  60. if(j < taps)
  61. d -= ns_coeffs[j] * ns_errors[pos + j];
  62. pos = pos ? pos - 1 : taps - 1;
  63. d1 = rint(d + noise[i]);
  64. ns_errors[pos + taps] = ns_errors[pos] = d1 - d;
  65. d1 *= S;
  66. CLIP(d1);
  67. dst[i] = d1;
  68. }
  69. }
  70. s->dither.ns_pos = pos;
  71. }
  72. #undef RENAME
  73. #undef DELEM
  74. #undef CLIP