Audio plugin host https://kx.studio/carla
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.

257 lines
7.5KB

  1. /* nekobee DSSI software synthesizer plugin
  2. *
  3. * Copyright (C) 2004 Sean Bolton and others.
  4. *
  5. * Portions of this file may have come from Steve Brookes'
  6. * nekobee, copyright (C) 1999 S. J. Brookes.
  7. * Portions of this file may have come from Peter Hanappe's
  8. * Fluidsynth, copyright (C) 2003 Peter Hanappe and others.
  9. *
  10. * This program is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU General Public License as
  12. * published by the Free Software Foundation; either version 2 of
  13. * the License, or (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be
  16. * useful, but WITHOUT ANY WARRANTY; without even the implied
  17. * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  18. * PURPOSE. See the GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public
  21. * License along with this program; if not, write to the Free
  22. * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  23. * MA 02111-1307, USA.
  24. */
  25. #define _BSD_SOURCE 1
  26. #define _SVID_SOURCE 1
  27. #define _ISOC99_SOURCE 1
  28. #include <stdlib.h>
  29. #include "nekobee_types.h"
  30. #include "nekobee.h"
  31. #include "nekobee_synth.h"
  32. #include "nekobee_voice.h"
  33. /*
  34. * nekobee_voice_new
  35. */
  36. nekobee_voice_t *
  37. nekobee_voice_new()
  38. {
  39. nekobee_voice_t *voice;
  40. voice = (nekobee_voice_t *)calloc(sizeof(nekobee_voice_t), 1);
  41. if (voice) {
  42. voice->status = XSYNTH_VOICE_OFF;
  43. }
  44. return voice;
  45. }
  46. /*
  47. * nekobee_voice_note_on
  48. */
  49. void
  50. nekobee_voice_note_on(nekobee_synth_t *synth, nekobee_voice_t *voice,
  51. unsigned char key, unsigned char velocity)
  52. {
  53. int i;
  54. voice->key = key;
  55. voice->velocity = velocity;
  56. if (!synth->monophonic || !(_ON(voice) || _SUSTAINED(voice))) {
  57. // brand-new voice, or monophonic voice in release phase; set everything up
  58. XDB_MESSAGE(XDB_NOTE, " nekobee_voice_note_on in polyphonic/new section: key %d, mono %d, old status %d\n", key, synth->monophonic, voice->status);
  59. voice->target_pitch = nekobee_pitch[key];
  60. if (synth->held_keys[0] >= 0) {
  61. voice->prev_pitch = nekobee_pitch[synth->held_keys[0]];
  62. } else {
  63. voice->prev_pitch = voice->target_pitch;
  64. }
  65. if (!_PLAYING(voice)) {
  66. voice->lfo_pos = 0.0f;
  67. voice->vca_eg = 0.0f;
  68. voice->vcf_eg = 0.0f;
  69. voice->delay1 = 0.0f;
  70. voice->delay2 = 0.0f;
  71. voice->delay3 = 0.0f;
  72. voice->delay4 = 0.0f;
  73. voice->c5 = 0.0f;
  74. voice->osc_index = 0;
  75. voice->osc1.last_waveform = -1;
  76. voice->osc1.pos = 0.0f;
  77. }
  78. voice->vca_eg_phase = 0;
  79. voice->vcf_eg_phase = 0;
  80. // nekobee_voice_update_pressure_mod(synth, voice);
  81. } else {
  82. /* synth is monophonic, and we're modifying a playing voice */
  83. XDB_MESSAGE(XDB_NOTE, " nekobee_voice_note_on in monophonic section: old key %d => new key %d\n", synth->held_keys[0], key);
  84. /* set new pitch */
  85. voice->target_pitch = nekobee_pitch[key];
  86. if (synth->glide == XSYNTH_GLIDE_MODE_INITIAL ||
  87. synth->glide == XSYNTH_GLIDE_MODE_OFF)
  88. voice->prev_pitch = voice->target_pitch;
  89. /* if in 'on' or 'both' modes, and key has changed, then re-trigger EGs */
  90. if ((synth->monophonic == XSYNTH_MONO_MODE_ON ||
  91. synth->monophonic == XSYNTH_MONO_MODE_BOTH) &&
  92. (synth->held_keys[0] < 0 || synth->held_keys[0] != key)) {
  93. voice->vca_eg_phase = 0;
  94. voice->vcf_eg_phase = 0;
  95. }
  96. /* all other variables stay what they are */
  97. }
  98. synth->last_noteon_pitch = voice->target_pitch;
  99. /* add new key to the list of held keys */
  100. /* check if new key is already in the list; if so, move it to the
  101. * top of the list, otherwise shift the other keys down and add it
  102. * to the top of the list. */
  103. for (i = 0; i < 7; i++) {
  104. if (synth->held_keys[i] == key)
  105. break;
  106. }
  107. for (; i > 0; i--) {
  108. synth->held_keys[i] = synth->held_keys[i - 1];
  109. }
  110. synth->held_keys[0] = key;
  111. if (!_PLAYING(voice)) {
  112. nekobee_voice_start_voice(voice);
  113. } else if (!_ON(voice)) { /* must be XSYNTH_VOICE_SUSTAINED or XSYNTH_VOICE_RELEASED */
  114. voice->status = XSYNTH_VOICE_ON;
  115. }
  116. }
  117. /*
  118. * nekobee_voice_set_release_phase
  119. */
  120. static inline void
  121. nekobee_voice_set_release_phase(nekobee_voice_t *voice)
  122. {
  123. voice->vca_eg_phase = 2;
  124. voice->vcf_eg_phase = 2;
  125. }
  126. /*
  127. * nekobee_voice_remove_held_key
  128. */
  129. inline void
  130. nekobee_voice_remove_held_key(nekobee_synth_t *synth, unsigned char key)
  131. {
  132. int i;
  133. /* check if this key is in list of held keys; if so, remove it and
  134. * shift the other keys up */
  135. for (i = 7; i >= 0; i--) {
  136. if (synth->held_keys[i] == key)
  137. break;
  138. }
  139. if (i >= 0) {
  140. for (; i < 7; i++) {
  141. synth->held_keys[i] = synth->held_keys[i + 1];
  142. }
  143. synth->held_keys[7] = -1;
  144. }
  145. }
  146. /*
  147. * nekobee_voice_note_off
  148. */
  149. void
  150. nekobee_voice_note_off(nekobee_synth_t *synth, nekobee_voice_t *voice,
  151. unsigned char key, unsigned char rvelocity)
  152. {
  153. unsigned char previous_top_key;
  154. XDB_MESSAGE(XDB_NOTE, " nekobee_set_note_off: called for voice %p, key %d\n", voice, key);
  155. /* save release velocity */
  156. voice->velocity = rvelocity;
  157. previous_top_key = synth->held_keys[0];
  158. /* remove this key from list of held keys */
  159. nekobee_voice_remove_held_key(synth, key);
  160. if (synth->held_keys[0] >= 0) {
  161. /* still some keys held */
  162. if (synth->held_keys[0] != previous_top_key) {
  163. /* most-recently-played key has changed */
  164. voice->key = synth->held_keys[0];
  165. XDB_MESSAGE(XDB_NOTE, " note-off in monophonic section: changing pitch to %d\n", voice->key);
  166. voice->target_pitch = nekobee_pitch[voice->key];
  167. if (synth->glide == XSYNTH_GLIDE_MODE_INITIAL ||
  168. synth->glide == XSYNTH_GLIDE_MODE_OFF)
  169. voice->prev_pitch = voice->target_pitch;
  170. /* if mono mode is 'both', re-trigger EGs */
  171. if (synth->monophonic == XSYNTH_MONO_MODE_BOTH && !_RELEASED(voice)) {
  172. voice->vca_eg_phase = 0;
  173. voice->vcf_eg_phase = 0;
  174. }
  175. }
  176. } else { /* no keys still held */
  177. if (XSYNTH_SYNTH_SUSTAINED(synth)) {
  178. /* no more keys in list, but we're sustained */
  179. XDB_MESSAGE(XDB_NOTE, " note-off in monophonic section: sustained with no held keys\n");
  180. if (!_RELEASED(voice))
  181. voice->status = XSYNTH_VOICE_SUSTAINED;
  182. } else { /* not sustained */
  183. /* no more keys in list, so turn off note */
  184. XDB_MESSAGE(XDB_NOTE, " note-off in monophonic section: turning off voice %p\n", voice);
  185. nekobee_voice_set_release_phase(voice);
  186. voice->status = XSYNTH_VOICE_RELEASED;
  187. }
  188. }
  189. }
  190. /*
  191. * nekobee_voice_release_note
  192. */
  193. void
  194. nekobee_voice_release_note(nekobee_synth_t *synth, nekobee_voice_t *voice)
  195. {
  196. XDB_MESSAGE(XDB_NOTE, " nekobee_voice_release_note: turning off voice %p\n", voice);
  197. if (_ON(voice)) {
  198. /* dummy up a release velocity */
  199. voice->rvelocity = 64;
  200. }
  201. nekobee_voice_set_release_phase(voice);
  202. voice->status = XSYNTH_VOICE_RELEASED;
  203. return;
  204. (void)synth;
  205. }