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.

121 lines
4.2KB

  1. /*
  2. WDL - resample.h
  3. Copyright (C) 2010 and later Cockos Incorporated
  4. This software is provided 'as-is', without any express or implied
  5. warranty. In no event will the authors be held liable for any damages
  6. arising from the use of this software.
  7. Permission is granted to anyone to use this software for any purpose,
  8. including commercial applications, and to alter it and redistribute it
  9. freely, subject to the following restrictions:
  10. 1. The origin of this software must not be misrepresented; you must not
  11. claim that you wrote the original software. If you use this software
  12. in a product, an acknowledgment in the product documentation would be
  13. appreciated but is not required.
  14. 2. Altered source versions must be plainly marked as such, and must not be
  15. misrepresented as being the original software.
  16. 3. This notice may not be removed or altered from any source distribution.
  17. You may also distribute this software under the LGPL v2 or later.
  18. */
  19. #ifndef _WDL_RESAMPLE_H_
  20. #define _WDL_RESAMPLE_H_
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include "wdltypes.h"
  24. #include "heapbuf.h"
  25. // default to floats for sinc filter ceofficients
  26. #ifdef WDL_RESAMPLE_FULL_SINC_PRECISION
  27. typedef double WDL_SincFilterSample;
  28. #else
  29. typedef float WDL_SincFilterSample;
  30. #endif
  31. // default to doubles for audio samples
  32. #ifdef WDL_RESAMPLE_TYPE
  33. typedef WDL_RESAMPLE_TYPE WDL_ResampleSample;
  34. #else
  35. typedef double WDL_ResampleSample;
  36. #endif
  37. #ifndef WDL_RESAMPLE_MAX_FILTERS
  38. #define WDL_RESAMPLE_MAX_FILTERS 4
  39. #endif
  40. #ifndef WDL_RESAMPLE_MAX_NCH
  41. #define WDL_RESAMPLE_MAX_NCH 64
  42. #endif
  43. class WDL_Resampler
  44. {
  45. public:
  46. WDL_Resampler(int initialinputbuffersize=0);
  47. ~WDL_Resampler();
  48. // if sinc set, it overrides interp or filtercnt
  49. void SetMode(bool interp, int filtercnt, bool sinc, int sinc_size=64, int sinc_interpsize=32);
  50. void SetFilterParms(float filterpos=0.693, float filterq=0.707) { m_filterpos=filterpos; m_filterq=filterq; } // used for filtercnt>0 but not sinc
  51. void SetFeedMode(bool wantInputDriven) { m_feedmode=wantInputDriven; } // if true, that means the first parameter to ResamplePrepare will specify however much input you have, not how much you want
  52. void Reset(double fracpos=0.0);
  53. void SetRates(double rate_in, double rate_out);
  54. double GetCurrentLatency(); // amount of input that has been received but not yet converted to output, in seconds
  55. // req_samples is output samples desired if !wantInputDriven, or if wantInputDriven is input samples that we have
  56. // returns number of samples desired (put these into *inbuffer)
  57. // note that it is safe to call ResamplePrepare without calling ResampleOut (the next call of ResamplePrepare will function as normal)
  58. int ResamplePrepare(int req_samples, int nch, WDL_ResampleSample **inbuffer);
  59. // if numsamples_in < the value return by ResamplePrepare(), then it will be flushed to produce all remaining valid samples
  60. // do NOT call with nsamples_in greater than the value returned from resamplerprpare()! the extra samples will be ignored.
  61. // returns number of samples successfully outputted to out
  62. int ResampleOut(WDL_ResampleSample *out, int nsamples_in, int nsamples_out, int nch);
  63. private:
  64. void BuildLowPass(double filtpos);
  65. void inline SincSample(WDL_ResampleSample *outptr, const WDL_ResampleSample *inptr, double fracpos, int nch, const WDL_SincFilterSample *filter, int filtsz);
  66. void inline SincSample1(WDL_ResampleSample *outptr, const WDL_ResampleSample *inptr, double fracpos, const WDL_SincFilterSample *filter, int filtsz);
  67. void inline SincSample2(WDL_ResampleSample *outptr, const WDL_ResampleSample *inptr, double fracpos, const WDL_SincFilterSample *filter, int filtsz);
  68. double m_sratein WDL_FIXALIGN;
  69. double m_srateout;
  70. double m_fracpos;
  71. double m_ratio;
  72. double m_filter_ratio;
  73. float m_filterq, m_filterpos;
  74. WDL_TypedBuf<WDL_ResampleSample> m_rsinbuf;
  75. WDL_TypedBuf<WDL_SincFilterSample> m_filter_coeffs;
  76. class WDL_Resampler_IIRFilter;
  77. WDL_Resampler_IIRFilter *m_iirfilter;
  78. int m_filter_coeffs_size;
  79. int m_last_requested;
  80. int m_filtlatency;
  81. int m_samples_in_rsinbuf;
  82. int m_lp_oversize;
  83. int m_sincsize;
  84. int m_filtercnt;
  85. int m_sincoversize;
  86. bool m_interp;
  87. bool m_feedmode;
  88. };
  89. #endif