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.

633 lines
21KB

  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. #include "clouds/dsp/granular_processor.h"
  29. #include <cstring>
  30. #include "clouds/drivers/debug_pin.h"
  31. #include "stmlib/dsp/parameter_interpolator.h"
  32. #include "stmlib/utils/buffer_allocator.h"
  33. #include "clouds/resources.h"
  34. namespace clouds {
  35. using namespace std;
  36. using namespace stmlib;
  37. void GranularProcessor::Init(
  38. void* large_buffer, size_t large_buffer_size,
  39. void* small_buffer, size_t small_buffer_size) {
  40. buffer_[0] = large_buffer;
  41. buffer_[1] = small_buffer;
  42. buffer_size_[0] = large_buffer_size;
  43. buffer_size_[1] = small_buffer_size;
  44. num_channels_ = 2;
  45. low_fidelity_ = false;
  46. bypass_ = false;
  47. src_down_.Init();
  48. src_up_.Init();
  49. ResetFilters();
  50. previous_playback_mode_ = PLAYBACK_MODE_LAST;
  51. reset_buffers_ = true;
  52. dry_wet_ = 0.0f;
  53. }
  54. void GranularProcessor::ResetFilters() {
  55. for (int32_t i = 0; i < 2; ++i) {
  56. fb_filter_[i].Init();
  57. lp_filter_[i].Init();
  58. hp_filter_[i].Init();
  59. }
  60. }
  61. void GranularProcessor::ProcessGranular(
  62. FloatFrame* input,
  63. FloatFrame* output,
  64. size_t size) {
  65. // At the exception of the spectral mode, all modes require the incoming
  66. // audio signal to be written to the recording buffer.
  67. if (playback_mode_ != PLAYBACK_MODE_SPECTRAL &&
  68. playback_mode_ != PLAYBACK_MODE_RESONESTOR) {
  69. const float* input_samples = &input[0].l;
  70. const bool play = !parameters_.freeze ||
  71. playback_mode_ == PLAYBACK_MODE_OLIVERB;
  72. for (int32_t i = 0; i < num_channels_; ++i) {
  73. if (resolution() == 8) {
  74. buffer_8_[i].WriteFade(&input_samples[i], size, 2, play);
  75. } else {
  76. buffer_16_[i].WriteFade(&input_samples[i], size, 2, play);
  77. }
  78. }
  79. }
  80. switch (playback_mode_) {
  81. case PLAYBACK_MODE_GRANULAR:
  82. // In Granular mode, DENSITY is a meta parameter.
  83. parameters_.granular.use_deterministic_seed = parameters_.density < 0.5f;
  84. if (parameters_.density >= 0.53f) {
  85. parameters_.granular.overlap = (parameters_.density - 0.53f) * 2.12f;
  86. } else if (parameters_.density <= 0.47f) {
  87. parameters_.granular.overlap = (0.47f - parameters_.density) * 2.12f;
  88. } else {
  89. parameters_.granular.overlap = 0.0f;
  90. }
  91. #ifdef CLOUDS_QUANTIZE_SEMITONES
  92. // Quantize pitch to closest semitone
  93. if (parameters_.pitch < 0.5f) parameters_.pitch -= 0.5f;
  94. parameters_.pitch = static_cast<int>(parameters_.pitch + 0.5f);
  95. #endif
  96. // And TEXTURE too.
  97. parameters_.granular.window_shape = parameters_.texture < 0.75f
  98. ? parameters_.texture * 1.333f : 1.0f;
  99. if (resolution() == 8) {
  100. player_.Play(buffer_8_, parameters_, &output[0].l, size);
  101. } else {
  102. player_.Play(buffer_16_, parameters_, &output[0].l, size);
  103. }
  104. break;
  105. case PLAYBACK_MODE_STRETCH:
  106. if (resolution() == 8) {
  107. ws_player_.Play(buffer_8_, parameters_, &output[0].l, size);
  108. } else {
  109. ws_player_.Play(buffer_16_, parameters_, &output[0].l, size);
  110. }
  111. break;
  112. case PLAYBACK_MODE_LOOPING_DELAY:
  113. if (resolution() == 8) {
  114. looper_.Play(buffer_8_, parameters_, &output[0].l, size);
  115. } else {
  116. looper_.Play(buffer_16_, parameters_, &output[0].l, size);
  117. }
  118. break;
  119. case PLAYBACK_MODE_SPECTRAL:
  120. {
  121. parameters_.spectral.quantization = parameters_.texture;
  122. parameters_.spectral.refresh_rate = 0.01f + 0.99f * parameters_.density;
  123. float warp = parameters_.size - 0.5f;
  124. parameters_.spectral.warp = 4.0f * warp * warp * warp + 0.5f;
  125. float randomization = parameters_.density - 0.5f;
  126. randomization *= randomization * 4.2f;
  127. randomization -= 0.05f;
  128. CONSTRAIN(randomization, 0.0f, 1.0f);
  129. parameters_.spectral.phase_randomization = randomization;
  130. phase_vocoder_.Process(parameters_, input, output, size);
  131. if (num_channels_ == 1) {
  132. for (size_t i = 0; i < size; ++i) {
  133. output[i].r = output[i].l;
  134. }
  135. }
  136. }
  137. break;
  138. case PLAYBACK_MODE_OLIVERB:
  139. {
  140. // Pre-delay, controlled by position or tap tempo sync
  141. Parameters p = {
  142. ws_player_.synchronized() ?
  143. parameters_.position :
  144. parameters_.position * 0.25f, // position;
  145. 0.1f, // size;
  146. 0.0f, // pitch;
  147. 0.0f, // density;
  148. 0.5f, // texture;
  149. 1.0f, // dry_wet;
  150. 0.0f, // stereo_spread;
  151. 0.0f, // feedback;
  152. 0.0f, // reverb;
  153. false, // freeze;
  154. parameters_.trigger, // trigger;
  155. false // gate;
  156. };
  157. if (resolution() == 8) {
  158. ws_player_.Play(buffer_8_, p, &output[0].l, size);
  159. } else {
  160. ws_player_.Play(buffer_16_, p, &output[0].l, size);
  161. }
  162. // Settings of the reverb
  163. oliverb_.set_diffusion(0.3f + 0.5f * parameters_.stereo_spread);
  164. oliverb_.set_size(0.05f + 0.94f * parameters_.size);
  165. oliverb_.set_mod_rate(parameters_.feedback);
  166. oliverb_.set_mod_amount(parameters_.reverb * 300.0f);
  167. oliverb_.set_ratio(SemitonesToRatio(parameters_.pitch));
  168. float x = parameters_.pitch;
  169. const float limit = 0.7f;
  170. const float slew = 0.4f;
  171. float wet =
  172. x < -limit ? 1.0f :
  173. x < -limit + slew ? 1.0f - (x + limit) / slew:
  174. x < limit - slew ? 0.0f :
  175. x < limit ? 1.0f + (x - limit) / slew:
  176. 1.0f;
  177. oliverb_.set_pitch_shift_amount(wet);
  178. if (parameters_.freeze) {
  179. oliverb_.set_input_gain(0.0f);
  180. oliverb_.set_decay(1.0f);
  181. oliverb_.set_lp(1.0f);
  182. oliverb_.set_hp(0.0f);
  183. } else {
  184. oliverb_.set_decay(parameters_.density * 1.3f
  185. + 0.15f * abs(parameters_.pitch) / 24.0f);
  186. oliverb_.set_input_gain(0.5f);
  187. float lp = parameters_.texture < 0.5f ?
  188. parameters_.texture * 2.0f : 1.0f;
  189. float hp = parameters_.texture > 0.5f ?
  190. (parameters_.texture - 0.5f) * 2.0f : 0.0f;
  191. oliverb_.set_lp(0.03f + 0.9f * lp);
  192. oliverb_.set_hp(0.01f + 0.2f * hp); // the small offset
  193. // gets rid of
  194. // feedback of large
  195. // DC offset.
  196. }
  197. oliverb_.Process(output, size);
  198. }
  199. break;
  200. case PLAYBACK_MODE_RESONESTOR:
  201. {
  202. copy(&input[0], &input[size], &output[0]);
  203. resonestor_.set_pitch(parameters_.pitch);
  204. resonestor_.set_chord(parameters_.size);
  205. resonestor_.set_trigger(parameters_.trigger);
  206. resonestor_.set_burst_damp(parameters_.position);
  207. resonestor_.set_burst_comb((1.0f - parameters_.position));
  208. resonestor_.set_burst_duration((1.0f - parameters_.position));
  209. resonestor_.set_spread_amount(parameters_.reverb);
  210. resonestor_.set_stereo(parameters_.stereo_spread < 0.5f ? 0.0f :
  211. (parameters_.stereo_spread - 0.5f) * 2.0f);
  212. resonestor_.set_separation(parameters_.stereo_spread > 0.5f ? 0.0f :
  213. (0.5f - parameters_.stereo_spread) * 2.0f);
  214. resonestor_.set_freeze(parameters_.freeze);
  215. resonestor_.set_harmonicity(1.0f - (parameters_.feedback * 0.5f));
  216. resonestor_.set_distortion(parameters_.dry_wet);
  217. float t = parameters_.texture;
  218. if (t < 0.5f) {
  219. resonestor_.set_narrow(0.001f);
  220. float l = 1.0f - (0.5f - t) / 0.5f;
  221. l = l * (1.0f - 0.08f) + 0.08f;
  222. resonestor_.set_damp(l * l);
  223. } else {
  224. resonestor_.set_damp(1.0f);
  225. float n = (t - 0.5f) / 0.5f * 1.35f;
  226. n *= n * n * n;
  227. resonestor_.set_narrow(0.001f + n * n * 0.6f);
  228. }
  229. float d = (parameters_.density - 0.05f) / 0.9f;
  230. if (d < 0.0f) d = 0.0f;
  231. d *= d * d;
  232. d *= d * d;
  233. d *= d * d;
  234. resonestor_.set_feedback(d * 20.0f);
  235. resonestor_.Process(output, size);
  236. }
  237. break;
  238. default:
  239. break;
  240. }
  241. }
  242. void GranularProcessor::Process(
  243. ShortFrame* input,
  244. ShortFrame* output,
  245. size_t size) {
  246. // TIC
  247. if (bypass_) {
  248. copy(&input[0], &input[size], &output[0]);
  249. return;
  250. }
  251. if (silence_ || reset_buffers_ ||
  252. previous_playback_mode_ != playback_mode_) {
  253. short* output_samples = &output[0].l;
  254. fill(&output_samples[0], &output_samples[size << 1], 0);
  255. return;
  256. }
  257. // Convert input buffers to float, and mixdown for mono processing.
  258. for (size_t i = 0; i < size; ++i) {
  259. in_[i].l = static_cast<float>(input[i].l) / 32768.0f;
  260. in_[i].r = static_cast<float>(input[i].r) / 32768.0f;
  261. }
  262. if (num_channels_ == 1) {
  263. for (size_t i = 0; i < size; ++i) {
  264. float xfade = 0.5f;
  265. // in mono delay modes, stereo spread controls input crossfade
  266. if (playback_mode_ == PLAYBACK_MODE_LOOPING_DELAY ||
  267. playback_mode_ == PLAYBACK_MODE_STRETCH)
  268. xfade = parameters_.stereo_spread;
  269. in_[i].l = in_[i].l * (1.0f - xfade) + in_[i].r * xfade;
  270. in_[i].r = in_[i].l;
  271. }
  272. }
  273. // Apply feedback, with high-pass filtering to prevent build-ups at very
  274. // low frequencies (causing large DC swings).
  275. float feedback = parameters_.feedback;
  276. if (playback_mode_ != PLAYBACK_MODE_OLIVERB &&
  277. playback_mode_ != PLAYBACK_MODE_RESONESTOR) {
  278. ONE_POLE(freeze_lp_, parameters_.freeze ? 1.0f : 0.0f, 0.0005f)
  279. float cutoff = (20.0f + 100.0f * feedback * feedback) / sample_rate();
  280. fb_filter_[0].set_f_q<FREQUENCY_FAST>(cutoff, 0.75f);
  281. fb_filter_[1].set(fb_filter_[0]);
  282. fb_filter_[0].Process<FILTER_MODE_HIGH_PASS>(&fb_[0].l, &fb_[0].l, size, 2);
  283. fb_filter_[1].Process<FILTER_MODE_HIGH_PASS>(&fb_[0].r, &fb_[0].r, size, 2);
  284. float fb_gain = feedback * (2.0f - feedback) * (1.0f - freeze_lp_);
  285. for (size_t i = 0; i < size; ++i) {
  286. in_[i].l += fb_gain * (
  287. SoftLimit(fb_gain * 1.4f * fb_[i].l + in_[i].l) - in_[i].l);
  288. in_[i].r += fb_gain * (
  289. SoftLimit(fb_gain * 1.4f * fb_[i].r + in_[i].r) - in_[i].r);
  290. }
  291. }
  292. if (low_fidelity_) {
  293. size_t downsampled_size = size / kDownsamplingFactor;
  294. src_down_.Process(in_, in_downsampled_,size);
  295. ProcessGranular(in_downsampled_, out_downsampled_, downsampled_size);
  296. src_up_.Process(out_downsampled_, out_, downsampled_size);
  297. } else {
  298. ProcessGranular(in_, out_, size);
  299. }
  300. // Diffusion and pitch-shifting post-processings.
  301. if (playback_mode_ != PLAYBACK_MODE_SPECTRAL &&
  302. playback_mode_ != PLAYBACK_MODE_OLIVERB &&
  303. playback_mode_ != PLAYBACK_MODE_RESONESTOR) {
  304. float texture = parameters_.texture;
  305. float diffusion = playback_mode_ == PLAYBACK_MODE_GRANULAR
  306. ? texture > 0.75f ? (texture - 0.75f) * 4.0f : 0.0f
  307. : parameters_.density;
  308. diffuser_.set_amount(diffusion);
  309. diffuser_.Process(out_, size);
  310. }
  311. if (playback_mode_ == PLAYBACK_MODE_LOOPING_DELAY &&
  312. (!parameters_.freeze || looper_.synchronized())) {
  313. pitch_shifter_.set_ratio(SemitonesToRatio(parameters_.pitch));
  314. pitch_shifter_.set_size(parameters_.size);
  315. float x = parameters_.pitch;
  316. const float limit = 0.7f;
  317. const float slew = 0.4f;
  318. float wet =
  319. x < -limit ? 1.0f :
  320. x < -limit + slew ? 1.0f - (x + limit) / slew:
  321. x < limit - slew ? 0.0f :
  322. x < limit ? 1.0f + (x - limit) / slew:
  323. 1.0f;
  324. pitch_shifter_.set_dry_wet(wet);
  325. pitch_shifter_.Process(out_, size);
  326. }
  327. // Apply filters.
  328. if (playback_mode_ == PLAYBACK_MODE_LOOPING_DELAY ||
  329. playback_mode_ == PLAYBACK_MODE_STRETCH) {
  330. float cutoff = parameters_.texture;
  331. float lp_cutoff = 0.5f * SemitonesToRatio(
  332. (cutoff < 0.5f ? cutoff - 0.5f : 0.0f) * 216.0f);
  333. float hp_cutoff = 0.25f * SemitonesToRatio(
  334. (cutoff < 0.5f ? -0.5f : cutoff - 1.0f) * 216.0f);
  335. CONSTRAIN(lp_cutoff, 0.0f, 0.499f);
  336. CONSTRAIN(hp_cutoff, 0.0f, 0.499f);
  337. lp_filter_[0].set_f_q<FREQUENCY_FAST>(lp_cutoff, 0.9f);
  338. lp_filter_[0].Process<FILTER_MODE_LOW_PASS>(
  339. &out_[0].l, &out_[0].l, size, 2);
  340. lp_filter_[1].set(lp_filter_[0]);
  341. lp_filter_[1].Process<FILTER_MODE_LOW_PASS>(
  342. &out_[0].r, &out_[0].r, size, 2);
  343. hp_filter_[0].set_f_q<FREQUENCY_FAST>(hp_cutoff, 0.9f);
  344. hp_filter_[0].Process<FILTER_MODE_HIGH_PASS>(
  345. &out_[0].l, &out_[0].l, size, 2);
  346. hp_filter_[1].set(hp_filter_[0]);
  347. hp_filter_[1].Process<FILTER_MODE_HIGH_PASS>(
  348. &out_[0].r, &out_[0].r, size, 2);
  349. }
  350. // This is what is fed back. Reverb is not fed back.
  351. copy(&out_[0], &out_[size], &fb_[0]);
  352. const float post_gain = 1.2f;
  353. if (playback_mode_ != PLAYBACK_MODE_RESONESTOR) {
  354. ParameterInterpolator dry_wet_mod(&dry_wet_, parameters_.dry_wet, size);
  355. for (size_t i = 0; i < size; ++i) {
  356. float dry_wet = dry_wet_mod.Next();
  357. float fade_in = Interpolate(lut_xfade_in, dry_wet, 16.0f);
  358. float fade_out = Interpolate(lut_xfade_out, dry_wet, 16.0f);
  359. float l = static_cast<float>(input[i].l) / 32768.0f;
  360. float r = static_cast<float>(input[i].r) / 32768.0f;
  361. out_[i].l = l * fade_out + out_[i].l * post_gain * fade_in;
  362. out_[i].r = r * fade_out + out_[i].r * post_gain * fade_in;
  363. }
  364. }
  365. // Apply the simple post-processing reverb.
  366. if (playback_mode_ != PLAYBACK_MODE_OLIVERB &&
  367. playback_mode_ != PLAYBACK_MODE_RESONESTOR) {
  368. float reverb_amount = parameters_.reverb;
  369. reverb_.set_amount(reverb_amount * 0.54f);
  370. reverb_.set_diffusion(0.7f);
  371. reverb_.set_time(0.35f + 0.63f * reverb_amount);
  372. reverb_.set_input_gain(0.2f);
  373. reverb_.set_lp(0.6f + 0.37f * feedback);
  374. reverb_.Process(out_, size);
  375. }
  376. for (size_t i = 0; i < size; ++i) {
  377. output[i].l = SoftConvert(out_[i].l);
  378. output[i].r = SoftConvert(out_[i].r);
  379. }
  380. // TOC
  381. }
  382. void GranularProcessor::PreparePersistentData() {
  383. persistent_state_.write_head[0] = low_fidelity_ ?
  384. buffer_8_[0].head() : buffer_16_[0].head();
  385. persistent_state_.write_head[1] = low_fidelity_ ?
  386. buffer_8_[1].head() : buffer_16_[1].head();
  387. persistent_state_.quality = quality();
  388. persistent_state_.spectral = playback_mode() == PLAYBACK_MODE_SPECTRAL;
  389. }
  390. void GranularProcessor::GetPersistentData(
  391. PersistentBlock* block, size_t *num_blocks) {
  392. PersistentBlock* first_block = block;
  393. block->tag = FourCC<'s', 't', 'a', 't'>::value;
  394. block->data = &persistent_state_;
  395. block->size = sizeof(PersistentState);
  396. ++block;
  397. // Create save block holding the audio buffers.
  398. for (int32_t i = 0; i < num_channels_; ++i) {
  399. block->tag = FourCC<'b', 'u', 'f', 'f'>::value;
  400. block->data = buffer_[i];
  401. block->size = buffer_size_[num_channels_ - 1];
  402. ++block;
  403. }
  404. *num_blocks = block - first_block;
  405. }
  406. bool GranularProcessor::LoadPersistentData(const uint32_t* data) {
  407. // Force a silent output while the swapping of buffers takes place.
  408. silence_ = true;
  409. PersistentBlock block[4];
  410. size_t num_blocks;
  411. GetPersistentData(block, &num_blocks);
  412. for (size_t i = 0; i < num_blocks; ++i) {
  413. // Check that the format is correct.
  414. if (block[i].tag != data[0] || block[i].size != data[1]) {
  415. silence_ = false;
  416. return false;
  417. }
  418. // All good. Load the data. 2 words have already been used for the block tag
  419. // and the block size.
  420. data += 2;
  421. memcpy(block[i].data, data, block[i].size);
  422. data += block[i].size / sizeof(uint32_t);
  423. if (i == 0) {
  424. // We now know from which mode the data was saved.
  425. bool currently_spectral = playback_mode_ == PLAYBACK_MODE_SPECTRAL;
  426. bool requires_spectral = persistent_state_.spectral;
  427. if (currently_spectral ^ requires_spectral) {
  428. set_playback_mode(requires_spectral
  429. ? PLAYBACK_MODE_SPECTRAL
  430. : PLAYBACK_MODE_GRANULAR);
  431. }
  432. set_quality(persistent_state_.quality);
  433. // We can force a switch to this mode, and once everything has been
  434. // initialized for this mode, we continue with the loop to copy the
  435. // actual buffer data - with all state variables correctly initialized.
  436. Prepare();
  437. GetPersistentData(block, &num_blocks);
  438. }
  439. }
  440. // We can finally reset the position of the write heads.
  441. if (low_fidelity_) {
  442. buffer_8_[0].Resync(persistent_state_.write_head[0]);
  443. buffer_8_[1].Resync(persistent_state_.write_head[1]);
  444. } else {
  445. buffer_16_[0].Resync(persistent_state_.write_head[0]);
  446. buffer_16_[1].Resync(persistent_state_.write_head[1]);
  447. }
  448. parameters_.freeze = true;
  449. silence_ = false;
  450. return true;
  451. }
  452. void GranularProcessor::Prepare() {
  453. bool playback_mode_changed = previous_playback_mode_ != playback_mode_;
  454. bool benign_change = previous_playback_mode_ != PLAYBACK_MODE_SPECTRAL
  455. && playback_mode_ != PLAYBACK_MODE_SPECTRAL
  456. && playback_mode_ != PLAYBACK_MODE_RESONESTOR
  457. && previous_playback_mode_ != PLAYBACK_MODE_RESONESTOR
  458. && playback_mode_ != PLAYBACK_MODE_OLIVERB
  459. && previous_playback_mode_ != PLAYBACK_MODE_OLIVERB
  460. && previous_playback_mode_ != PLAYBACK_MODE_LAST;
  461. if (!reset_buffers_ && playback_mode_changed && benign_change) {
  462. ResetFilters();
  463. pitch_shifter_.Clear();
  464. previous_playback_mode_ = playback_mode_;
  465. }
  466. if ((playback_mode_changed && !benign_change) || reset_buffers_) {
  467. parameters_.freeze = false;
  468. }
  469. if (reset_buffers_ || (playback_mode_changed && !benign_change)) {
  470. void* buffer[2];
  471. size_t buffer_size[2];
  472. void* workspace;
  473. size_t workspace_size;
  474. if (num_channels_ == 1) {
  475. // Large buffer: 120k of sample memory.
  476. // small buffer: fully allocated to FX workspace.
  477. buffer[0] = buffer_[0];
  478. buffer_size[0] = buffer_size_[0];
  479. buffer[1] = NULL;
  480. buffer_size[1] = 0;
  481. workspace = buffer_[1];
  482. workspace_size = buffer_size_[1];
  483. } else {
  484. // Large buffer: 64k of sample memory + FX workspace.
  485. // small buffer: 64k of sample memory.
  486. buffer_size[0] = buffer_size[1] = buffer_size_[1];
  487. buffer[0] = buffer_[0];
  488. buffer[1] = buffer_[1];
  489. workspace_size = buffer_size_[0] - buffer_size_[1];
  490. workspace = static_cast<uint8_t*>(buffer[0]) + buffer_size[0];
  491. }
  492. float sr = sample_rate();
  493. BufferAllocator allocator(workspace, workspace_size);
  494. diffuser_.Init(allocator.Allocate<float>(2048));
  495. uint16_t* reverb_buffer = allocator.Allocate<uint16_t>(16384);
  496. if (playback_mode_ == PLAYBACK_MODE_OLIVERB) {
  497. oliverb_.Init(reverb_buffer);
  498. } else {
  499. reverb_.Init(reverb_buffer);
  500. }
  501. size_t correlator_block_size = (kMaxWSOLASize / 32) + 2;
  502. uint32_t* correlator_data = allocator.Allocate<uint32_t>(
  503. correlator_block_size * 3);
  504. correlator_.Init(
  505. &correlator_data[0],
  506. &correlator_data[correlator_block_size]);
  507. pitch_shifter_.Init((uint16_t*)correlator_data);
  508. if (playback_mode_ == PLAYBACK_MODE_SPECTRAL) {
  509. phase_vocoder_.Init(
  510. buffer, buffer_size,
  511. lut_sine_window_4096, 4096,
  512. num_channels_, resolution(), sr);
  513. } else if (playback_mode_ == PLAYBACK_MODE_RESONESTOR) {
  514. float* buf = (float*)buffer[0];
  515. resonestor_.Init(buf);
  516. } else {
  517. for (int32_t i = 0; i < num_channels_; ++i) {
  518. if (resolution() == 8) {
  519. buffer_8_[i].Init(
  520. buffer[i],
  521. (buffer_size[i]),
  522. tail_buffer_[i]);
  523. } else {
  524. buffer_16_[i].Init(
  525. buffer[i],
  526. ((buffer_size[i]) >> 1),
  527. tail_buffer_[i]);
  528. }
  529. }
  530. int32_t num_grains = (num_channels_ == 1 ? 32 : 26) * \
  531. (low_fidelity_ ? 20 : 16) >> 4;
  532. player_.Init(num_channels_, num_grains);
  533. ws_player_.Init(&correlator_, num_channels_);
  534. looper_.Init(num_channels_);
  535. }
  536. reset_buffers_ = false;
  537. previous_playback_mode_ = playback_mode_;
  538. }
  539. if (playback_mode_ == PLAYBACK_MODE_SPECTRAL) {
  540. phase_vocoder_.Buffer();
  541. } else if (playback_mode_ == PLAYBACK_MODE_STRETCH ||
  542. playback_mode_ == PLAYBACK_MODE_OLIVERB) {
  543. if (resolution() == 8) {
  544. ws_player_.LoadCorrelator(buffer_8_);
  545. } else {
  546. ws_player_.LoadCorrelator(buffer_16_);
  547. }
  548. correlator_.EvaluateSomeCandidates();
  549. }
  550. }
  551. } // namespace clouds