LMMS
Loading...
Searching...
No Matches
nekobee_voice.c
Go to the documentation of this file.
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
26#define _BSD_SOURCE 1
27#define _SVID_SOURCE 1
28#define _ISOC99_SOURCE 1
29
30#include <stdlib.h>
31
32#include "nekobee_types.h"
33#include "nekobee.h"
34#include "nekobee_synth.h"
35#include "nekobee_voice.h"
36
37/*
38 * nekobee_voice_new
39 */
42{
43 nekobee_voice_t *voice;
44
45 voice = (nekobee_voice_t *)calloc(sizeof(nekobee_voice_t), 1);
46 if (voice) {
47 voice->status = XSYNTH_VOICE_OFF;
48 }
49 return voice;
50}
51
52/*
53 * nekobee_voice_note_on
54 */
55void
57 unsigned char key, unsigned char velocity)
58{
59 int i;
60
61 voice->key = key;
62 voice->velocity = velocity;
63
64
65 if (!synth->monophonic || !(_ON(voice) || _SUSTAINED(voice))) {
66
67 // brand-new voice, or monophonic voice in release phase; set everything up
68 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);
69
71
72
73 if (synth->held_keys[0] >= 0) {
74 voice->prev_pitch = nekobee_pitch[synth->held_keys[0]];
75 } else {
76 voice->prev_pitch = voice->target_pitch;
77 }
78
79 if (!_PLAYING(voice)) {
80 voice->lfo_pos = 0.0f;
81 voice->vca_eg = 0.0f;
82 voice->vcf_eg = 0.0f;
83 voice->delay1 = 0.0f;
84 voice->delay2 = 0.0f;
85 voice->delay3 = 0.0f;
86 voice->delay4 = 0.0f;
87 voice->c5 = 0.0f;
88 voice->osc_index = 0;
89 voice->osc1.last_waveform = -1;
90 voice->osc1.pos = 0.0f;
91
92 }
93 voice->vca_eg_phase = 0;
94 voice->vcf_eg_phase = 0;
95// nekobee_voice_update_pressure_mod(synth, voice);
96
97 } else {
98
99 /* synth is monophonic, and we're modifying a playing voice */
100 XDB_MESSAGE(XDB_NOTE, " nekobee_voice_note_on in monophonic section: old key %d => new key %d\n", synth->held_keys[0], key);
101
102 /* set new pitch */
104 if (synth->glide == XSYNTH_GLIDE_MODE_INITIAL ||
106 voice->prev_pitch = voice->target_pitch;
107
108 /* if in 'on' or 'both' modes, and key has changed, then re-trigger EGs */
109 if ((synth->monophonic == XSYNTH_MONO_MODE_ON ||
110 synth->monophonic == XSYNTH_MONO_MODE_BOTH) &&
111 (synth->held_keys[0] < 0 || synth->held_keys[0] != key)) {
112 voice->vca_eg_phase = 0;
113 voice->vcf_eg_phase = 0;
114 }
115
116 /* all other variables stay what they are */
117
118 }
119 synth->last_noteon_pitch = voice->target_pitch;
120
121 /* add new key to the list of held keys */
122
123 /* check if new key is already in the list; if so, move it to the
124 * top of the list, otherwise shift the other keys down and add it
125 * to the top of the list. */
126 for (i = 0; i < 7; i++) {
127 if (synth->held_keys[i] == key)
128 break;
129 }
130 for (; i > 0; i--) {
131 synth->held_keys[i] = synth->held_keys[i - 1];
132 }
133 synth->held_keys[0] = key;
134
135 if (!_PLAYING(voice)) {
136
138
139 } else if (!_ON(voice)) { /* must be XSYNTH_VOICE_SUSTAINED or XSYNTH_VOICE_RELEASED */
140
141 voice->status = XSYNTH_VOICE_ON;
142
143 }
144}
145
146/*
147 * nekobee_voice_set_release_phase
148 */
149static inline void
151{
152 voice->vca_eg_phase = 2;
153 voice->vcf_eg_phase = 2;
154}
155
156/*
157 * nekobee_voice_remove_held_key
158 */
159inline void
161{
162 int i;
163
164 /* check if this key is in list of held keys; if so, remove it and
165 * shift the other keys up */
166 for (i = 7; i >= 0; i--) {
167 if (synth->held_keys[i] == key)
168 break;
169 }
170 if (i >= 0) {
171 for (; i < 7; i++) {
172 synth->held_keys[i] = synth->held_keys[i + 1];
173 }
174 synth->held_keys[7] = -1;
175 }
176}
177
178/*
179 * nekobee_voice_note_off
180 */
181void
183 unsigned char key, unsigned char rvelocity)
184{
185 unsigned char previous_top_key;
186
187 XDB_MESSAGE(XDB_NOTE, " nekobee_set_note_off: called for voice %p, key %d\n", voice, key);
188
189 /* save release velocity */
190 voice->velocity = rvelocity;
191
192 previous_top_key = synth->held_keys[0];
193
194 /* remove this key from list of held keys */
196
197 if (synth->held_keys[0] >= 0) {
198
199 /* still some keys held */
200
201 if (synth->held_keys[0] != previous_top_key) {
202
203 /* most-recently-played key has changed */
204 voice->key = synth->held_keys[0];
205 XDB_MESSAGE(XDB_NOTE, " note-off in monophonic section: changing pitch to %d\n", voice->key);
206 voice->target_pitch = nekobee_pitch[voice->key];
207 if (synth->glide == XSYNTH_GLIDE_MODE_INITIAL ||
209 voice->prev_pitch = voice->target_pitch;
210
211 /* if mono mode is 'both', re-trigger EGs */
212 if (synth->monophonic == XSYNTH_MONO_MODE_BOTH && !_RELEASED(voice)) {
213 voice->vca_eg_phase = 0;
214 voice->vcf_eg_phase = 0;
215 }
216
217 }
218
219 } else { /* no keys still held */
220
222
223 /* no more keys in list, but we're sustained */
224 XDB_MESSAGE(XDB_NOTE, " note-off in monophonic section: sustained with no held keys\n");
225 if (!_RELEASED(voice))
227
228 } else { /* not sustained */
229
230 /* no more keys in list, so turn off note */
231 XDB_MESSAGE(XDB_NOTE, " note-off in monophonic section: turning off voice %p\n", voice);
234
235 }
236 }
237
238}
239
240/*
241 * nekobee_voice_release_note
242 */
243void
245{
246 XDB_MESSAGE(XDB_NOTE, " nekobee_voice_release_note: turning off voice %p\n", voice);
247 if (_ON(voice)) {
248 /* dummy up a release velocity */
249 voice->rvelocity = 64;
250 }
253
254 return;
255 (void)synth;
256}
SYNTH_T * synth
Definition LocalZynAddSubFx.cpp:47
register unsigned i
Definition inflate.c:1575
#define XDB_MESSAGE(type, fmt...)
Definition nekobee.h:66
#define XDB_NOTE
Definition nekobee.h:32
#define XSYNTH_GLIDE_MODE_OFF
Definition nekobee_synth.h:43
#define XSYNTH_GLIDE_MODE_INITIAL
Definition nekobee_synth.h:40
#define XSYNTH_SYNTH_SUSTAINED(_s)
Definition nekobee_synth.h:130
#define XSYNTH_MONO_MODE_ON
Definition nekobee_synth.h:35
#define XSYNTH_MONO_MODE_BOTH
Definition nekobee_synth.h:37
struct _nekobee_synth_t nekobee_synth_t
Definition nekobee_types.h:26
struct _nekobee_voice_t nekobee_voice_t
Definition nekobee_types.h:27
nekobee_voice_t * nekobee_voice_new()
Definition nekobee_voice.c:41
void nekobee_voice_release_note(nekobee_synth_t *synth, nekobee_voice_t *voice)
Definition nekobee_voice.c:244
void nekobee_voice_note_on(nekobee_synth_t *synth, nekobee_voice_t *voice, unsigned char key, unsigned char velocity)
Definition nekobee_voice.c:56
static void nekobee_voice_set_release_phase(nekobee_voice_t *voice)
Definition nekobee_voice.c:150
void nekobee_voice_note_off(nekobee_synth_t *synth, nekobee_voice_t *voice, unsigned char key, unsigned char rvelocity)
Definition nekobee_voice.c:182
void nekobee_voice_remove_held_key(nekobee_synth_t *synth, unsigned char key)
Definition nekobee_voice.c:160
@ XSYNTH_VOICE_RELEASED
Definition nekobee_voice.h:70
@ XSYNTH_VOICE_SUSTAINED
Definition nekobee_voice.h:69
@ XSYNTH_VOICE_ON
Definition nekobee_voice.h:68
@ XSYNTH_VOICE_OFF
Definition nekobee_voice.h:67
float nekobee_pitch[128]
Definition nekobee_voice_render.c:25
#define _PLAYING(voice)
Definition nekobee_voice.h:118
#define _ON(voice)
Definition nekobee_voice.h:119
#define _RELEASED(voice)
Definition nekobee_voice.h:121
static void nekobee_voice_start_voice(nekobee_voice_t *voice)
Definition nekobee_voice.h:177
#define _SUSTAINED(voice)
Definition nekobee_voice.h:120
float prev_pitch
Definition nekobee_voice.h:98
float delay3
Definition nekobee_voice.h:107
unsigned char status
Definition nekobee_voice.h:89
unsigned char key
Definition nekobee_voice.h:90
float vcf_eg
Definition nekobee_voice.h:103
struct blosc osc1
Definition nekobee_voice.h:101
float delay1
Definition nekobee_voice.h:105
unsigned char vca_eg_phase
Definition nekobee_voice.h:110
unsigned char vcf_eg_phase
Definition nekobee_voice.h:111
unsigned char rvelocity
Definition nekobee_voice.h:92
float c5
Definition nekobee_voice.h:109
float delay2
Definition nekobee_voice.h:106
int osc_index
Definition nekobee_voice.h:112
float target_pitch
Definition nekobee_voice.h:99
unsigned char velocity
Definition nekobee_voice.h:91
float vca_eg
Definition nekobee_voice.h:102
float delay4
Definition nekobee_voice.h:108
float lfo_pos
Definition nekobee_voice.h:100
float pos
Definition nekobee_voice.h:78
int last_waveform
Definition nekobee_voice.h:75
ZCONST char * key
Definition crypt.c:587
#define void
Definition unzip.h:396