diff options
Diffstat (limited to 'apps/plugins/midi/synth.c')
-rw-r--r-- | apps/plugins/midi/synth.c | 41 |
1 files changed, 16 insertions, 25 deletions
diff --git a/apps/plugins/midi/synth.c b/apps/plugins/midi/synth.c index e95dd7cec9..f199d544e5 100644 --- a/apps/plugins/midi/synth.c +++ b/apps/plugins/midi/synth.c | |||
@@ -300,7 +300,8 @@ static inline void synthVoice(struct SynthObject * so, int32_t * out, unsigned i | |||
300 | s1 = so->decay; | 300 | s1 = so->decay; |
301 | s2 = s1 * pan; | 301 | s2 = s1 * pan; |
302 | s1 = (s1 << 7) -s2; | 302 | s1 = (s1 << 7) -s2; |
303 | *(out++) += ((s1 << 9) & 0xFFFF0000) | ((s2 >> 7) &0xFFFF); | 303 | *(out++) += s1; |
304 | *(out++) += s2; | ||
304 | continue; | 305 | continue; |
305 | } | 306 | } |
306 | } else /* OK to advance voice */ | 307 | } else /* OK to advance voice */ |
@@ -431,7 +432,8 @@ static inline void synthVoice(struct SynthObject * so, int32_t * out, unsigned i | |||
431 | 432 | ||
432 | s2 = s1 * pan; | 433 | s2 = s1 * pan; |
433 | s1 = (s1 << 7) - s2; | 434 | s1 = (s1 << 7) - s2; |
434 | *(out++) += ((s1 << 9) & 0xFFFF0000) | ((s2 >> 7) &0xFFFF); | 435 | *(out++) += s1; |
436 | *(out++) += s2; | ||
435 | } | 437 | } |
436 | 438 | ||
437 | /* store these again */ | 439 | /* store these again */ |
@@ -441,40 +443,29 @@ static inline void synthVoice(struct SynthObject * so, int32_t * out, unsigned i | |||
441 | return; | 443 | return; |
442 | } | 444 | } |
443 | 445 | ||
444 | /* buffer to hold all the samples for the current tick, this is a hack | ||
445 | neccesary for coldfire targets as pcm_play_data uses the dma which cannot | ||
446 | access iram */ | ||
447 | int32_t samp_buf[512] IBSS_ATTR; | ||
448 | |||
449 | /* synth num_samples samples and write them to the */ | 446 | /* synth num_samples samples and write them to the */ |
450 | /* buffer pointed to by buf_ptr */ | 447 | /* buffer pointed to by buf_ptr */ |
451 | void synthSamples(int32_t *buf_ptr, unsigned int num_samples) ICODE_ATTR; | 448 | size_t synthSamples(int32_t *buf_ptr, size_t num_samples) ICODE_ATTR; |
452 | void synthSamples(int32_t *buf_ptr, unsigned int num_samples) | 449 | size_t synthSamples(int32_t *buf_ptr, size_t num_samples) |
453 | { | 450 | { |
454 | if (UNLIKELY(num_samples > 512)) | 451 | unsigned int i; |
455 | DEBUGF("num_samples is too big!\n"); | 452 | struct SynthObject *voicept; |
456 | else | 453 | size_t nsamples = MIN(num_samples, MAX_SAMPLES); |
457 | { | ||
458 | int i; | ||
459 | struct SynthObject *voicept; | ||
460 | 454 | ||
461 | rb->memset(samp_buf, 0, num_samples*4); | 455 | rb->memset(buf_ptr, 0, nsamples * 2 * sizeof(int32_t)); |
462 | 456 | ||
463 | for(i=0; i < MAX_VOICES; i++) | 457 | for(i=0; i < MAX_VOICES; i++) |
458 | { | ||
459 | voicept=&voices[i]; | ||
460 | if(voicept->isUsed) | ||
464 | { | 461 | { |
465 | voicept=&voices[i]; | 462 | synthVoice(voicept, buf_ptr, nsamples); |
466 | if(voicept->isUsed) | ||
467 | { | ||
468 | synthVoice(voicept, samp_buf, num_samples); | ||
469 | } | ||
470 | } | 463 | } |
471 | |||
472 | rb->memcpy(buf_ptr, samp_buf, num_samples*4); | ||
473 | } | 464 | } |
474 | 465 | ||
475 | /* TODO: Automatic Gain Control, anyone? */ | 466 | /* TODO: Automatic Gain Control, anyone? */ |
476 | /* Or, should this be implemented on the DSP's output volume instead? */ | 467 | /* Or, should this be implemented on the DSP's output volume instead? */ |
477 | 468 | ||
478 | return; /* No more ghetto lowpass filter. Linear interpolation works well. */ | 469 | return nsamples; /* No more ghetto lowpass filter. Linear interpolation works well. */ |
479 | } | 470 | } |
480 | 471 | ||