summaryrefslogtreecommitdiff
path: root/apps/plugins/midi/synth.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/midi/synth.c')
-rw-r--r--apps/plugins/midi/synth.c83
1 files changed, 42 insertions, 41 deletions
diff --git a/apps/plugins/midi/synth.c b/apps/plugins/midi/synth.c
index 42ca9ddaf6..44417b2583 100644
--- a/apps/plugins/midi/synth.c
+++ b/apps/plugins/midi/synth.c
@@ -104,8 +104,9 @@ int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig)
104 104
105 if( (getEvent(mf->tracks[a], ts)->status & 0xF0) == MIDI_PRGM) 105 if( (getEvent(mf->tracks[a], ts)->status & 0xF0) == MIDI_PRGM)
106 { 106 {
107 if(patchUsed[getEvent(mf->tracks[a], ts)->d1]==0) 107/* if(patchUsed[getEvent(mf->tracks[a], ts)->d1]==0)
108 printf("\nI need to load patch %d.", getEvent(mf->tracks[a], ts)->d1); 108 printf("\nI need to load patch %d.", getEvent(mf->tracks[a], ts)->d1);
109*/
109 patchUsed[getEvent(mf->tracks[a], ts)->d1]=1; 110 patchUsed[getEvent(mf->tracks[a], ts)->d1]=1;
110 } 111 }
111 } 112 }
@@ -124,13 +125,14 @@ int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig)
124 /* Scan our config file and load the right patches as needed */ 125 /* Scan our config file and load the right patches as needed */
125 int c = 0; 126 int c = 0;
126 rb->snprintf(name, 40, ""); 127 rb->snprintf(name, 40, "");
128 printf("\nLoading instruments");
127 for(a=0; a<128; a++) 129 for(a=0; a<128; a++)
128 { 130 {
129 while(readChar(file)!=' ' && !eof(file)); 131 while(readChar(file)!=' ' && !eof(file));
130 readTextBlock(file, name); 132 readTextBlock(file, name);
131 133
132 rb->snprintf(fn, 40, "/.rockbox/patchset/%s.pat", name); 134 rb->snprintf(fn, 40, "/.rockbox/patchset/%s.pat", name);
133 printf("\nLOADING: <%s> ", fn); 135/* printf("\nLOADING: <%s> ", fn); */
134 136
135 if(patchUsed[a]==1) 137 if(patchUsed[a]==1)
136 { 138 {
@@ -155,6 +157,7 @@ int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig)
155 /* Scan our config file and load the drum data */ 157 /* Scan our config file and load the drum data */
156 int idx=0; 158 int idx=0;
157 char number[30]; 159 char number[30];
160 printf("\nLoading drums");
158 while(!eof(file)) 161 while(!eof(file))
159 { 162 {
160 readTextBlock(file, number); 163 readTextBlock(file, number);
@@ -168,7 +171,6 @@ int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig)
168 if(drumUsed[idx]==1) 171 if(drumUsed[idx]==1)
169 { 172 {
170 drumSet[idx]=gusload(fn); 173 drumSet[idx]=gusload(fn);
171
172 if(drumSet[idx] == NULL) /* Error loading patch */ 174 if(drumSet[idx] == NULL) /* Error loading patch */
173 return -1; 175 return -1;
174 } 176 }
@@ -180,32 +182,14 @@ int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig)
180 return 0; 182 return 0;
181} 183}
182 184
183 185inline short getSample(int s,struct GWaveform * wf )
184
185int currentVoice IDATA_ATTR;
186struct SynthObject * so IDATA_ATTR;
187struct GWaveform * wf IDATA_ATTR;
188int s IDATA_ATTR;
189short s1 IDATA_ATTR;
190short s2 IDATA_ATTR;
191short sample IDATA_ATTR; /* For synthSample */
192unsigned int cpShifted IDATA_ATTR;
193
194unsigned char b1 IDATA_ATTR;
195unsigned char b2 IDATA_ATTR;
196
197
198inline int getSample(int s)
199{ 186{
200 /* Sign conversion moved to guspat.c */ 187 /* Sign conversion moved to guspat.c */
201 /* 8bit conversion NOT YET IMPLEMENTED in guspat.c */ 188 /* 8bit conversion NOT YET IMPLEMENTED in guspat.c */
202 return ((short *) wf->data)[s]; 189 return ((short *) wf->data)[s];
203} 190}
204 191
205 192void setPoint(struct SynthObject * so, int pt)
206
207
208inline void setPoint(struct SynthObject * so, int pt)
209{ 193{
210 if(so->ch==9) /* Drums, no ADSR */ 194 if(so->ch==9) /* Drums, no ADSR */
211 { 195 {
@@ -227,7 +211,7 @@ inline void setPoint(struct SynthObject * so, int pt)
227 211
228 so->curPoint = pt; 212 so->curPoint = pt;
229 213
230 int r=0; 214 int r;
231 int rate = so->wf->envRate[pt]; 215 int rate = so->wf->envRate[pt];
232 216
233 r=3-((rate>>6) & 0x3); /* Some blatant Timidity code for rate conversion... */ 217 r=3-((rate>>6) & 0x3); /* Some blatant Timidity code for rate conversion... */
@@ -243,15 +227,17 @@ inline void setPoint(struct SynthObject * so, int pt)
243 * default this to 10, and maybe later have an option to set it to 9 227 * default this to 10, and maybe later have an option to set it to 9
244 * for longer decays. 228 * for longer decays.
245 */ 229 */
246 so->curRate = r<<10; 230 so->curRate = r<<11;
247 231
248 /* 232 /*
249 * Do this here because the patches assume a 44100 sampling rate 233 * Do this here because the patches assume a 44100 sampling rate
250 * We've halved our sampling rate, ergo the ADSR code will be 234 * We've halved our sampling rate, ergo the ADSR code will be
251 * called half the time. Ergo, double the rate to keep stuff 235 * called half the time. Ergo, double the rate to keep stuff
252 * sounding right. 236 * sounding right.
237 *
238 * Or just move the 1 up one line to optimize a tiny bit.
253 */ 239 */
254 so->curRate = so->curRate << 1; 240/* so->curRate = so->curRate << 1;*/
255 241
256 242
257 so->targetOffset = so->wf->envOffset[pt]<<(20); 243 so->targetOffset = so->wf->envOffset[pt]<<(20);
@@ -270,9 +256,14 @@ inline void stopVoice(struct SynthObject * so)
270} 256}
271 257
272 258
273inline signed short int synthVoice(void) 259signed short int synthVoice(struct SynthObject * so)
274{ 260{
275 so = &voices[currentVoice]; 261 struct GWaveform * wf;
262 register int s;
263 register unsigned int cpShifted;
264 register short s1;
265 register short s2;
266
276 wf = so->wf; 267 wf = so->wf;
277 268
278 269
@@ -288,7 +279,7 @@ inline signed short int synthVoice(void)
288 stopVoice(so); 279 stopVoice(so);
289 } 280 }
290 281
291 s2 = getSample((cpShifted)+1); 282 s2 = getSample((cpShifted)+1, wf);
292 283
293 /* LOOP_REVERSE|LOOP_PINGPONG = 24 */ 284 /* LOOP_REVERSE|LOOP_PINGPONG = 24 */
294 if((wf->mode & (24)) && so->loopState == STATE_LOOPING && (cpShifted <= (wf->startLoop))) 285 if((wf->mode & (24)) && so->loopState == STATE_LOOPING && (cpShifted <= (wf->startLoop)))
@@ -297,8 +288,9 @@ inline signed short int synthVoice(void)
297 { 288 {
298 so->cp = (wf->endLoop)<<10; //Was 10 289 so->cp = (wf->endLoop)<<10; //Was 10
299 cpShifted = wf->endLoop; 290 cpShifted = wf->endLoop;
300 s2=getSample((cpShifted)); 291 s2=getSample((cpShifted), wf);
301 } else 292 }
293 else
302 { 294 {
303 so->delta = -so->delta; 295 so->delta = -so->delta;
304 so->loopDir = LOOPDIR_FORWARD; 296 so->loopDir = LOOPDIR_FORWARD;
@@ -312,8 +304,9 @@ inline signed short int synthVoice(void)
312 { 304 {
313 so->cp = (wf->startLoop)<<10; //Was 10 305 so->cp = (wf->startLoop)<<10; //Was 10
314 cpShifted = wf->startLoop; 306 cpShifted = wf->startLoop;
315 s2=getSample((cpShifted)); 307 s2=getSample((cpShifted), wf);
316 } else 308 }
309 else
317 { 310 {
318 so->delta = -so->delta; 311 so->delta = -so->delta;
319 so->loopDir = LOOPDIR_REVERSE; 312 so->loopDir = LOOPDIR_REVERSE;
@@ -321,7 +314,7 @@ inline signed short int synthVoice(void)
321 } 314 }
322 315
323 /* Better, working, linear interpolation */ 316 /* Better, working, linear interpolation */
324 s1=getSample((cpShifted)); //\|/ Was 1023)) >> 10 317 s1=getSample((cpShifted), wf); //\|/ Was 1023)) >> 10
325 s = s1 + ((signed)((s2 - s1) * (so->cp & 1023))>>10); //Was 10 318 s = s1 + ((signed)((s2 - s1) * (so->cp & 1023))>>10); //Was 10
326 319
327 320
@@ -381,18 +374,26 @@ inline signed short int synthVoice(void)
381 374
382inline void synthSample(int * mixL, int * mixR) 375inline void synthSample(int * mixL, int * mixR)
383{ 376{
384 *mixL = 0; 377 register int dL=0;
385 *mixR = 0; 378 register int dR=0;
386 for(currentVoice=0; currentVoice<MAX_VOICES; currentVoice++) 379 register short sample=0;
380 register struct SynthObject *voicept=voices;
381 struct SynthObject *lastvoice=&voices[MAX_VOICES];
382
383 while(voicept!=lastvoice)
387 { 384 {
388 if(voices[currentVoice].isUsed==1) 385 if(voicept->isUsed==1)
389 { 386 {
390 sample = synthVoice(); 387 sample = synthVoice(voicept);
391 *mixL += (sample*chPanLeft[voices[currentVoice].ch])>>7; 388 dL += (sample*chPanLeft[voicept->ch])>>7;
392 *mixR += (sample*chPanRight[voices[currentVoice].ch])>>7; 389 dR += (sample*chPanRight[voicept->ch])>>7;
393 } 390 }
391 voicept++;
394 } 392 }
395 393
394 *mixL=dL;
395 *mixR=dR;
396
396 /* TODO: Automatic Gain Control, anyone? */ 397 /* TODO: Automatic Gain Control, anyone? */
397 /* Or, should this be implemented on the DSP's output volume instead? */ 398 /* Or, should this be implemented on the DSP's output volume instead? */
398 399