blob: 34478e4d4fe51ec838dd76bf981318bcf40c1e55 [file] [log] [blame]
Stepan Moskovchenko215e4922005-04-15 06:08:55 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
Nils Wallménius0e496052007-09-24 15:57:32 +00008 * $Id$
Stepan Moskovchenko215e4922005-04-15 06:08:55 +00009 *
10 * Copyright (C) 2005 Stepan Moskovchenko
11 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000012 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
Stepan Moskovchenko215e4922005-04-15 06:08:55 +000016 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
Nils Wallménius0e496052007-09-24 15:57:32 +000021#include "plugin.h"
22#include "midiutil.h"
23#include "guspat.h"
Nils Wallménius6888db32007-09-27 20:17:38 +000024#include "synth.h"
Stepan Moskovchenko215e4922005-04-15 06:08:55 +000025
Stepan Moskovchenko215e4922005-04-15 06:08:55 +000026extern struct plugin_api * rb;
Stepan Moskovchenkocd963d82007-11-03 04:09:38 +000027extern int playingTime IBSS_ATTR;
28extern int samplesThisSecond IBSS_ATTR;
Stepan Moskovchenko215e4922005-04-15 06:08:55 +000029
30long tempo=375000;
31
Stepan Moskovchenkoc3584c02007-10-17 05:06:57 +000032/* From the old patch config.... each patch is scaled.
33 * Should be moved into patchset.cfg
34 * But everyone would need a new config file.
35 *
36 * While this really does need to go into the patch config,
37 * I doubt anyone has made their own custom rockbox patchset
38 * (if you have, please send a copy my way :) )
39 */
40static const unsigned char patchScale[]=
41{
42 125,115,115,100,100,80,115,100,100,100,100,80,100,100,100,100,
43 100,100,100,100,60,100,100,100,150,155,145,100,125,86,125,85,
44 161,160,133,160,135,133,100,128,150,100,100,150,100,130,100,200,
45 100,100,125,125,100,100,100,100,124,110,111,100,139,113,115,115,
46 125,115,95,140,100,100,105,100,90,100,80,80,100,125,100,80,
47 100,100,100,250,130,100,100,100,115,100,100,120,200,100,100,80,
48 130,100,100,150,100,100,100,100,100,100,200,100,100,100,100,100,
49 100,100,113,100,200,100,100,100,30,100,100,100,100,100,100,100
50};
51
Nils Wallménius6386dbe2007-09-30 11:21:25 +000052/* Sets the volume scaling by channel volume and note volume */
53/* This way we can do the multiplication/indexing once per */
54/* MIDI event at the most, instead of once per sample. */
55static inline void setVolScale(int a)
56{
57 struct SynthObject * so = &voices[a];
Stepan Moskovchenkoc3584c02007-10-17 05:06:57 +000058 int ch = so->ch;
59
60 so->volscale = so->vol * chVol[ch]*patchScale[chPat[ch]] / 100;
61 //((signed short int)so->vol*(signed short int)chVol[ch])*patchScale[chPat[ch]];
Nils Wallménius6386dbe2007-09-30 11:21:25 +000062}
63
64static inline void setVol(int ch, int vol)
Stepan Moskovchenko215e4922005-04-15 06:08:55 +000065{
Stepan Moskovchenko28b5afd2006-05-03 19:32:22 +000066 int a=0;
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +000067 chVol[ch]=vol;
Stepan Moskovchenko28b5afd2006-05-03 19:32:22 +000068
69 /* If channel volume changes, we need to recalculate the volume scale */
70 /* factor for all voices active on this channel */
71 for(a=0; a<MAX_VOICES; a++)
72 if(voices[a].ch == ch)
73 setVolScale(a);
Stepan Moskovchenko215e4922005-04-15 06:08:55 +000074}
75
Nils Wallménius6386dbe2007-09-30 11:21:25 +000076static inline void setPatch(int ch, int pat)
Stepan Moskovchenko215e4922005-04-15 06:08:55 +000077{
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +000078 chPat[ch]=pat;
Stepan Moskovchenko215e4922005-04-15 06:08:55 +000079}
80
81
Stepan Moskovchenkob2f1b5d2006-05-01 23:22:59 +000082
Stepan Moskovchenko1515ff82007-10-15 05:11:37 +000083/*
Stepan Moskovchenkod33645b2007-10-17 03:48:24 +000084 This is the new pitch bend table. There are 512 entries.
85 The middle entry is exactly 65536 - no bending.
86
87 The range of the table is one semitone /in either direction/
88 Ie, one semitone from the center.
89
90 Bends beyond this can be achieved by first offsetting the index
91 into the GUS frequency table by the appropriate number of semitones,
92 and then using this table to bend the rest of the way.
93
94 Generated using Matlab code:
Stepan Moskovchenko1515ff82007-10-15 05:11:37 +000095 for i=0:512, fprintf('%d,', round(2^16*2^((i-256)/1536))); end
96*/
97
Nils Wallméniusddee0f12007-09-24 21:13:20 +000098const uint32_t pitchTbl[] ICONST_ATTR={
Stepan Moskovchenko1515ff82007-10-15 05:11:37 +000099 61858,61872,61886,61900,61914,61928,61942,61956,61970,61983,61997,62011,
100 62025,62039,62053,62067,62081,62095,62109,62124,62138,62152,62166,62180,
101 62194,62208,62222,62236,62250,62264,62278,62292,62306,62320,62334,62348,
102 62362,62376,62390,62404,62419,62433,62447,62461,62475,62489,62503,62517,
103 62531,62545,62560,62574,62588,62602,62616,62630,62644,62658,62673,62687,
104 62701,62715,62729,62743,62757,62772,62786,62800,62814,62828,62843,62857,
105 62871,62885,62899,62913,62928,62942,62956,62970,62984,62999,63013,63027,
106 63041,63056,63070,63084,63098,63112,63127,63141,63155,63169,63184,63198,
107 63212,63227,63241,63255,63269,63284,63298,63312,63326,63341,63355,63369,
108 63384,63398,63412,63427,63441,63455,63470,63484,63498,63512,63527,63541,
109 63555,63570,63584,63599,63613,63627,63642,63656,63670,63685,63699,63713,
110 63728,63742,63757,63771,63785,63800,63814,63829,63843,63857,63872,63886,
111 63901,63915,63929,63944,63958,63973,63987,64002,64016,64030,64045,64059,
112 64074,64088,64103,64117,64132,64146,64161,64175,64190,64204,64219,64233,
113 64248,64262,64277,64291,64306,64320,64335,64349,64364,64378,64393,64407,
114 64422,64436,64451,64465,64480,64494,64509,64524,64538,64553,64567,64582,
115 64596,64611,64626,64640,64655,64669,64684,64699,64713,64728,64742,64757,
116 64772,64786,64801,64815,64830,64845,64859,64874,64889,64903,64918,64933,
117 64947,64962,64976,64991,65006,65020,65035,65050,65065,65079,65094,65109,
118 65123,65138,65153,65167,65182,65197,65211,65226,65241,65256,65270,65285,
119 65300,65315,65329,65344,65359,65374,65388,65403,65418,65433,65447,65462,
120 65477,65492,65506,65521,65536,65551,65566,65580,65595,65610,65625,65640,
121 65654,65669,65684,65699,65714,65729,65743,65758,65773,65788,65803,65818,
122 65832,65847,65862,65877,65892,65907,65922,65936,65951,65966,65981,65996,
123 66011,66026,66041,66056,66071,66085,66100,66115,66130,66145,66160,66175,
124 66190,66205,66220,66235,66250,66265,66280,66294,66309,66324,66339,66354,
125 66369,66384,66399,66414,66429,66444,66459,66474,66489,66504,66519,66534,
126 66549,66564,66579,66594,66609,66624,66639,66654,66670,66685,66700,66715,
127 66730,66745,66760,66775,66790,66805,66820,66835,66850,66865,66880,66896,
128 66911,66926,66941,66956,66971,66986,67001,67016,67032,67047,67062,67077,
129 67092,67107,67122,67137,67153,67168,67183,67198,67213,67228,67244,67259,
130 67274,67289,67304,67320,67335,67350,67365,67380,67395,67411,67426,67441,
131 67456,67472,67487,67502,67517,67532,67548,67563,67578,67593,67609,67624,
132 67639,67655,67670,67685,67700,67716,67731,67746,67761,67777,67792,67807,
133 67823,67838,67853,67869,67884,67899,67915,67930,67945,67961,67976,67991,
134 68007,68022,68037,68053,68068,68083,68099,68114,68129,68145,68160,68176,
135 68191,68206,68222,68237,68252,68268,68283,68299,68314,68330,68345,68360,
136 68376,68391,68407,68422,68438,68453,68468,68484,68499,68515,68530,68546,
137 68561,68577,68592,68608,68623,68639,68654,68670,68685,68701,68716,68732,
138 68747,68763,68778,68794,68809,68825,68840,68856,68871,68887,68902,68918,
139 68933,68949,68965,68980,68996,69011,69027,69042,69058,69074,69089,69105,
140 69120,69136,69152,69167,69183,69198,69214,69230,69245,69261,69276,69292,
141 69308,69323,69339,69355,69370,69386,69402,69417,69433
Stepan Moskovchenko1515ff82007-10-15 05:11:37 +0000142};
143
Stepan Moskovchenko47efba82006-05-03 05:18:18 +0000144
Nils Wallménius6386dbe2007-09-30 11:21:25 +0000145static void findDelta(struct SynthObject * so, int ch, int note)
Stepan Moskovchenko47efba82006-05-03 05:18:18 +0000146{
Stepan Moskovchenko47efba82006-05-03 05:18:18 +0000147 struct GWaveform * wf = patchSet[chPat[ch]]->waveforms[patchSet[chPat[ch]]->noteTable[note]];
Stepan Moskovchenko28b5afd2006-05-03 19:32:22 +0000148 so->wf=wf;
Stepan Moskovchenko47efba82006-05-03 05:18:18 +0000149
Stepan Moskovchenko7f1fbe42007-11-17 06:39:02 +0000150 /* Used to be unsigned int, but math had to be done in different order to avoid overflow */
151 unsigned long long delta= 0;
152
153/*
154 Old formula:
155 delta = (((gustable[note+chPBNoteOffset[ch]]<<FRACTSIZE) / (wf->rootFreq)) * wf->sampRate / (SAMPLE_RATE));
156
157 Plus some pitch stuff. See old SVN for how it used to be
158*/
159
160 delta = (((gustable[note+chPBNoteOffset[ch]]))); /* anywhere from 8000 to 8000000 */
161 delta = delta * wf->sampRate; /* approx 20000 - 44000 but can vary with tuning */
162 delta = (delta * chPBFractBend[ch]); /* approx 60000 - 70000 */
163 delta = delta / (SAMPLE_RATE); /* 44100 or 22050 */
164 delta = delta / (wf->rootFreq); /* anywhere from 8000 to 8000000 */
165
166 /* Pitch bend is encoded as a fractional of 16 bits, hence the 16 */
167 delta = delta >> (16 - FRACTSIZE); /* a shift of approx 4 bits */
Stepan Moskovchenko47efba82006-05-03 05:18:18 +0000168 so->delta = delta;
169}
Stepan Moskovchenko215e4922005-04-15 06:08:55 +0000170
Stepan Moskovchenkobdfe87c2007-11-05 05:35:10 +0000171static inline void computeDeltas(int ch)
172{
173 int a=0;
174 for(a = 0; a<MAX_VOICES; a++)
175 {
Nils Wallménius0fd4c2e2007-11-11 01:02:45 +0000176 if(voices[a].isUsed && voices[a].ch == ch)
Stepan Moskovchenkobdfe87c2007-11-05 05:35:10 +0000177 {
178 findDelta(&voices[a], ch, voices[a].note);
179 }
180 }
181}
182
Nils Wallménius6386dbe2007-09-30 11:21:25 +0000183static inline void setPW(int ch, int msb, int lsb)
Stepan Moskovchenko215e4922005-04-15 06:08:55 +0000184{
Stepan Moskovchenkofb3e9a42005-08-07 22:20:40 +0000185 chPW[ch] = msb<<2|lsb>>5;
Stepan Moskovchenko215e4922005-04-15 06:08:55 +0000186
Stepan Moskovchenkod33645b2007-10-17 03:48:24 +0000187 int totalBend = (chPW[ch]-256) * chPBDepth[ch];
188 chPBNoteOffset[ch] = totalBend >> 8;
189 chPBFractBend[ch] = pitchTbl[(totalBend & 0xFF) + 256];
190
Stepan Moskovchenkobdfe87c2007-11-05 05:35:10 +0000191 computeDeltas(ch);
Stepan Moskovchenko215e4922005-04-15 06:08:55 +0000192}
193
Nils Wallméniuscb9ba112007-10-04 10:30:01 +0000194inline void pressNote(int ch, int note, int vol)
Stepan Moskovchenko215e4922005-04-15 06:08:55 +0000195{
Stepan Moskovchenkob2f1b5d2006-05-01 23:22:59 +0000196 static int lastKill = 0;
Stepan Moskovchenko28b5afd2006-05-03 19:32:22 +0000197/* Silences all channels but one, for easy debugging, for me. */
Stepan Moskovchenko1f5fb992005-04-19 15:57:07 +0000198/*
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +0000199 if(ch == 0) return;
200 if(ch == 1) return;
201 if(ch == 2) return;
202 if(ch == 3) return;
Stepan Moskovchenko28b5afd2006-05-03 19:32:22 +0000203 if(ch == 4) return;
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +0000204 if(ch == 5) return;
205 if(ch == 6) return;
206 if(ch == 7) return;
207 if(ch == 8) return;
208 if(ch == 9) return;
209 if(ch == 10) return;
210 if(ch == 11) return;
211 if(ch == 12) return;
212 if(ch == 13) return;
213 if(ch == 14) return;
214 if(ch == 15) return;
Stepan Moskovchenko1f5fb992005-04-19 15:57:07 +0000215*/
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +0000216 int a=0;
217 for(a=0; a<MAX_VOICES; a++)
218 {
219 if(voices[a].ch == ch && voices[a].note == note)
220 break;
Stepan Moskovchenko1f5fb992005-04-19 15:57:07 +0000221
Nils Wallménius0fd4c2e2007-11-11 01:02:45 +0000222 if(!voices[a].isUsed)
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +0000223 break;
224 }
Stepan Moskovchenko65ef67e2007-01-10 17:53:54 +0000225 if(a==MAX_VOICES)
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +0000226 {
Stepan Moskovchenkob2f1b5d2006-05-01 23:22:59 +0000227// printf("\nVoice kill");
228// printf("\nToo many voices playing at once. No more left");
229// printf("\nVOICE DUMP: ");
230// for(a=0; a<48; a++)
231// 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);
232 lastKill++;
233 if(lastKill == MAX_VOICES)
234 lastKill = 0;
235 a = lastKill;
236// return; /* None available */
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +0000237 }
238 voices[a].ch=ch;
239 voices[a].note=note;
240 voices[a].vol=vol;
241 voices[a].cp=0;
242 voices[a].state=STATE_ATTACK;
243 voices[a].decay=255;
Stepan Moskovchenko215e4922005-04-15 06:08:55 +0000244
Stepan Moskovchenko28b5afd2006-05-03 19:32:22 +0000245 setVolScale(a);
Stepan Moskovchenko215e4922005-04-15 06:08:55 +0000246
Nils Wallménius65331f12007-11-15 21:20:29 +0000247 voices[a].loopState=STATE_NONLOOPING;
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +0000248 /*
249 * OKAY. Gt = Gus Table value
250 * rf = Root Frequency of wave
251 * SR = sound sampling rate
252 * sr = WAVE sampling rate
253 */
Stepan Moskovchenko215e4922005-04-15 06:08:55 +0000254
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +0000255 if(ch!=9)
256 {
257 findDelta(&voices[a], ch, note);
258 /* Turn it on */
Nils Wallménius0fd4c2e2007-11-11 01:02:45 +0000259 voices[a].isUsed=true;
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +0000260 setPoint(&voices[a], 0);
261 } else
262 {
263 if(drumSet[note]!=NULL)
264 {
Stepan Moskovchenkocd963d82007-11-03 04:09:38 +0000265 if(note<35)
Jens Arnoldb1f00492007-04-21 05:35:17 +0000266 printf("NOTE LESS THAN 35, AND A DRUM PATCH EXISTS FOR THIS? WHAT THE HELL?");
Stepan Moskovchenko215e4922005-04-15 06:08:55 +0000267
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +0000268 struct GWaveform * wf = drumSet[note]->waveforms[0];
269 voices[a].wf=wf;
Stepan Moskovchenko7f1fbe42007-11-17 06:39:02 +0000270 voices[a].delta = (((gustable[note]<<FRACTSIZE) / wf->rootFreq) * wf->sampRate / SAMPLE_RATE);
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +0000271 if(wf->mode & 28)
Stepan Moskovchenkob2f1b5d2006-05-01 23:22:59 +0000272// printf("\nWoah, a drum patch has a loop. Stripping the loop...");
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +0000273 wf->mode = wf->mode & (255-28);
Stepan Moskovchenko215e4922005-04-15 06:08:55 +0000274
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +0000275 /* Turn it on */
Nils Wallménius0fd4c2e2007-11-11 01:02:45 +0000276 voices[a].isUsed=true;
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +0000277 setPoint(&voices[a], 0);
Stepan Moskovchenko215e4922005-04-15 06:08:55 +0000278
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +0000279 } else
280 {
Stepan Moskovchenkob2f1b5d2006-05-01 23:22:59 +0000281/* printf("\nWarning: drum %d does not have a patch defined... Ignoring it", note); */
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +0000282 }
283 }
Stepan Moskovchenko215e4922005-04-15 06:08:55 +0000284}
Stepan Moskovchenko215e4922005-04-15 06:08:55 +0000285
Nils Wallménius6386dbe2007-09-30 11:21:25 +0000286static void releaseNote(int ch, int note)
Stepan Moskovchenko215e4922005-04-15 06:08:55 +0000287{
Stepan Moskovchenkoc84461f2006-10-03 21:09:47 +0000288
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +0000289 if(ch==9)
290 return;
Stepan Moskovchenko215e4922005-04-15 06:08:55 +0000291
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +0000292 int a=0;
293 for(a=0; a<MAX_VOICES; a++)
294 {
295 if(voices[a].ch == ch && voices[a].note == note)
296 {
297 if((voices[a].wf->mode & 28))
298 {
299 setPoint(&voices[a], 3);
300 }
301 }
302 }
Stepan Moskovchenko215e4922005-04-15 06:08:55 +0000303}
304
Nils Wallménius93787dd2007-09-27 18:29:50 +0000305static void sendEvent(struct Event * ev)
Stepan Moskovchenko215e4922005-04-15 06:08:55 +0000306{
Nils Wallménius93787dd2007-09-27 18:29:50 +0000307 const unsigned char status_low = ev->status & 0x0F;
308 const unsigned char d1 = ev->d1;
309 const unsigned char d2 = ev->d2;
310 switch(ev->status & 0xF0)
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +0000311 {
Nils Wallménius93787dd2007-09-27 18:29:50 +0000312 case MIDI_CONTROL:
313 switch(d1)
314 {
315 case CTRL_VOLUME:
316 {
317 setVol((status_low), d2);
318 return;
319 }
320 case CTRL_PANNING:
321 {
Nils Wallméniuse1940b82007-10-04 19:36:42 +0000322 chPan[status_low]=d2;
Nils Wallménius93787dd2007-09-27 18:29:50 +0000323 return;
324 }
Stepan Moskovchenko47d83232007-10-21 19:47:33 +0000325 case CTRL_DATAENT_MSB:
Stepan Moskovchenko1515ff82007-10-15 05:11:37 +0000326 {
327 /* TODO: Update all deltas. Is this really needed? */
Stepan Moskovchenko47d83232007-10-21 19:47:33 +0000328 if(chLastCtrlMSB[status_low] == REG_PITCHBEND_MSB &&
329 chLastCtrlLSB[status_low] == REG_PITCHBEND_LSB)
330 {
331// printf("Pitch bend depth set to %d\n", d2);
332 chPBDepth[status_low] = d2;
333 }
334 return;
335 }
336
337 case CTRL_NONREG_LSB:
338 {
339 chLastCtrlLSB[status_low] = 0xFF; /* Ignore nonregistered writes */
340 return;
341 }
342
343 case CTRL_NONREG_MSB:
344 {
345 chLastCtrlMSB[status_low] = 0xFF; /* Ignore nonregistered writes */
346 return;
347 }
348
349 case CTRL_REG_LSB:
350 {
351 chLastCtrlLSB[status_low] = d2;
352 return;
353 }
354
355 case CTRL_REG_MSB:
356 {
357 chLastCtrlMSB[status_low] = d2;
Stepan Moskovchenko1515ff82007-10-15 05:11:37 +0000358 return;
359 }
360
Nils Wallménius93787dd2007-09-27 18:29:50 +0000361 }
362 break;
Stepan Moskovchenko215e4922005-04-15 06:08:55 +0000363
Nils Wallménius93787dd2007-09-27 18:29:50 +0000364 case MIDI_PITCHW:
365 setPW((status_low), d2, d1);
366 return;
Stepan Moskovchenko215e4922005-04-15 06:08:55 +0000367
Nils Wallménius93787dd2007-09-27 18:29:50 +0000368 case MIDI_NOTE_ON:
369 switch(d2)
370 {
371 case 0: /* Release by vol=0 */
372 releaseNote(status_low, d1);
373 return;
Stepan Moskovchenko1515ff82007-10-15 05:11:37 +0000374
Nils Wallménius93787dd2007-09-27 18:29:50 +0000375 default:
376 pressNote(status_low, d1, d2);
377 return;
378 }
Stepan Moskovchenko215e4922005-04-15 06:08:55 +0000379
Nils Wallménius93787dd2007-09-27 18:29:50 +0000380 case MIDI_NOTE_OFF:
381 releaseNote(status_low, d1);
382 return;
Stepan Moskovchenko215e4922005-04-15 06:08:55 +0000383
Nils Wallménius93787dd2007-09-27 18:29:50 +0000384 case MIDI_PRGM:
385 if((status_low) != 9)
386 setPatch(status_low, d1);
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +0000387 }
Stepan Moskovchenko215e4922005-04-15 06:08:55 +0000388}
389
Stéphane Doyon775279b2007-11-03 04:59:24 +0000390void rewindFile(void)
Stepan Moskovchenkocd963d82007-11-03 04:09:38 +0000391{
392 int i=0;
393 for(i=0; i<mf->numTracks; i++)
394 {
395 mf->tracks[i]->delta = 0;
396 mf->tracks[i]->pos = 0;
397 }
398}
399
Stepan Moskovchenkobdfe87c2007-11-05 05:35:10 +0000400
Nils Wallménius6888db32007-09-27 20:17:38 +0000401int tick(void) ICODE_ATTR;
Stepan Moskovchenkobdfe87c2007-11-05 05:35:10 +0000402
403void seekBackward(int nsec)
404{
405 int notesUsed = 0, a=0;
406 int desiredTime = playingTime - nsec; /* Rewind 5 sec */
407
408 if(desiredTime < 0)
409 desiredTime = 0;
410
411 /* Set controllers to default values */
412 resetControllers();
413
414 /* Set the tempo to defalt */
415 bpm=mf->div*1000000/tempo;
416 numberOfSamples=SAMPLE_RATE/bpm;
417
418
419 /* Reset the tracks to start */
420 rewindFile();
421
422 /* Reset the time counter to 0 */
423 playingTime = 0;
424 samplesThisSecond = 0;
425
426 /* Quickly run through any initial things that occur before notes */
427 do
428 {
429 notesUsed = 0;
430 for(a=0; a<MAX_VOICES; a++)
Nils Wallménius0fd4c2e2007-11-11 01:02:45 +0000431 if(voices[a].isUsed)
Stepan Moskovchenkobdfe87c2007-11-05 05:35:10 +0000432 notesUsed++;
433 tick();
434 } while(notesUsed == 0);
435
436 /* Reset the time counter to 0 */
437 playingTime = 0;
438 samplesThisSecond = 0;
439
440 /* Tick until goal is reached */
441 while(playingTime < desiredTime)
442 tick();
443}
444
445
446void seekForward(int nsec)
447{
448 int desiredTime = playingTime + nsec;
449 while(tick() && playingTime < desiredTime);
450}
451
Stepan Moskovchenkob2f1b5d2006-05-01 23:22:59 +0000452int tick(void)
Stepan Moskovchenko215e4922005-04-15 06:08:55 +0000453{
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +0000454 if(mf==NULL)
455 return 0;
Stepan Moskovchenko215e4922005-04-15 06:08:55 +0000456
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +0000457 int a=0;
458 int tracksAdv=0;
459 for(a=0; a<mf->numTracks; a++)
460 {
461 struct Track * tr = mf->tracks[a];
Stepan Moskovchenko215e4922005-04-15 06:08:55 +0000462
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +0000463 if(tr == NULL)
Jens Arnoldb1f00492007-04-21 05:35:17 +0000464 printf("NULL TRACK: %d", a);
Stepan Moskovchenko215e4922005-04-15 06:08:55 +0000465
466
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +0000467 //BIG DEBUG STATEMENT
468 //printf("\nTrack %2d, Event = %4d of %4d, Delta = %5d, Next = %4d", a, tr->pos, tr->numEvents, tr->delta, getEvent(tr, tr->pos)->delta);
Stepan Moskovchenko215e4922005-04-15 06:08:55 +0000469
470
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +0000471 if(tr != NULL && (tr->pos < tr->numEvents))
472 {
473 tr->delta++;
474 tracksAdv++;
475 while(getEvent(tr, tr->pos)->delta <= tr->delta)
476 {
477 struct Event * e = getEvent(tr, tr->pos);
Stepan Moskovchenko215e4922005-04-15 06:08:55 +0000478
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +0000479 if(e->status != 0xFF)
480 {
481 sendEvent(e);
482 if(((e->status&0xF0) == MIDI_PRGM))
483 {
Stepan Moskovchenkob2f1b5d2006-05-01 23:22:59 +0000484/* printf("\nPatch Event, patch[%d] ==> %d", e->status&0xF, e->d1); */
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +0000485 }
486 }
487 else
488 {
489 if(e->d1 == 0x51)
490 {
491 tempo = (((short)e->evData[0])<<16)|(((short)e->evData[1])<<8)|(e->evData[2]);
Stepan Moskovchenko28b5afd2006-05-03 19:32:22 +0000492/* printf("\nMeta-Event: Tempo Set = %d", tempo); */
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +0000493 bpm=mf->div*1000000/tempo;
494 numberOfSamples=SAMPLE_RATE/bpm;
Stepan Moskovchenko1f5fb992005-04-19 15:57:07 +0000495
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +0000496 }
497 }
498 tr->delta = 0;
499 tr->pos++;
500 if(tr->pos>=(tr->numEvents-1))
501 break;
502 }
503 }
504 }
Stepan Moskovchenko215e4922005-04-15 06:08:55 +0000505
Stepan Moskovchenkocd963d82007-11-03 04:09:38 +0000506 samplesThisSecond += numberOfSamples;
507
508 while(samplesThisSecond >= SAMPLE_RATE)
509 {
510 samplesThisSecond -= SAMPLE_RATE;
511 playingTime++;
512// printf("Time: %d sec\n", playingTime);
513 }
514
Stepan Moskovchenko9ec1ff82005-04-20 21:07:13 +0000515 if(tracksAdv != 0)
516 return 1;
517 else
518 return 0;
Stepan Moskovchenko215e4922005-04-15 06:08:55 +0000519}
Nils Wallménius0e496052007-09-24 15:57:32 +0000520