You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

85 lines
3.0KB

  1. /*
  2. * Copyright (C) 2012 Michael Niedermayer (michaelni@gmx.at)
  3. *
  4. * This file is part of libswresample
  5. *
  6. * libswresample is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * libswresample is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with libswresample; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. #include "libavutil/avassert.h"
  21. #include "swresample_internal.h"
  22. void swri_get_dither(SwrContext *s, void *dst, int len, unsigned seed, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt) {
  23. double scale = 0;
  24. #define TMP_EXTRA 2
  25. double *tmp = av_malloc((len + TMP_EXTRA) * sizeof(double));
  26. int i;
  27. if(in_fmt == AV_SAMPLE_FMT_FLT || in_fmt == AV_SAMPLE_FMT_DBL){
  28. if(out_fmt == AV_SAMPLE_FMT_S32) scale = 1.0/(1L<<31);
  29. if(out_fmt == AV_SAMPLE_FMT_S16) scale = 1.0/(1L<<15);
  30. if(out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1.0/(1L<< 7);
  31. }
  32. if(in_fmt == AV_SAMPLE_FMT_S32 && out_fmt == AV_SAMPLE_FMT_S16) scale = 1L<<16;
  33. if(in_fmt == AV_SAMPLE_FMT_S32 && out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1L<<24;
  34. if(in_fmt == AV_SAMPLE_FMT_S16 && out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1L<<8;
  35. scale *= s->dither_scale;
  36. for(i=0; i<len + TMP_EXTRA; i++){
  37. double v;
  38. seed = seed* 1664525 + 1013904223;
  39. switch(s->dither_method){
  40. case SWR_DITHER_RECTANGULAR: v= ((double)seed) / UINT_MAX - 0.5; break;
  41. case SWR_DITHER_TRIANGULAR :
  42. case SWR_DITHER_TRIANGULAR_HIGHPASS :
  43. v = ((double)seed) / UINT_MAX;
  44. seed = seed*1664525 + 1013904223;
  45. v-= ((double)seed) / UINT_MAX;
  46. break;
  47. default: av_assert0(0);
  48. }
  49. tmp[i] = v;
  50. }
  51. for(i=0; i<len; i++){
  52. double v;
  53. switch(s->dither_method){
  54. case SWR_DITHER_RECTANGULAR:
  55. case SWR_DITHER_TRIANGULAR :
  56. v = tmp[i];
  57. break;
  58. case SWR_DITHER_TRIANGULAR_HIGHPASS :
  59. v = (- tmp[i] + 2*tmp[i+1] - tmp[i+2]) / sqrt(6);
  60. break;
  61. default: av_assert0(0);
  62. }
  63. v*= scale;
  64. switch(in_fmt){
  65. case AV_SAMPLE_FMT_S16: ((int16_t*)dst)[i] = v; break;
  66. case AV_SAMPLE_FMT_S32: ((int32_t*)dst)[i] = v; break;
  67. case AV_SAMPLE_FMT_FLT: ((float *)dst)[i] = v; break;
  68. case AV_SAMPLE_FMT_DBL: ((double *)dst)[i] = v; break;
  69. default: av_assert0(0);
  70. }
  71. }
  72. av_free(tmp);
  73. }