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.

225 lines
6.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. // Main processing class.
  28. #ifndef CLOUDS_DSP_GRANULAR_PROCESSOR_H_
  29. #define CLOUDS_DSP_GRANULAR_PROCESSOR_H_
  30. #include "stmlib/stmlib.h"
  31. #include "stmlib/dsp/filter.h"
  32. #include "clouds/dsp/correlator.h"
  33. #include "clouds/dsp/frame.h"
  34. #include "clouds/dsp/fx/diffuser.h"
  35. #include "clouds/dsp/fx/pitch_shifter.h"
  36. #include "clouds/dsp/fx/reverb.h"
  37. #include "clouds/dsp/resonestor.h"
  38. #include "clouds/dsp/fx/oliverb.h"
  39. #include "clouds/dsp/granular_processor.h"
  40. #include "clouds/dsp/granular_sample_player.h"
  41. #include "clouds/dsp/looping_sample_player.h"
  42. #include "clouds/dsp/pvoc/phase_vocoder.h"
  43. #include "clouds/dsp/sample_rate_converter.h"
  44. #include "clouds/dsp/wsola_sample_player.h"
  45. namespace clouds {
  46. const int32_t kDownsamplingFactor = 2;
  47. enum PlaybackMode {
  48. PLAYBACK_MODE_GRANULAR,
  49. PLAYBACK_MODE_STRETCH,
  50. PLAYBACK_MODE_LOOPING_DELAY,
  51. PLAYBACK_MODE_SPECTRAL,
  52. PLAYBACK_MODE_OLIVERB,
  53. PLAYBACK_MODE_RESONESTOR,
  54. PLAYBACK_MODE_LAST
  55. };
  56. // State of the recording buffer as saved in one of the 4 sample memories.
  57. struct PersistentState {
  58. int32_t write_head[2];
  59. uint8_t quality;
  60. uint8_t spectral;
  61. };
  62. // Data block as saved in one of the 4 sample memories.
  63. struct PersistentBlock {
  64. uint32_t tag;
  65. uint32_t size;
  66. void* data;
  67. };
  68. class GranularProcessor {
  69. public:
  70. GranularProcessor() { }
  71. ~GranularProcessor() { }
  72. void Init(
  73. void* large_buffer,
  74. size_t large_buffer_size,
  75. void* small_buffer,
  76. size_t small_buffer_size);
  77. void Process(ShortFrame* input, ShortFrame* output, size_t size);
  78. void Prepare();
  79. inline Parameters* mutable_parameters() {
  80. return &parameters_;
  81. }
  82. inline const Parameters& parameters() const {
  83. return parameters_;
  84. }
  85. inline void ToggleFreeze() {
  86. parameters_.freeze = !parameters_.freeze;
  87. }
  88. inline void ToggleReverse() {
  89. parameters_.granular.reverse = !parameters_.granular.reverse;
  90. }
  91. inline bool frozen() const {
  92. return parameters_.freeze;
  93. }
  94. inline bool reversed() const {
  95. return parameters_.granular.reverse;
  96. }
  97. inline void set_silence(bool silence) {
  98. silence_ = silence;
  99. }
  100. inline void set_bypass(bool bypass) {
  101. bypass_ = bypass;
  102. }
  103. inline bool bypass() const {
  104. return bypass_;
  105. }
  106. inline void set_playback_mode(PlaybackMode playback_mode) {
  107. playback_mode_ = playback_mode;
  108. }
  109. inline PlaybackMode playback_mode() const { return playback_mode_; }
  110. inline void set_quality(int32_t quality) {
  111. set_num_channels(quality & 1 ? 1 : 2);
  112. set_low_fidelity(quality >> 1 ? true : false);
  113. }
  114. inline void set_num_channels(int32_t num_channels) {
  115. reset_buffers_ = reset_buffers_ || num_channels_ != num_channels;
  116. num_channels_ = num_channels;
  117. }
  118. inline void set_low_fidelity(bool low_fidelity) {
  119. reset_buffers_ = reset_buffers_ || low_fidelity != low_fidelity_;
  120. low_fidelity_ = low_fidelity;
  121. }
  122. inline int32_t quality() const {
  123. int32_t quality = 0;
  124. if (num_channels_ == 1) quality |= 1;
  125. if (low_fidelity_) quality |= 2;
  126. return quality;
  127. }
  128. void GetPersistentData(PersistentBlock* block, size_t *num_blocks);
  129. bool LoadPersistentData(const uint32_t* data);
  130. void PreparePersistentData();
  131. private:
  132. inline int32_t resolution() const {
  133. return low_fidelity_ ? 8 : 16;
  134. }
  135. inline float sample_rate() const {
  136. return 32000.0f / \
  137. (low_fidelity_ ? kDownsamplingFactor : 1);
  138. }
  139. void ResetFilters();
  140. void ProcessGranular(FloatFrame* input, FloatFrame* output, size_t size);
  141. PlaybackMode playback_mode_;
  142. PlaybackMode previous_playback_mode_;
  143. int32_t num_channels_;
  144. bool low_fidelity_;
  145. bool silence_;
  146. bool bypass_;
  147. bool reset_buffers_;
  148. float freeze_lp_;
  149. float dry_wet_;
  150. void* buffer_[2];
  151. size_t buffer_size_[2];
  152. Correlator correlator_;
  153. GranularSamplePlayer player_;
  154. WSOLASamplePlayer ws_player_;
  155. LoopingSamplePlayer looper_;
  156. PhaseVocoder phase_vocoder_;
  157. Diffuser diffuser_;
  158. Reverb reverb_;
  159. Oliverb oliverb_;
  160. Resonestor resonestor_;
  161. PitchShifter pitch_shifter_;
  162. stmlib::Svf fb_filter_[2];
  163. stmlib::Svf hp_filter_[2];
  164. stmlib::Svf lp_filter_[2];
  165. AudioBuffer<RESOLUTION_8_BIT_MU_LAW> buffer_8_[2];
  166. AudioBuffer<RESOLUTION_16_BIT> buffer_16_[2];
  167. FloatFrame in_[kMaxBlockSize];
  168. FloatFrame in_downsampled_[kMaxBlockSize / kDownsamplingFactor];
  169. FloatFrame out_downsampled_[kMaxBlockSize / kDownsamplingFactor];
  170. FloatFrame out_[kMaxBlockSize];
  171. FloatFrame fb_[kMaxBlockSize];
  172. int16_t tail_buffer_[2][256];
  173. Parameters parameters_;
  174. SampleRateConverter<-kDownsamplingFactor, 45, src_filter_1x_2_45> src_down_;
  175. SampleRateConverter<+kDownsamplingFactor, 45, src_filter_1x_2_45> src_up_;
  176. PersistentState persistent_state_;
  177. DISALLOW_COPY_AND_ASSIGN(GranularProcessor);
  178. };
  179. } // namespace clouds
  180. #endif // CLOUDS_DSP_GRANULAR_PROCESSOR_H_