diff options
Diffstat (limited to 'apps/plugins/midi/sequencer.c')
-rw-r--r-- | apps/plugins/midi/sequencer.c | 470 |
1 files changed, 228 insertions, 242 deletions
diff --git a/apps/plugins/midi/sequencer.c b/apps/plugins/midi/sequencer.c index 836866a5df..4781963645 100644 --- a/apps/plugins/midi/sequencer.c +++ b/apps/plugins/midi/sequencer.c | |||
@@ -24,233 +24,220 @@ long tempo=375000; | |||
24 | 24 | ||
25 | void setVol(int ch, int vol) | 25 | void setVol(int ch, int vol) |
26 | { | 26 | { |
27 | printf("\nvolume[%d] %d ==> %d", ch, chVol[ch], vol); | 27 | printf("\nvolume[%d] %d ==> %d", ch, chVol[ch], vol); |
28 | chVol[ch]=vol; | 28 | chVol[ch]=vol; |
29 | } | 29 | } |
30 | 30 | ||
31 | void setPan(int ch, int pan) | 31 | void setPan(int ch, int pan) |
32 | { | 32 | { |
33 | printf("\npanning[%d] %d ==> %d", ch, chPanRight[ch], pan); | 33 | printf("\npanning[%d] %d ==> %d", ch, chPanRight[ch], pan); |
34 | 34 | ||
35 | chPanLeft[ch]=128-pan; | 35 | chPanLeft[ch]=128-pan; |
36 | chPanRight[ch]=pan; | 36 | chPanRight[ch]=pan; |
37 | } | 37 | } |
38 | 38 | ||
39 | 39 | ||
40 | void setPatch(int ch, int pat) | 40 | void setPatch(int ch, int pat) |
41 | { | 41 | { |
42 | chPat[ch]=pat; | 42 | chPat[ch]=pat; |
43 | } | 43 | } |
44 | 44 | ||
45 | 45 | ||
46 | /* | 46 | /* |
47 | Pitch Bend table, Computed by | 47 | * Pitch Bend table, Computed by |
48 | for i=0:127, fprintf('%d,', round(2^16*2^((i-64)/384))); end | 48 | * for i=0:127, fprintf('%d,', round(2^16*2^((i-64)/384))); end |
49 | (When typed into Matlab) | 49 | * (When typed into Matlab) |
50 | 16 bit pitch bend table | 50 | * 16 bit pitch bend table |
51 | */ | 51 | */ |
52 | long pitchTbl[]= | 52 | long pitchTbl[]= |
53 | { | 53 | { |
54 | 58386,58491,58597,58703,58809,58915,59022,59128,59235,59342,59449,59557,59664,59772,59880,59988,60097,60205, | 54 | 58386,58491,58597,58703,58809,58915,59022,59128,59235,59342,59449,59557,59664,59772,59880,59988,60097,60205, |
55 | 60314,60423,60532,60642,60751,60861,60971,61081,61191,61302,61413,61524,61635,61746,61858,61970,62081,62194, | 55 | 60314,60423,60532,60642,60751,60861,60971,61081,61191,61302,61413,61524,61635,61746,61858,61970,62081,62194, |
56 | 62306,62419,62531,62644,62757,62871,62984,63098,63212,63326,63441,63555,63670,63785,63901,64016,64132,64248, | 56 | 62306,62419,62531,62644,62757,62871,62984,63098,63212,63326,63441,63555,63670,63785,63901,64016,64132,64248, |
57 | 64364,64480,64596,64713,64830,64947,65065,65182,65300,65418,65536,65654,65773,65892,66011,66130,66250,66369, | 57 | 64364,64480,64596,64713,64830,64947,65065,65182,65300,65418,65536,65654,65773,65892,66011,66130,66250,66369, |
58 | 66489,66609,66730,66850,66971,67092,67213,67335,67456,67578,67700,67823,67945,68068,68191,68314,68438,68561, | 58 | 66489,66609,66730,66850,66971,67092,67213,67335,67456,67578,67700,67823,67945,68068,68191,68314,68438,68561, |
59 | 68685,68809,68933,69058,69183,69308,69433,69558,69684,69810,69936,70062,70189,70316,70443,70570,70698,70825, | 59 | 68685,68809,68933,69058,69183,69308,69433,69558,69684,69810,69936,70062,70189,70316,70443,70570,70698,70825, |
60 | 70953,71082,71210,71339,71468,71597,71726,71856,71985,72115,72246,72376,72507,72638,72769,72901,73032,73164, | 60 | 70953,71082,71210,71339,71468,71597,71726,71856,71985,72115,72246,72376,72507,72638,72769,72901,73032,73164, |
61 | 73297,73429 | 61 | 73297,73429 |
62 | }; | 62 | }; |
63 | 63 | ||
64 | 64 | ||
65 | void findDelta(struct SynthObject * so, int ch, int note) | 65 | void findDelta(struct SynthObject * so, int ch, int note) |
66 | { | 66 | { |
67 | 67 | ||
68 | struct GWaveform * wf = patchSet[chPat[ch]]->waveforms[patchSet[chPat[ch]]->noteTable[note]]; | 68 | struct GWaveform * wf = patchSet[chPat[ch]]->waveforms[patchSet[chPat[ch]]->noteTable[note]]; |
69 | so->wf=wf; | 69 | so->wf=wf; |
70 | so->delta = (((gustable[note]<<10) / wf->rootFreq) * wf->sampRate / SAMPLE_RATE); | 70 | so->delta = (((gustable[note]<<10) / (wf->rootFreq)) * wf->sampRate / (SAMPLE_RATE)); |
71 | so->delta = so->delta * pitchTbl[chPW[ch]] >> 16; | 71 | so->delta = (so->delta * pitchTbl[chPW[ch]])>> 16; |
72 | } | 72 | } |
73 | 73 | ||
74 | void setPW(int ch, int msb) | 74 | void setPW(int ch, int msb) |
75 | { | 75 | { |
76 | printf("\npitchw[%d] %d ==> %d", ch, chPW[ch], msb); | 76 | printf("\npitchw[%d] %d ==> %d", ch, chPW[ch], msb); |
77 | chPW[ch] = msb; | 77 | chPW[ch] = msb; |
78 | 78 | ||
79 | int a=0; | 79 | int a=0; |
80 | for(a = 0; a<MAX_VOICES; a++) | 80 | for(a = 0; a<MAX_VOICES; a++) |
81 | { | 81 | { |
82 | if(voices[a].isUsed==1 && voices[a].ch == ch) | 82 | if(voices[a].isUsed==1 && voices[a].ch == ch) |
83 | { | 83 | { |
84 | findDelta(&voices[a], ch, voices[a].note); | 84 | findDelta(&voices[a], ch, voices[a].note); |
85 | } | 85 | } |
86 | } | 86 | } |
87 | } | 87 | } |
88 | 88 | ||
89 | void pressNote(int ch, int note, int vol) | 89 | void pressNote(int ch, int note, int vol) |
90 | { | 90 | { |
91 | |||
92 | //Silences all channels but one, for easy debugging, for me. | ||
91 | /* | 93 | /* |
92 | if(ch == 0) return; | 94 | if(ch == 0) return; |
93 | // if(ch == 1) return; | 95 | if(ch == 1) return; |
94 | if(ch == 2) return; | 96 | if(ch == 2) return; |
95 | if(ch == 3) return; | 97 | if(ch == 3) return; |
96 | if(ch == 4) return; | 98 | // if(ch == 4) return; |
97 | if(ch == 5) return; | 99 | if(ch == 5) return; |
98 | if(ch == 6) return; | 100 | if(ch == 6) return; |
99 | if(ch == 7) return; | 101 | if(ch == 7) return; |
100 | if(ch == 8) return; | 102 | if(ch == 8) return; |
101 | if(ch == 9) return; | 103 | if(ch == 9) return; |
102 | if(ch == 10) return; | 104 | if(ch == 10) return; |
103 | if(ch == 11) return; | 105 | if(ch == 11) return; |
104 | if(ch == 12) return; | 106 | if(ch == 12) return; |
105 | if(ch == 13) return; | 107 | if(ch == 13) return; |
106 | if(ch == 14) return; | 108 | if(ch == 14) return; |
107 | if(ch == 15) return; | 109 | if(ch == 15) return; |
108 | */ | 110 | */ |
109 | int a=0; | 111 | int a=0; |
110 | for(a=0; a<MAX_VOICES; a++) | 112 | for(a=0; a<MAX_VOICES; a++) |
111 | { | 113 | { |
112 | if(voices[a].ch == ch && voices[a].note == note) | 114 | if(voices[a].ch == ch && voices[a].note == note) |
113 | break; | 115 | break; |
114 | 116 | ||
115 | if(voices[a].isUsed==0) | 117 | if(voices[a].isUsed==0) |
116 | break; | 118 | break; |
117 | } | 119 | } |
118 | if(a==MAX_VOICES-1) | 120 | if(a==MAX_VOICES-1) |
119 | { | 121 | { |
120 | printf("\nOVERFLOW: Too many voices playing at once. No more left"); | 122 | printf("\nOVERFLOW: Too many voices playing at once. No more left"); |
121 | printf("\nVOICE DUMP: "); | 123 | printf("\nVOICE DUMP: "); |
122 | for(a=0; a<48; a++) | 124 | for(a=0; a<48; a++) |
123 | printf("\n#%d Ch=%d Note=%d curRate=%d curOffset=%d curPoint=%d targetOffset=%d", a, voices[a].ch, voices[a].note, voices[a].curRate, voices[a].curOffset, voices[a].curPoint, voices[a].targetOffset); | 125 | printf("\n#%d Ch=%d Note=%d curRate=%d curOffset=%d curPoint=%d targetOffset=%d", a, voices[a].ch, voices[a].note, voices[a].curRate, voices[a].curOffset, voices[a].curPoint, voices[a].targetOffset); |
124 | return; //None avaolable | 126 | return; /* None available */ |
125 | } | 127 | } |
126 | voices[a].ch=ch; | 128 | voices[a].ch=ch; |
127 | voices[a].note=note; | 129 | voices[a].note=note; |
128 | voices[a].vol=vol; | 130 | voices[a].vol=vol; |
129 | voices[a].cp=0; | 131 | voices[a].cp=0; |
130 | voices[a].state=STATE_ATTACK; | 132 | voices[a].state=STATE_ATTACK; |
131 | // voices[a].pstate=STATE_ATTACK; | 133 | voices[a].decay=255; |
132 | voices[a].decay=255; | 134 | |
133 | 135 | ||
134 | 136 | voices[a].loopState=STATE_NONLOOPING; | |
135 | voices[a].loopState=STATE_NONLOOPING; | 137 | voices[a].loopDir = LOOPDIR_FORWARD; |
136 | voices[a].loopDir = LOOPDIR_FORWARD; | 138 | /* |
137 | /* | 139 | * OKAY. Gt = Gus Table value |
138 | OKAY. Gt = Gus Table value | 140 | * rf = Root Frequency of wave |
139 | rf = Root Frequency of wave | 141 | * SR = sound sampling rate |
140 | SR = sound sampling rate | 142 | * sr = WAVE sampling rate |
141 | sr = WAVE sampling rate | 143 | */ |
142 | */ | 144 | |
143 | 145 | if(ch!=9) | |
144 | 146 | { | |
145 | /* | 147 | findDelta(&voices[a], ch, note); |
146 | unsigned int gt = gustable[note]; | 148 | /* Turn it on */ |
147 | unsigned int rf = wf->rootFreq; | 149 | voices[a].isUsed=1; |
148 | unsigned int SR = SAMPLE_RATE; | 150 | setPoint(&voices[a], 0); |
149 | unsigned int sr = wf->sampRate; | 151 | } else |
150 | voices[a].delta=((((gt<<10) / rf) * sr / SR)); | 152 | { |
151 | */ | 153 | if(drumSet[note]!=NULL) |
152 | 154 | { | |
153 | 155 | if(note<35) | |
154 | if(ch!=9) | 156 | printf("\nNOTE LESS THAN 35, AND A DRUM PATCH EXISTS FOR THIS? WHAT THE HELL?"); |
155 | { | 157 | |
156 | findDelta(&voices[a], ch, note); | 158 | struct GWaveform * wf = drumSet[note]->waveforms[0]; |
157 | //Turn it on | 159 | voices[a].wf=wf; |
158 | voices[a].isUsed=1; | 160 | voices[a].delta = (((gustable[note]<<10) / wf->rootFreq) * wf->sampRate / SAMPLE_RATE); |
159 | setPoint(&voices[a], 0); | 161 | if(wf->mode & 28) |
160 | } else | 162 | printf("\nWoah, a drum patch has a loop. Stripping the loop..."); |
161 | { | 163 | wf->mode = wf->mode & (255-28); |
162 | if(drumSet[note]!=NULL) | 164 | |
163 | { | 165 | /* Turn it on */ |
164 | if(note<35) | 166 | voices[a].isUsed=1; |
165 | printf("\nNOTE LESS THAN 35, AND A DRUM PATCH EXISTS FOR THIS? WHAT THE HELL?"); | 167 | setPoint(&voices[a], 0); |
166 | 168 | ||
167 | struct GWaveform * wf = drumSet[note]->waveforms[0]; | 169 | } else |
168 | voices[a].wf=wf; | 170 | { |
169 | voices[a].delta = (((gustable[note]<<10) / wf->rootFreq) * wf->sampRate / SAMPLE_RATE); | 171 | printf("\nWarning: drum %d does not have a patch defined... Ignoring it", note); |
170 | if(wf->mode & 28) | 172 | } |
171 | printf("\nWoah, a drum patch has a loop. Stripping the loop..."); | 173 | } |
172 | wf->mode = wf->mode & (255-28); | ||
173 | //Turn it on | ||
174 | voices[a].isUsed=1; | ||
175 | setPoint(&voices[a], 0); | ||
176 | |||
177 | } else | ||
178 | { | ||
179 | printf("\nWarning: drum %d does not have a patch defined... Ignoring it", note); | ||
180 | } | ||
181 | } | ||
182 | } | 174 | } |
183 | 175 | ||
184 | 176 | ||
185 | void releaseNote(int ch, int note) | 177 | void releaseNote(int ch, int note) |
186 | { | 178 | { |
187 | if(ch==9) // && note != 27 && note != 31 && note != 28) | 179 | if(ch==9) |
188 | return; | 180 | return; |
189 | int a=0; | 181 | |
190 | for(a=0; a<MAX_VOICES; a++) | 182 | int a=0; |
191 | { | 183 | for(a=0; a<MAX_VOICES; a++) |
192 | if(voices[a].ch == ch && voices[a].note == note) | 184 | { |
193 | { | 185 | if(voices[a].ch == ch && voices[a].note == note) |
194 | if((voices[a].wf->mode & 28)) | 186 | { |
195 | { | 187 | if((voices[a].wf->mode & 28)) |
196 | // voices[a].tmp=40; | 188 | { |
197 | // voices[a].state = STATE_RELEASE; //Ramp down | 189 | setPoint(&voices[a], 3); |
198 | 190 | } | |
199 | // voices[a].state = STATE_RAMPDOWN; //Ramp down | 191 | } |
200 | setPoint(&voices[a], 3); | 192 | } |
201 | } | ||
202 | } | ||
203 | } | ||
204 | } | 193 | } |
205 | 194 | ||
206 | void sendEvent(struct Event * ev) | 195 | void sendEvent(struct Event * ev) |
207 | { | 196 | { |
208 | // printf("\nEVENT S=%2x D1=%2x D2=%2x", ev->status, ev->d1, ev->d2); | 197 | if( ((ev->status & 0xF0) == MIDI_CONTROL) && (ev->d1 == CTRL_VOLUME) ) |
209 | 198 | { | |
210 | if( ((ev->status & 0xF0) == MIDI_CONTROL) && (ev->d1 == CTRL_VOLUME) ) | 199 | setVol((ev->status & 0xF), ev->d2); |
211 | { | 200 | return; |
212 | setVol((ev->status & 0xF), ev->d2); | 201 | } |
213 | return; | 202 | |
214 | } | 203 | if( ((ev->status & 0xF0) == MIDI_CONTROL) && (ev->d1 == CTRL_PANNING)) |
215 | 204 | { | |
216 | if( ((ev->status & 0xF0) == MIDI_CONTROL) && (ev->d1 == CTRL_PANNING)) | 205 | setPan((ev->status & 0xF), ev->d2); |
217 | { | 206 | return; |
218 | setPan((ev->status & 0xF), ev->d2); | 207 | } |
219 | return; | 208 | |
220 | } | 209 | if(((ev->status & 0xF0) == MIDI_PITCHW)) |
221 | 210 | { | |
222 | if(((ev->status & 0xF0) == MIDI_PITCHW)) | 211 | setPW((ev->status & 0xF), ev->d2); |
223 | { | 212 | return; |
224 | setPW((ev->status & 0xF), ev->d2); | 213 | } |
225 | return; | 214 | |
226 | } | 215 | if(((ev->status & 0xF0) == MIDI_NOTE_ON) && (ev->d2 != 0)) |
227 | 216 | { | |
228 | if(((ev->status & 0xF0) == MIDI_NOTE_ON) && (ev->d2 != 0)) | 217 | pressNote(ev->status & 0x0F, ev->d1, ev->d2); |
229 | { | 218 | return; |
230 | pressNote(ev->status & 0x0F, ev->d1, ev->d2); | 219 | } |
231 | return; | 220 | |
232 | } | 221 | if(((ev->status & 0xF0) == MIDI_NOTE_ON) && (ev->d2 == 0)) /* Release by vol=0 */ |
233 | 222 | { | |
234 | if(((ev->status & 0xF0) == MIDI_NOTE_ON) && (ev->d2 == 0)) //Release by vol=0 | 223 | releaseNote(ev->status & 0x0F, ev->d1); |
235 | { | 224 | return; |
236 | releaseNote(ev->status & 0x0F, ev->d1); | 225 | } |
237 | return; | 226 | |
238 | } | 227 | |
239 | 228 | if((ev->status & 0xF0) == MIDI_NOTE_OFF) | |
240 | 229 | { | |
241 | if((ev->status & 0xF0) == MIDI_NOTE_OFF) | 230 | releaseNote(ev->status & 0x0F, ev->d1); |
242 | { | 231 | return; |
243 | releaseNote(ev->status & 0x0F, ev->d1); | 232 | } |
244 | return; | 233 | |
245 | } | 234 | if((ev->status & 0xF0) == MIDI_PRGM) |
246 | 235 | { | |
247 | if((ev->status & 0xF0) == MIDI_PRGM) | 236 | if((ev->status & 0x0F) == 9) |
248 | { | 237 | printf("\nNOT PATCHING: Someone tried patching Channel 9 onto something?"); |
249 | if((ev->status & 0x0F) == 9) | 238 | else |
250 | printf("\nNOT PATCHING: Someone tried patching Channel 9 onto something?"); | 239 | setPatch(ev->status & 0x0F, ev->d1); |
251 | else | 240 | } |
252 | setPatch(ev->status & 0x0F, ev->d1); | ||
253 | } | ||
254 | } | 241 | } |
255 | 242 | ||
256 | 243 | ||
@@ -259,61 +246,60 @@ void sendEvent(struct Event * ev) | |||
259 | 246 | ||
260 | int tick(struct MIDIfile * mf) | 247 | int tick(struct MIDIfile * mf) |
261 | { | 248 | { |
262 | if(mf==NULL) | 249 | if(mf==NULL) |
263 | return 0; | 250 | return 0; |
264 | 251 | ||
265 | int a=0; | 252 | int a=0; |
266 | int tracksAdv=0; | 253 | int tracksAdv=0; |
267 | for(a=0; a<mf->numTracks; a++) | 254 | for(a=0; a<mf->numTracks; a++) |
268 | { | 255 | { |
269 | struct Track * tr = mf->tracks[a]; | 256 | struct Track * tr = mf->tracks[a]; |
270 | 257 | ||
271 | if(tr == NULL) | 258 | if(tr == NULL) |
272 | printf("\nNULL TRACK: %d", a); | 259 | printf("\nNULL TRACK: %d", a); |
273 | 260 | ||
274 | 261 | ||
275 | //BIG DEBUG STATEMENT | 262 | //BIG DEBUG STATEMENT |
276 | //printf("\nTrack %2d, Event = %4d of %4d, Delta = %5d, Next = %4d", a, tr->pos, tr->numEvents, tr->delta, getEvent(tr, tr->pos)->delta); | 263 | //printf("\nTrack %2d, Event = %4d of %4d, Delta = %5d, Next = %4d", a, tr->pos, tr->numEvents, tr->delta, getEvent(tr, tr->pos)->delta); |
277 | 264 | ||
278 | 265 | ||
279 | if(tr != NULL && (tr->pos < tr->numEvents)) | 266 | if(tr != NULL && (tr->pos < tr->numEvents)) |
280 | { | 267 | { |
281 | tr->delta++; | 268 | tr->delta++; |
282 | tracksAdv++; | 269 | tracksAdv++; |
283 | while(getEvent(tr, tr->pos)->delta <= tr->delta) | 270 | while(getEvent(tr, tr->pos)->delta <= tr->delta) |
284 | { | 271 | { |
285 | // printf("\nDelta = %d", tr->delta); | 272 | struct Event * e = getEvent(tr, tr->pos); |
286 | struct Event * e = getEvent(tr, tr->pos); | 273 | |
287 | 274 | if(e->status != 0xFF) | |
288 | if(e->status != 0xFF) | 275 | { |
289 | { | 276 | sendEvent(e); |
290 | sendEvent(e); | 277 | if(((e->status&0xF0) == MIDI_PRGM)) |
291 | if(((e->status&0xF0) == MIDI_PRGM)) | 278 | { |
292 | { | 279 | printf("\nPatch Event, patch[%d] ==> %d", e->status&0xF, e->d1); |
293 | printf("\nPatch Event, patch[%d] ==> %d", e->status&0xF, e->d1); | 280 | } |
294 | } | 281 | } |
295 | } | 282 | else |
296 | else | 283 | { |
297 | { | 284 | if(e->d1 == 0x51) |
298 | if(e->d1 == 0x51) | 285 | { |
299 | { | 286 | tempo = (((short)e->evData[0])<<16)|(((short)e->evData[1])<<8)|(e->evData[2]); |
300 | tempo = (((short)e->evData[0])<<16)|(((short)e->evData[1])<<8)|(e->evData[2]); | 287 | printf("\nMeta-Event: Tempo Set = %d", tempo); |
301 | printf("\nMeta-Event: Tempo Set = %d", tempo); | 288 | bpm=mf->div*1000000/tempo; |
302 | bpm=mf->div*1000000/tempo; | 289 | numberOfSamples=SAMPLE_RATE/bpm; |
303 | numberOfSamples=SAMPLE_RATE/bpm; | 290 | |
304 | 291 | } | |
305 | } | 292 | } |
306 | } | 293 | tr->delta = 0; |
307 | tr->delta = 0; | 294 | tr->pos++; |
308 | tr->pos++; | 295 | if(tr->pos>=(tr->numEvents-1)) |
309 | if(tr->pos>=(tr->numEvents-1)) | 296 | break; |
310 | break; | 297 | } |
311 | } | 298 | } |
312 | } | 299 | } |
313 | } | 300 | |
314 | 301 | if(tracksAdv != 0) | |
315 | if(tracksAdv != 0) | 302 | return 1; |
316 | return 1; | 303 | else |
317 | else | 304 | return 0; |
318 | return 0; | ||
319 | } | 305 | } |