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.

399 lines
13KB

  1. // Copyright 2012 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. // Macro-oscillator.
  28. #include "braids/macro_oscillator.h"
  29. #include <algorithm>
  30. #include "stmlib/utils/dsp.h"
  31. #include "braids/parameter_interpolation.h"
  32. #include "braids/resources.h"
  33. namespace braids {
  34. using namespace stmlib;
  35. void MacroOscillator::Render(
  36. const uint8_t* sync,
  37. int16_t* buffer,
  38. size_t size) {
  39. RenderFn fn = fn_table_[shape_];
  40. (this->*fn)(sync, buffer, size);
  41. }
  42. void MacroOscillator::RenderCSaw(
  43. const uint8_t* sync,
  44. int16_t* buffer,
  45. size_t size) {
  46. analog_oscillator_[0].set_pitch(pitch_);
  47. analog_oscillator_[0].set_shape(OSC_SHAPE_CSAW);
  48. analog_oscillator_[0].set_parameter(parameter_[0]);
  49. analog_oscillator_[0].set_aux_parameter(parameter_[1]);
  50. analog_oscillator_[0].Render(sync, buffer, NULL, size);
  51. int16_t shift = -(parameter_[1] - 32767) >> 4;
  52. while (size--) {
  53. int32_t s = *buffer + shift;
  54. *buffer++ = (s * 13) >> 3;
  55. }
  56. }
  57. void MacroOscillator::RenderMorph(
  58. const uint8_t* sync,
  59. int16_t* buffer,
  60. size_t size) {
  61. analog_oscillator_[0].set_pitch(pitch_);
  62. analog_oscillator_[1].set_pitch(pitch_);
  63. uint16_t balance;
  64. if (parameter_[0] <= 10922) {
  65. analog_oscillator_[0].set_parameter(0);
  66. analog_oscillator_[1].set_parameter(0);
  67. analog_oscillator_[0].set_shape(OSC_SHAPE_TRIANGLE);
  68. analog_oscillator_[1].set_shape(OSC_SHAPE_SAW);
  69. balance = parameter_[0] * 6;
  70. } else if (parameter_[0] <= 21845) {
  71. analog_oscillator_[0].set_parameter(0);
  72. analog_oscillator_[1].set_parameter(0);
  73. analog_oscillator_[0].set_shape(OSC_SHAPE_SQUARE);
  74. analog_oscillator_[1].set_shape(OSC_SHAPE_SAW);
  75. balance = 65535 - (parameter_[0] - 10923) * 6;
  76. } else {
  77. analog_oscillator_[0].set_parameter((parameter_[0] - 21846) * 3);
  78. analog_oscillator_[1].set_parameter(0);
  79. analog_oscillator_[0].set_shape(OSC_SHAPE_SQUARE);
  80. analog_oscillator_[1].set_shape(OSC_SHAPE_SINE);
  81. balance = 0;
  82. }
  83. int16_t* shape_1 = buffer;
  84. int16_t* shape_2 = temp_buffer_;
  85. analog_oscillator_[0].Render(sync, shape_1, NULL, size);
  86. analog_oscillator_[1].Render(sync, shape_2, NULL, size);
  87. int32_t lp_cutoff = pitch_ - (parameter_[1] >> 1) + 128 * 128;
  88. if (lp_cutoff < 0) {
  89. lp_cutoff = 0;
  90. } else if (lp_cutoff > 32767) {
  91. lp_cutoff = 32767;
  92. }
  93. int32_t f = Interpolate824(lut_svf_cutoff, lp_cutoff << 17);
  94. int32_t lp_state = lp_state_;
  95. int32_t fuzz_amount = parameter_[1] << 1;
  96. if (pitch_ > (80 << 7)) {
  97. fuzz_amount -= (pitch_ - (80 << 7)) << 4;
  98. if (fuzz_amount < 0) {
  99. fuzz_amount = 0;
  100. }
  101. }
  102. while (size--) {
  103. int16_t sample = Mix(*shape_1++, *shape_2++, balance);
  104. int32_t shifted_sample = sample;
  105. shifted_sample += (parameter_[1] >> 2) + (parameter_[0] >> 4);
  106. lp_state += (sample - lp_state) * f >> 15;
  107. CLIP(lp_state)
  108. shifted_sample = lp_state + 32768;
  109. int16_t fuzzed = Interpolate88(ws_violent_overdrive, shifted_sample);
  110. *buffer++ = Mix(sample, fuzzed, fuzz_amount);
  111. }
  112. lp_state_ = lp_state;
  113. }
  114. void MacroOscillator::RenderSawSquare(
  115. const uint8_t* sync,
  116. int16_t* buffer,
  117. size_t size) {
  118. analog_oscillator_[0].set_parameter(parameter_[0]);
  119. analog_oscillator_[1].set_parameter(parameter_[0]);
  120. analog_oscillator_[0].set_pitch(pitch_);
  121. analog_oscillator_[1].set_pitch(pitch_);
  122. analog_oscillator_[0].set_shape(OSC_SHAPE_VARIABLE_SAW);
  123. analog_oscillator_[1].set_shape(OSC_SHAPE_SQUARE);
  124. int16_t* saw_buffer = buffer;
  125. int16_t* square_buffer = temp_buffer_;
  126. analog_oscillator_[0].Render(sync, saw_buffer, NULL, size);
  127. analog_oscillator_[1].Render(sync, square_buffer, NULL, size);
  128. BEGIN_INTERPOLATE_PARAMETER_1
  129. while (size--) {
  130. INTERPOLATE_PARAMETER_1
  131. uint16_t balance = parameter_1 << 1;
  132. int16_t attenuated_square = static_cast<int32_t>(
  133. *square_buffer++) * 148 >> 8;
  134. *buffer++ = Mix(*saw_buffer++, attenuated_square, balance);
  135. }
  136. END_INTERPOLATE_PARAMETER_1
  137. }
  138. #define SEMI * 128
  139. const int16_t intervals[65] = {
  140. -24 SEMI, -24 SEMI, -24 SEMI + 4,
  141. -23 SEMI, -22 SEMI, -21 SEMI, -20 SEMI, -19 SEMI, -18 SEMI,
  142. -17 SEMI - 4, -17 SEMI,
  143. -16 SEMI, -15 SEMI, -14 SEMI, -13 SEMI,
  144. -12 SEMI - 4, -12 SEMI,
  145. -11 SEMI, -10 SEMI, -9 SEMI, -8 SEMI,
  146. -7 SEMI - 4, -7 SEMI,
  147. -6 SEMI, -5 SEMI, -4 SEMI, -3 SEMI, -2 SEMI, -1 SEMI,
  148. -24, -8, -4, 0, 4, 8, 24,
  149. 1 SEMI, 2 SEMI, 3 SEMI, 4 SEMI, 5 SEMI, 6 SEMI,
  150. 7 SEMI, 7 SEMI + 4,
  151. 8 SEMI, 9 SEMI, 10 SEMI, 11 SEMI,
  152. 12 SEMI, 12 SEMI + 4,
  153. 13 SEMI, 14 SEMI, 15 SEMI, 16 SEMI,
  154. 17 SEMI, 17 SEMI + 4,
  155. 18 SEMI, 19 SEMI, 20 SEMI, 21 SEMI, 22 SEMI, 23 SEMI,
  156. 24 SEMI - 4, 24 SEMI, 24 SEMI
  157. };
  158. void MacroOscillator::RenderTriple(
  159. const uint8_t* sync,
  160. int16_t* buffer,
  161. size_t size) {
  162. AnalogOscillatorShape base_shape;
  163. switch (shape_) {
  164. case MACRO_OSC_SHAPE_TRIPLE_SAW:
  165. base_shape = OSC_SHAPE_SAW;
  166. break;
  167. case MACRO_OSC_SHAPE_TRIPLE_TRIANGLE:
  168. base_shape = OSC_SHAPE_TRIANGLE;
  169. break;
  170. case MACRO_OSC_SHAPE_TRIPLE_SQUARE:
  171. base_shape = OSC_SHAPE_SQUARE;
  172. break;
  173. default:
  174. base_shape = OSC_SHAPE_SINE;
  175. break;
  176. }
  177. analog_oscillator_[0].set_parameter(0);
  178. analog_oscillator_[1].set_parameter(0);
  179. analog_oscillator_[2].set_parameter(0);
  180. analog_oscillator_[0].set_pitch(pitch_);
  181. for (size_t i = 0; i < 2; ++i) {
  182. int16_t detune_1 = intervals[parameter_[i] >> 9];
  183. int16_t detune_2 = intervals[((parameter_[i] >> 8) + 1) >> 1];
  184. uint16_t xfade = parameter_[i] << 8;
  185. int16_t detune = detune_1 + ((detune_2 - detune_1) * xfade >> 16);
  186. analog_oscillator_[i + 1].set_pitch(pitch_ + detune);
  187. }
  188. analog_oscillator_[0].set_shape(base_shape);
  189. analog_oscillator_[1].set_shape(base_shape);
  190. analog_oscillator_[2].set_shape(base_shape);
  191. std::fill(&buffer[0], &buffer[size], 0);
  192. for (size_t i = 0; i < 3; ++i) {
  193. analog_oscillator_[i].Render(sync, temp_buffer_, NULL, size);
  194. for (size_t j = 0; j < size; ++j) {
  195. buffer[j] += temp_buffer_[j] * 21 >> 6;
  196. }
  197. }
  198. }
  199. void MacroOscillator::RenderDualSync(
  200. const uint8_t* sync,
  201. int16_t* buffer,
  202. size_t size) {
  203. AnalogOscillatorShape base_shape = shape_ == MACRO_OSC_SHAPE_SQUARE_SYNC ?
  204. OSC_SHAPE_SQUARE : OSC_SHAPE_SAW;
  205. analog_oscillator_[0].set_parameter(0);
  206. analog_oscillator_[0].set_shape(base_shape);
  207. analog_oscillator_[0].set_pitch(pitch_);
  208. analog_oscillator_[1].set_parameter(0);
  209. analog_oscillator_[1].set_shape(base_shape);
  210. analog_oscillator_[1].set_pitch(pitch_ + (parameter_[0] >> 2));
  211. analog_oscillator_[0].Render(sync, buffer, sync_buffer_, size);
  212. analog_oscillator_[1].Render(sync_buffer_, temp_buffer_, NULL, size);
  213. BEGIN_INTERPOLATE_PARAMETER_1
  214. int16_t* temp_buffer = temp_buffer_;
  215. while (size--) {
  216. INTERPOLATE_PARAMETER_1
  217. uint16_t balance = parameter_1 << 1;
  218. *buffer = (Mix(*buffer, *temp_buffer, balance) >> 2) * 3;
  219. buffer++;
  220. temp_buffer++;
  221. }
  222. END_INTERPOLATE_PARAMETER_1
  223. }
  224. void MacroOscillator::RenderSineTriangle(
  225. const uint8_t* sync,
  226. int16_t* buffer,
  227. size_t size) {
  228. int32_t attenuation_sine = 32767 - 6 * (pitch_ - (92 << 7));
  229. int32_t attenuation_tri = 32767 - 7 * (pitch_ - (80 << 7));
  230. if (attenuation_tri < 0) attenuation_tri = 0;
  231. if (attenuation_sine < 0) attenuation_sine = 0;
  232. if (attenuation_tri > 32767) attenuation_tri = 32767;
  233. if (attenuation_sine > 32767) attenuation_sine = 32767;
  234. int32_t timbre = parameter_[0];
  235. analog_oscillator_[0].set_parameter(timbre * attenuation_sine >> 15);
  236. analog_oscillator_[1].set_parameter(timbre * attenuation_tri >> 15);
  237. analog_oscillator_[0].set_pitch(pitch_);
  238. analog_oscillator_[1].set_pitch(pitch_);
  239. analog_oscillator_[0].set_shape(OSC_SHAPE_SINE_FOLD);
  240. analog_oscillator_[1].set_shape(OSC_SHAPE_TRIANGLE_FOLD);
  241. analog_oscillator_[0].Render(sync, buffer, NULL, size);
  242. analog_oscillator_[1].Render(sync, temp_buffer_, NULL, size);
  243. int16_t* temp_buffer = temp_buffer_;
  244. BEGIN_INTERPOLATE_PARAMETER_1
  245. while (size--) {
  246. INTERPOLATE_PARAMETER_1
  247. uint16_t balance = parameter_1 << 1;
  248. *buffer = Mix(*buffer, *temp_buffer, balance);
  249. buffer++;
  250. temp_buffer++;
  251. }
  252. END_INTERPOLATE_PARAMETER_1
  253. }
  254. void MacroOscillator::RenderBuzz(
  255. const uint8_t* sync,
  256. int16_t* buffer,
  257. size_t size) {
  258. analog_oscillator_[0].set_parameter(parameter_[0]);
  259. analog_oscillator_[0].set_shape(OSC_SHAPE_BUZZ);
  260. analog_oscillator_[0].set_pitch(pitch_);
  261. analog_oscillator_[1].set_parameter(parameter_[0]);
  262. analog_oscillator_[1].set_shape(OSC_SHAPE_BUZZ);
  263. analog_oscillator_[1].set_pitch(pitch_ + (parameter_[1] >> 8));
  264. analog_oscillator_[0].Render(sync, buffer, NULL, size);
  265. analog_oscillator_[1].Render(sync, temp_buffer_, NULL, size);
  266. int16_t* temp_buffer = temp_buffer_;
  267. while (size--) {
  268. *buffer >>= 1;
  269. *buffer += *temp_buffer >> 1;
  270. buffer++;
  271. temp_buffer++;
  272. }
  273. }
  274. void MacroOscillator::RenderDigital(
  275. const uint8_t* sync,
  276. int16_t* buffer,
  277. size_t size) {
  278. digital_oscillator_.set_parameters(parameter_[0], parameter_[1]);
  279. digital_oscillator_.set_pitch(pitch_);
  280. digital_oscillator_.set_shape(static_cast<DigitalOscillatorShape>(
  281. shape_ - MACRO_OSC_SHAPE_TRIPLE_RING_MOD));
  282. digital_oscillator_.Render(sync, buffer, size);
  283. }
  284. void MacroOscillator::RenderSawComb(
  285. const uint8_t* sync,
  286. int16_t* buffer,
  287. size_t size) {
  288. analog_oscillator_[0].set_parameter(0);
  289. analog_oscillator_[0].set_pitch(pitch_);
  290. analog_oscillator_[0].set_shape(OSC_SHAPE_SAW);
  291. analog_oscillator_[0].Render(sync, buffer, NULL, size);
  292. digital_oscillator_.set_parameters(parameter_[0], parameter_[1]);
  293. digital_oscillator_.set_pitch(pitch_);
  294. digital_oscillator_.set_shape(OSC_SHAPE_COMB_FILTER);
  295. digital_oscillator_.Render(sync, buffer, size);
  296. }
  297. /* static */
  298. MacroOscillator::RenderFn MacroOscillator::fn_table_[] = {
  299. &MacroOscillator::RenderCSaw,
  300. &MacroOscillator::RenderMorph,
  301. &MacroOscillator::RenderSawSquare,
  302. &MacroOscillator::RenderSineTriangle,
  303. &MacroOscillator::RenderBuzz,
  304. &MacroOscillator::RenderDualSync,
  305. &MacroOscillator::RenderDualSync,
  306. &MacroOscillator::RenderTriple,
  307. &MacroOscillator::RenderTriple,
  308. &MacroOscillator::RenderTriple,
  309. &MacroOscillator::RenderTriple,
  310. &MacroOscillator::RenderDigital,
  311. &MacroOscillator::RenderDigital,
  312. &MacroOscillator::RenderSawComb,
  313. &MacroOscillator::RenderDigital,
  314. &MacroOscillator::RenderDigital,
  315. &MacroOscillator::RenderDigital,
  316. &MacroOscillator::RenderDigital,
  317. &MacroOscillator::RenderDigital,
  318. &MacroOscillator::RenderDigital,
  319. &MacroOscillator::RenderDigital,
  320. &MacroOscillator::RenderDigital,
  321. &MacroOscillator::RenderDigital,
  322. &MacroOscillator::RenderDigital,
  323. &MacroOscillator::RenderDigital,
  324. &MacroOscillator::RenderDigital,
  325. &MacroOscillator::RenderDigital,
  326. &MacroOscillator::RenderDigital,
  327. &MacroOscillator::RenderDigital,
  328. &MacroOscillator::RenderDigital,
  329. &MacroOscillator::RenderDigital,
  330. &MacroOscillator::RenderDigital,
  331. &MacroOscillator::RenderDigital,
  332. &MacroOscillator::RenderDigital,
  333. &MacroOscillator::RenderDigital,
  334. &MacroOscillator::RenderDigital,
  335. &MacroOscillator::RenderDigital,
  336. &MacroOscillator::RenderDigital,
  337. &MacroOscillator::RenderDigital,
  338. &MacroOscillator::RenderDigital,
  339. &MacroOscillator::RenderDigital,
  340. &MacroOscillator::RenderDigital,
  341. &MacroOscillator::RenderDigital,
  342. &MacroOscillator::RenderDigital,
  343. &MacroOscillator::RenderDigital,
  344. &MacroOscillator::RenderDigital,
  345. // &MacroOscillator::RenderDigital
  346. };
  347. } // namespace braids