diff options
Diffstat (limited to 'apps/plugins/midi/synth.c')
-rw-r--r-- | apps/plugins/midi/synth.c | 83 |
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 | 185 | inline short getSample(int s,struct GWaveform * wf ) | |
184 | |||
185 | int currentVoice IDATA_ATTR; | ||
186 | struct SynthObject * so IDATA_ATTR; | ||
187 | struct GWaveform * wf IDATA_ATTR; | ||
188 | int s IDATA_ATTR; | ||
189 | short s1 IDATA_ATTR; | ||
190 | short s2 IDATA_ATTR; | ||
191 | short sample IDATA_ATTR; /* For synthSample */ | ||
192 | unsigned int cpShifted IDATA_ATTR; | ||
193 | |||
194 | unsigned char b1 IDATA_ATTR; | ||
195 | unsigned char b2 IDATA_ATTR; | ||
196 | |||
197 | |||
198 | inline 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 | 192 | void setPoint(struct SynthObject * so, int pt) | |
206 | |||
207 | |||
208 | inline 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 | ||
273 | inline signed short int synthVoice(void) | 259 | signed 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 | ||
382 | inline void synthSample(int * mixL, int * mixR) | 375 | inline 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 | ||