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.

97 lines
3.1KB

  1. // Copyright 2014 Olivier Gillet.
  2. //
  3. // Author: Olivier Gillet (ol.gillet@gmail.com)
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. // See http://creativecommons.org/licenses/MIT/ for more information.
  24. //
  25. // -----------------------------------------------------------------------------
  26. //
  27. // Sample rate converter
  28. #ifndef CLOUDS_DSP_SAMPLE_RATE_CONVERTER_H_
  29. #define CLOUDS_DSP_SAMPLE_RATE_CONVERTER_H_
  30. #include "stmlib/stmlib.h"
  31. #include "clouds/dsp/frame.h"
  32. namespace clouds {
  33. template<int32_t ratio, int32_t filter_size, const float* coefficients>
  34. class SampleRateConverter {
  35. public:
  36. SampleRateConverter() { }
  37. ~SampleRateConverter() { }
  38. void Init() {
  39. for (int32_t i = 0; i < filter_size * 2; ++i) {
  40. history_[i].l = history_[i].r = 0.0f;
  41. }
  42. std::copy(&coefficients[0], &coefficients[filter_size], &coefficients_[0]);
  43. history_ptr_ = filter_size - 1;
  44. };
  45. void Process(const FloatFrame* in, FloatFrame* out, size_t input_size) {
  46. int32_t history_ptr = history_ptr_;
  47. FloatFrame* history = history_;
  48. const float scale = ratio < 0 ? 1.0f : float(ratio);
  49. while (input_size) {
  50. int32_t consumed = ratio < 0 ? -ratio : 1;
  51. for (int32_t i = 0; i < consumed; ++i) {
  52. history[history_ptr + filter_size] = history[history_ptr] = *in++;
  53. --input_size;
  54. --history_ptr;
  55. if (history_ptr < 0) {
  56. history_ptr += filter_size;
  57. }
  58. }
  59. int32_t produced = ratio > 0 ? ratio : 1;
  60. for (int32_t i = 0; i < produced; ++i) {
  61. float y_l = 0.0f;
  62. float y_r = 0.0f;
  63. const FloatFrame* x = &history[history_ptr + 1];
  64. for (int32_t j = i; j < filter_size; j += produced) {
  65. const float h = coefficients_[j];
  66. y_l += x->l * h;
  67. y_r += x->r * h;
  68. ++x;
  69. }
  70. out->l = y_l * scale;
  71. out->r = y_r * scale;
  72. ++out;
  73. }
  74. }
  75. history_ptr_ = history_ptr;
  76. }
  77. private:
  78. float coefficients_[filter_size];
  79. FloatFrame history_[filter_size * 2];
  80. int32_t history_ptr_;
  81. DISALLOW_COPY_AND_ASSIGN(SampleRateConverter);
  82. };
  83. } // namespace clouds
  84. #endif // CLOUDS_DSP_SAMPLE_RATE_CONVERTER_H_