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.

603 lines
16KB

  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. // Oscillator - analog style waveforms.
  28. #include "braids/analog_oscillator.h"
  29. #include "stmlib/utils/dsp.h"
  30. #include "braids/resources.h"
  31. #include "braids/parameter_interpolation.h"
  32. namespace braids {
  33. using namespace stmlib;
  34. static const size_t kNumZones = 15;
  35. static const uint16_t kHighestNote = 128 * 128;
  36. static const uint16_t kPitchTableStart = 128 * 128;
  37. static const uint16_t kOctave = 12 * 128;
  38. uint32_t AnalogOscillator::ComputePhaseIncrement(int16_t midi_pitch) {
  39. if (midi_pitch >= kHighestNote) {
  40. midi_pitch = kHighestNote - 1;
  41. }
  42. int32_t ref_pitch = midi_pitch;
  43. ref_pitch -= kPitchTableStart;
  44. size_t num_shifts = 0;
  45. while (ref_pitch < 0) {
  46. ref_pitch += kOctave;
  47. ++num_shifts;
  48. }
  49. uint32_t a = lut_oscillator_increments[ref_pitch >> 4];
  50. uint32_t b = lut_oscillator_increments[(ref_pitch >> 4) + 1];
  51. uint32_t phase_increment = a + \
  52. (static_cast<int32_t>(b - a) * (ref_pitch & 0xf) >> 4);
  53. phase_increment >>= num_shifts;
  54. return phase_increment;
  55. }
  56. void AnalogOscillator::Render(
  57. const uint8_t* sync_in,
  58. int16_t* buffer,
  59. uint8_t* sync_out,
  60. size_t size) {
  61. RenderFn fn = fn_table_[shape_];
  62. if (shape_ != previous_shape_) {
  63. Init();
  64. previous_shape_ = shape_;
  65. }
  66. phase_increment_ = ComputePhaseIncrement(pitch_);
  67. if (pitch_ > kHighestNote) {
  68. pitch_ = kHighestNote;
  69. } else if (pitch_ < 0) {
  70. pitch_ = 0;
  71. }
  72. (this->*fn)(sync_in, buffer, sync_out, size);
  73. }
  74. void AnalogOscillator::RenderCSaw(
  75. const uint8_t* sync_in,
  76. int16_t* buffer,
  77. uint8_t* sync_out,
  78. size_t size) {
  79. BEGIN_INTERPOLATE_PHASE_INCREMENT
  80. int32_t next_sample = next_sample_;
  81. while (size--) {
  82. bool sync_reset = false;
  83. bool self_reset = false;
  84. bool transition_during_reset = false;
  85. uint32_t reset_time = 0;
  86. INTERPOLATE_PHASE_INCREMENT
  87. uint32_t pw = static_cast<uint32_t>(parameter_) * 49152;
  88. if (pw < 8 * phase_increment) {
  89. pw = 8 * phase_increment;
  90. }
  91. int32_t this_sample = next_sample;
  92. next_sample = 0;
  93. if (*sync_in) {
  94. // sync_in contain the fractional reset time.
  95. reset_time = static_cast<uint32_t>(*sync_in - 1) << 9;
  96. uint32_t phase_at_reset = phase_ + \
  97. (65535 - reset_time) * (phase_increment >> 16);
  98. sync_reset = true;
  99. transition_during_reset = false;
  100. if (phase_at_reset < phase_ || (!high_ && phase_at_reset >= pw)) {
  101. transition_during_reset = true;
  102. }
  103. if (phase_ >= pw) {
  104. discontinuity_depth_ = -2048 + (aux_parameter_ >> 2);
  105. int32_t before = (phase_at_reset >> 18);
  106. int16_t after = discontinuity_depth_;
  107. int32_t discontinuity = after - before;
  108. this_sample += discontinuity * ThisBlepSample(reset_time) >> 15;
  109. next_sample += discontinuity * NextBlepSample(reset_time) >> 15;
  110. }
  111. }
  112. sync_in++;
  113. phase_ += phase_increment;
  114. if (phase_ < phase_increment) {
  115. self_reset = true;
  116. }
  117. if (sync_out) {
  118. if (phase_ < phase_increment) {
  119. *sync_out++ = phase_ / (phase_increment >> 7) + 1;
  120. } else {
  121. *sync_out++ = 0;
  122. }
  123. }
  124. while (transition_during_reset || !sync_reset) {
  125. if (!high_) {
  126. if (phase_ < pw) {
  127. break;
  128. }
  129. uint32_t t = (phase_ - pw) / (phase_increment >> 16);
  130. int16_t before = discontinuity_depth_;
  131. int16_t after = phase_ >> 18;
  132. int16_t discontinuity = after - before;
  133. this_sample += discontinuity * ThisBlepSample(t) >> 15;
  134. next_sample += discontinuity * NextBlepSample(t) >> 15;
  135. high_ = true;
  136. }
  137. if (high_) {
  138. if (!self_reset) {
  139. break;
  140. }
  141. self_reset = false;
  142. discontinuity_depth_ = -2048 + (aux_parameter_ >> 2);
  143. uint32_t t = phase_ / (phase_increment >> 16);
  144. int16_t before = 16383;
  145. int16_t after = discontinuity_depth_;
  146. int16_t discontinuity = after - before;
  147. this_sample += discontinuity * ThisBlepSample(t) >> 15;
  148. next_sample += discontinuity * NextBlepSample(t) >> 15;
  149. high_ = false;
  150. }
  151. }
  152. if (sync_reset) {
  153. phase_ = reset_time * (phase_increment >> 16);
  154. high_ = false;
  155. }
  156. next_sample += phase_ < pw
  157. ? discontinuity_depth_
  158. : phase_ >> 18;
  159. *buffer++ = (this_sample - 8192) << 1;
  160. }
  161. next_sample_ = next_sample;
  162. END_INTERPOLATE_PHASE_INCREMENT
  163. }
  164. void AnalogOscillator::RenderSquare(
  165. const uint8_t* sync_in,
  166. int16_t* buffer,
  167. uint8_t* sync_out,
  168. size_t size) {
  169. BEGIN_INTERPOLATE_PHASE_INCREMENT
  170. if (parameter_ > 32000) {
  171. parameter_ = 32000;
  172. }
  173. int32_t next_sample = next_sample_;
  174. while (size--) {
  175. bool sync_reset = false;
  176. bool self_reset = false;
  177. bool transition_during_reset = false;
  178. uint32_t reset_time = 0;
  179. INTERPOLATE_PHASE_INCREMENT
  180. uint32_t pw = static_cast<uint32_t>(32768 - parameter_) << 16;
  181. int32_t this_sample = next_sample;
  182. next_sample = 0;
  183. if (*sync_in) {
  184. // sync_in contain the fractional reset time.
  185. reset_time = static_cast<uint32_t>(*sync_in - 1) << 9;
  186. uint32_t phase_at_reset = phase_ + \
  187. (65535 - reset_time) * (phase_increment >> 16);
  188. sync_reset = true;
  189. if (phase_at_reset < phase_ || (!high_ && phase_at_reset >= pw)) {
  190. transition_during_reset = true;
  191. }
  192. if (phase_at_reset >= pw) {
  193. this_sample -= ThisBlepSample(reset_time);
  194. next_sample -= NextBlepSample(reset_time);
  195. }
  196. }
  197. sync_in++;
  198. phase_ += phase_increment;
  199. if (phase_ < phase_increment) {
  200. self_reset = true;
  201. }
  202. if (sync_out) {
  203. if (phase_ < phase_increment) {
  204. *sync_out++ = phase_ / (phase_increment >> 7) + 1;
  205. } else {
  206. *sync_out++ = 0;
  207. }
  208. }
  209. while (transition_during_reset || !sync_reset) {
  210. if (!high_) {
  211. if (phase_ < pw) {
  212. break;
  213. }
  214. uint32_t t = (phase_ - pw) / (phase_increment >> 16);
  215. this_sample += ThisBlepSample(t);
  216. next_sample += NextBlepSample(t);
  217. high_ = true;
  218. }
  219. if (high_) {
  220. if (!self_reset) {
  221. break;
  222. }
  223. self_reset = false;
  224. uint32_t t = phase_ / (phase_increment >> 16);
  225. this_sample -= ThisBlepSample(t);
  226. next_sample -= NextBlepSample(t);
  227. high_ = false;
  228. }
  229. }
  230. if (sync_reset) {
  231. phase_ = reset_time * (phase_increment >> 16);
  232. high_ = false;
  233. }
  234. next_sample += phase_ < pw ? 0 : 32767;
  235. *buffer++ = (this_sample - 16384) << 1;
  236. }
  237. next_sample_ = next_sample;
  238. END_INTERPOLATE_PHASE_INCREMENT
  239. }
  240. void AnalogOscillator::RenderSaw(
  241. const uint8_t* sync_in,
  242. int16_t* buffer,
  243. uint8_t* sync_out,
  244. size_t size) {
  245. BEGIN_INTERPOLATE_PHASE_INCREMENT
  246. int32_t next_sample = next_sample_;
  247. while (size--) {
  248. bool sync_reset = false;
  249. bool self_reset = false;
  250. bool transition_during_reset = false;
  251. uint32_t reset_time = 0;
  252. INTERPOLATE_PHASE_INCREMENT
  253. int32_t this_sample = next_sample;
  254. next_sample = 0;
  255. if (*sync_in) {
  256. // sync_in contain the fractional reset time.
  257. reset_time = static_cast<uint32_t>(*sync_in - 1) << 9;
  258. uint32_t phase_at_reset = phase_ + \
  259. (65535 - reset_time) * (phase_increment >> 16);
  260. sync_reset = true;
  261. if (phase_at_reset < phase_) {
  262. transition_during_reset = true;
  263. }
  264. int32_t discontinuity = phase_at_reset >> 17;
  265. this_sample -= discontinuity * ThisBlepSample(reset_time) >> 15;
  266. next_sample -= discontinuity * NextBlepSample(reset_time) >> 15;
  267. }
  268. sync_in++;
  269. phase_ += phase_increment;
  270. if (phase_ < phase_increment) {
  271. self_reset = true;
  272. }
  273. if (sync_out) {
  274. if (phase_ < phase_increment) {
  275. *sync_out++ = phase_ / (phase_increment >> 7) + 1;
  276. } else {
  277. *sync_out++ = 0;
  278. }
  279. }
  280. if ((transition_during_reset || !sync_reset) && self_reset) {
  281. uint32_t t = phase_ / (phase_increment >> 16);
  282. this_sample -= ThisBlepSample(t);
  283. next_sample -= NextBlepSample(t);
  284. }
  285. if (sync_reset) {
  286. phase_ = reset_time * (phase_increment >> 16);
  287. high_ = false;
  288. }
  289. next_sample += phase_ >> 17;
  290. *buffer++ = (this_sample - 16384) << 1;
  291. }
  292. next_sample_ = next_sample;
  293. END_INTERPOLATE_PHASE_INCREMENT
  294. }
  295. void AnalogOscillator::RenderVariableSaw(
  296. const uint8_t* sync_in,
  297. int16_t* buffer,
  298. uint8_t* sync_out,
  299. size_t size) {
  300. BEGIN_INTERPOLATE_PHASE_INCREMENT
  301. int32_t next_sample = next_sample_;
  302. if (parameter_ < 1024) {
  303. parameter_ = 1024;
  304. }
  305. while (size--) {
  306. bool sync_reset = false;
  307. bool self_reset = false;
  308. bool transition_during_reset = false;
  309. uint32_t reset_time = 0;
  310. INTERPOLATE_PHASE_INCREMENT
  311. uint32_t pw = static_cast<uint32_t>(parameter_) << 16;
  312. int32_t this_sample = next_sample;
  313. next_sample = 0;
  314. if (*sync_in) {
  315. // sync_in contain the fractional reset time.
  316. reset_time = static_cast<uint32_t>(*sync_in - 1) << 9;
  317. uint32_t phase_at_reset = phase_ + \
  318. (65535 - reset_time) * (phase_increment >> 16);
  319. sync_reset = true;
  320. if (phase_at_reset < phase_ || (!high_ && phase_at_reset >= pw)) {
  321. transition_during_reset = true;
  322. }
  323. int32_t before = (phase_at_reset >> 18) + ((phase_at_reset - pw) >> 18);
  324. int32_t after = (0 >> 18) + ((0 - pw) >> 18);
  325. int32_t discontinuity = after - before;
  326. this_sample += discontinuity * ThisBlepSample(reset_time) >> 15;
  327. next_sample += discontinuity * NextBlepSample(reset_time) >> 15;
  328. }
  329. sync_in++;
  330. phase_ += phase_increment;
  331. if (phase_ < phase_increment) {
  332. self_reset = true;
  333. }
  334. if (sync_out) {
  335. if (phase_ < phase_increment) {
  336. *sync_out++ = phase_ / (phase_increment >> 7) + 1;
  337. } else {
  338. *sync_out++ = 0;
  339. }
  340. }
  341. while (transition_during_reset || !sync_reset) {
  342. if (!high_) {
  343. if (phase_ < pw) {
  344. break;
  345. }
  346. uint32_t t = (phase_ - pw) / (phase_increment >> 16);
  347. this_sample -= ThisBlepSample(t) >> 1;
  348. next_sample -= NextBlepSample(t) >> 1;
  349. high_ = true;
  350. }
  351. if (high_) {
  352. if (!self_reset) {
  353. break;
  354. }
  355. self_reset = false;
  356. uint32_t t = phase_ / (phase_increment >> 16);
  357. this_sample -= ThisBlepSample(t) >> 1;
  358. next_sample -= NextBlepSample(t) >> 1;
  359. high_ = false;
  360. }
  361. }
  362. if (sync_reset) {
  363. phase_ = reset_time * (phase_increment >> 16);
  364. high_ = false;
  365. }
  366. next_sample += phase_ >> 18;
  367. next_sample += (phase_ - pw) >> 18;
  368. *buffer++ = (this_sample - 16384) << 1;
  369. }
  370. next_sample_ = next_sample;
  371. END_INTERPOLATE_PHASE_INCREMENT
  372. }
  373. void AnalogOscillator::RenderTriangle(
  374. const uint8_t* sync_in,
  375. int16_t* buffer,
  376. uint8_t* sync_out,
  377. size_t size) {
  378. BEGIN_INTERPOLATE_PHASE_INCREMENT
  379. uint32_t phase = phase_;
  380. while (size--) {
  381. INTERPOLATE_PHASE_INCREMENT
  382. int16_t triangle;
  383. uint16_t phase_16;
  384. if (*sync_in++) {
  385. phase = 0;
  386. }
  387. phase += phase_increment >> 1;
  388. phase_16 = phase >> 16;
  389. triangle = (phase_16 << 1) ^ (phase_16 & 0x8000 ? 0xffff : 0x0000);
  390. triangle += 32768;
  391. *buffer = triangle >> 1;
  392. phase += phase_increment >> 1;
  393. phase_16 = phase >> 16;
  394. triangle = (phase_16 << 1) ^ (phase_16 & 0x8000 ? 0xffff : 0x0000);
  395. triangle += 32768;
  396. *buffer++ += triangle >> 1;
  397. }
  398. phase_ = phase;
  399. END_INTERPOLATE_PHASE_INCREMENT
  400. }
  401. void AnalogOscillator::RenderSine(
  402. const uint8_t* sync_in,
  403. int16_t* buffer,
  404. uint8_t* sync_out,
  405. size_t size) {
  406. uint32_t phase = phase_;
  407. BEGIN_INTERPOLATE_PHASE_INCREMENT
  408. while (size--) {
  409. INTERPOLATE_PHASE_INCREMENT
  410. phase += phase_increment;
  411. if (*sync_in++) {
  412. phase = 0;
  413. }
  414. *buffer++ = Interpolate824(wav_sine, phase);
  415. }
  416. END_INTERPOLATE_PHASE_INCREMENT
  417. phase_ = phase;
  418. }
  419. void AnalogOscillator::RenderTriangleFold(
  420. const uint8_t* sync_in,
  421. int16_t* buffer,
  422. uint8_t* sync_out,
  423. size_t size) {
  424. uint32_t phase = phase_;
  425. BEGIN_INTERPOLATE_PHASE_INCREMENT
  426. BEGIN_INTERPOLATE_PARAMETER
  427. while (size--) {
  428. INTERPOLATE_PARAMETER
  429. INTERPOLATE_PHASE_INCREMENT
  430. uint16_t phase_16;
  431. int16_t triangle;
  432. int16_t gain = 2048 + (parameter * 30720 >> 15);
  433. if (*sync_in++) {
  434. phase = 0;
  435. }
  436. // 2x oversampled WF.
  437. phase += phase_increment >> 1;
  438. phase_16 = phase >> 16;
  439. triangle = (phase_16 << 1) ^ (phase_16 & 0x8000 ? 0xffff : 0x0000);
  440. triangle += 32768;
  441. triangle = triangle * gain >> 15;
  442. triangle = Interpolate88(ws_tri_fold, triangle + 32768);
  443. *buffer = triangle >> 1;
  444. phase += phase_increment >> 1;
  445. phase_16 = phase >> 16;
  446. triangle = (phase_16 << 1) ^ (phase_16 & 0x8000 ? 0xffff : 0x0000);
  447. triangle += 32768;
  448. triangle = triangle * gain >> 15;
  449. triangle = Interpolate88(ws_tri_fold, triangle + 32768);
  450. *buffer++ += triangle >> 1;
  451. }
  452. END_INTERPOLATE_PARAMETER
  453. END_INTERPOLATE_PHASE_INCREMENT
  454. phase_ = phase;
  455. }
  456. void AnalogOscillator::RenderSineFold(
  457. const uint8_t* sync_in,
  458. int16_t* buffer,
  459. uint8_t* sync_out,
  460. size_t size) {
  461. uint32_t phase = phase_;
  462. BEGIN_INTERPOLATE_PHASE_INCREMENT
  463. BEGIN_INTERPOLATE_PARAMETER
  464. while (size--) {
  465. INTERPOLATE_PARAMETER
  466. INTERPOLATE_PHASE_INCREMENT
  467. int16_t sine;
  468. int16_t gain = 2048 + (parameter * 30720 >> 15);
  469. if (*sync_in++) {
  470. phase = 0;
  471. }
  472. // 2x oversampled WF.
  473. phase += phase_increment >> 1;
  474. sine = Interpolate824(wav_sine, phase);
  475. sine = sine * gain >> 15;
  476. sine = Interpolate88(ws_sine_fold, sine + 32768);
  477. *buffer = sine >> 1;
  478. phase += phase_increment >> 1;
  479. sine = Interpolate824(wav_sine, phase);
  480. sine = sine * gain >> 15;
  481. sine = Interpolate88(ws_sine_fold, sine + 32768);
  482. *buffer++ += sine >> 1;
  483. }
  484. END_INTERPOLATE_PARAMETER
  485. END_INTERPOLATE_PHASE_INCREMENT
  486. phase_ = phase;
  487. }
  488. void AnalogOscillator::RenderBuzz(
  489. const uint8_t* sync_in,
  490. int16_t* buffer,
  491. uint8_t* sync_out,
  492. size_t size) {
  493. int32_t shifted_pitch = pitch_ + ((32767 - parameter_) >> 1);
  494. uint16_t crossfade = shifted_pitch << 6;
  495. size_t index = (shifted_pitch >> 10);
  496. if (index >= kNumZones) {
  497. index = kNumZones - 1;
  498. }
  499. const int16_t* wave_1 = waveform_table[WAV_BANDLIMITED_COMB_0 + index];
  500. index += 1;
  501. if (index >= kNumZones) {
  502. index = kNumZones - 1;
  503. }
  504. const int16_t* wave_2 = waveform_table[WAV_BANDLIMITED_COMB_0 + index];
  505. while (size--) {
  506. phase_ += phase_increment_;
  507. if (*sync_in++) {
  508. phase_ = 0;
  509. }
  510. *buffer++ = Crossfade(wave_1, wave_2, phase_, crossfade);
  511. }
  512. }
  513. /* static */
  514. AnalogOscillator::RenderFn AnalogOscillator::fn_table_[] = {
  515. &AnalogOscillator::RenderSaw,
  516. &AnalogOscillator::RenderVariableSaw,
  517. &AnalogOscillator::RenderCSaw,
  518. &AnalogOscillator::RenderSquare,
  519. &AnalogOscillator::RenderTriangle,
  520. &AnalogOscillator::RenderSine,
  521. &AnalogOscillator::RenderTriangleFold,
  522. &AnalogOscillator::RenderSineFold,
  523. &AnalogOscillator::RenderBuzz,
  524. };
  525. } // namespace braids