summaryrefslogtreecommitdiff
path: root/apps/plugins/midi/sequencer.c
diff options
context:
space:
mode:
authorStepan Moskovchenko <stevenm@rockbox.org>2006-05-03 19:32:22 +0000
committerStepan Moskovchenko <stevenm@rockbox.org>2006-05-03 19:32:22 +0000
commit28b5afd05a075cce1f46e5cc85c7e2caae3fc6ee (patch)
treed7285c0d7afb20145a0a9918b17827ed59a1cc9b /apps/plugins/midi/sequencer.c
parent7f1d21480127c9246d2aa7a329f74fd8754b1e42 (diff)
downloadrockbox-28b5afd05a075cce1f46e5cc85c7e2caae3fc6ee.tar.gz
rockbox-28b5afd05a075cce1f46e5cc85c7e2caae3fc6ee.zip
Optimize synth code by pre-computing the volume scaling for each note.
Scaling is now calculated once per MIDI event at the most, instead of once per sample. Increase voice ramping speed, increase number of active voices a little. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9870 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/midi/sequencer.c')
-rw-r--r--apps/plugins/midi/sequencer.c47
1 files changed, 25 insertions, 22 deletions
diff --git a/apps/plugins/midi/sequencer.c b/apps/plugins/midi/sequencer.c
index b6fb592294..ebd5b76405 100644
--- a/apps/plugins/midi/sequencer.c
+++ b/apps/plugins/midi/sequencer.c
@@ -16,6 +16,7 @@
16 * 16 *
17 ****************************************************************************/ 17 ****************************************************************************/
18 18
19void setVolScale(int a);
19 20
20extern struct plugin_api * rb; 21extern struct plugin_api * rb;
21 22
@@ -24,8 +25,14 @@ long tempo=375000;
24 25
25inline void setVol(int ch, int vol) 26inline void setVol(int ch, int vol)
26{ 27{
27// printf("\nvolume[%d] %d ==> %d", ch, chVol[ch], vol); 28 int a=0;
28 chVol[ch]=vol; 29 chVol[ch]=vol;
30
31 /* If channel volume changes, we need to recalculate the volume scale */
32 /* factor for all voices active on this channel */
33 for(a=0; a<MAX_VOICES; a++)
34 if(voices[a].ch == ch)
35 setVolScale(a);
29} 36}
30 37
31inline void setPan(int ch, int pan) 38inline void setPan(int ch, int pan)
@@ -111,25 +118,13 @@ long pitchTbl[] ICONST_ATTR={
111 72901,72934,72967,72999,73032,73065,73098,73131,73164,73197,73230,73264, 118 72901,72934,72967,72999,73032,73065,73098,73131,73164,73197,73230,73264,
112 73297,73330,73363,73396,73429,73462,73495,73528 119 73297,73330,73363,73396,73429,73462,73495,73528
113}; 120};
114/*
115void findDelta(struct SynthObject * so, int ch, int note)
116{
117
118 struct GWaveform * wf = patchSet[chPat[ch]]->waveforms[patchSet[chPat[ch]]->noteTable[note]];
119 so->wf=wf; // \|/ was 10
120 so->delta = (((gustable[note]<<10) / (wf->rootFreq)) * wf->sampRate / (SAMPLE_RATE));
121 so->delta = (so->delta * pitchTbl[chPW[ch]])>> 16;
122}
123*/
124
125 121
126void findDelta(struct SynthObject * so, int ch, int note) 122void findDelta(struct SynthObject * so, int ch, int note)
127{ 123{
128 124
129 struct GWaveform * wf = patchSet[chPat[ch]]->waveforms[patchSet[chPat[ch]]->noteTable[note]]; 125 struct GWaveform * wf = patchSet[chPat[ch]]->waveforms[patchSet[chPat[ch]]->noteTable[note]];
130 so->wf=wf; // \|/ was 10 126 so->wf=wf;
131 127 unsigned long delta= 0; /* More percision- extra bit - not so off-key as before */
132 unsigned long delta= 0 ;
133 128
134 delta = (((gustable[note]<<FRACTSIZE) / (wf->rootFreq)) * wf->sampRate / (SAMPLE_RATE)); 129 delta = (((gustable[note]<<FRACTSIZE) / (wf->rootFreq)) * wf->sampRate / (SAMPLE_RATE));
135 delta = (delta * pitchTbl[chPW[ch]])>> 16; 130 delta = (delta * pitchTbl[chPW[ch]])>> 16;
@@ -139,7 +134,6 @@ void findDelta(struct SynthObject * so, int ch, int note)
139 134
140inline void setPW(int ch, int msb, int lsb) 135inline void setPW(int ch, int msb, int lsb)
141{ 136{
142// printf("\npitchw[%d] %d ==> %d", ch, chPW[ch], msb);
143 chPW[ch] = msb<<2|lsb>>5; 137 chPW[ch] = msb<<2|lsb>>5;
144 138
145 int a=0; 139 int a=0;
@@ -152,16 +146,26 @@ inline void setPW(int ch, int msb, int lsb)
152 } 146 }
153} 147}
154 148
149
150/* Sets the volume scaling by channel volume and note volume */
151/* This way we can do the multiplication/indexing once per */
152/* MIDI event at the most, instead of once per sample. */
153void setVolScale(int a)
154{
155 struct SynthObject * so = &voices[a];
156 so->volscale = ((signed short int)so->vol*(signed short int)chVol[so->ch]);
157}
158
155void pressNote(int ch, int note, int vol) 159void pressNote(int ch, int note, int vol)
156{ 160{
157 static int lastKill = 0; 161 static int lastKill = 0;
158//Silences all channels but one, for easy debugging, for me. 162/* Silences all channels but one, for easy debugging, for me. */
159/* 163/*
160 if(ch == 0) return; 164 if(ch == 0) return;
161 if(ch == 1) return; 165 if(ch == 1) return;
162 if(ch == 2) return; 166 if(ch == 2) return;
163 if(ch == 3) return; 167 if(ch == 3) return;
164// if(ch == 4) return; 168 if(ch == 4) return;
165 if(ch == 5) return; 169 if(ch == 5) return;
166 if(ch == 6) return; 170 if(ch == 6) return;
167 if(ch == 7) return; 171 if(ch == 7) return;
@@ -203,6 +207,7 @@ void pressNote(int ch, int note, int vol)
203 voices[a].state=STATE_ATTACK; 207 voices[a].state=STATE_ATTACK;
204 voices[a].decay=255; 208 voices[a].decay=255;
205 209
210 setVolScale(a);
206 211
207 voices[a].loopState=STATE_NONLOOPING; 212 voices[a].loopState=STATE_NONLOOPING;
208 voices[a].loopDir = LOOPDIR_FORWARD; 213 voices[a].loopDir = LOOPDIR_FORWARD;
@@ -304,9 +309,7 @@ void sendEvent(struct Event * ev)
304 309
305 if((ev->status & 0xF0) == MIDI_PRGM) 310 if((ev->status & 0xF0) == MIDI_PRGM)
306 { 311 {
307 if((ev->status & 0x0F) == 9) 312 if((ev->status & 0x0F) != 9)
308 printf("\nNOT PATCHING: Someone tried patching Channel 9 onto something?");
309 else
310 setPatch(ev->status & 0x0F, ev->d1); 313 setPatch(ev->status & 0x0F, ev->d1);
311 } 314 }
312} 315}
@@ -351,7 +354,7 @@ int tick(void)
351 if(e->d1 == 0x51) 354 if(e->d1 == 0x51)
352 { 355 {
353 tempo = (((short)e->evData[0])<<16)|(((short)e->evData[1])<<8)|(e->evData[2]); 356 tempo = (((short)e->evData[0])<<16)|(((short)e->evData[1])<<8)|(e->evData[2]);
354 printf("\nMeta-Event: Tempo Set = %d", tempo); 357/* printf("\nMeta-Event: Tempo Set = %d", tempo); */
355 bpm=mf->div*1000000/tempo; 358 bpm=mf->div*1000000/tempo;
356 numberOfSamples=SAMPLE_RATE/bpm; 359 numberOfSamples=SAMPLE_RATE/bpm;
357 360