summaryrefslogtreecommitdiff
path: root/apps/plugins/midi/synth.c
diff options
context:
space:
mode:
authorSolomon Peachy <pizza@shaftnet.org>2019-08-04 16:58:20 -0400
committerSolomon Peachy <pizza@shaftnet.org>2019-08-05 20:48:40 +0200
commited724fecb15d90d8075ed1edb963f455cb91b0a1 (patch)
tree6b72250278e5170bc7ed4b8263f48eb8e8dc1c61 /apps/plugins/midi/synth.c
parenteea5bfc9aec35686406296641b37bcc2c731fbbb (diff)
downloadrockbox-ed724fecb15d90d8075ed1edb963f455cb91b0a1.tar.gz
rockbox-ed724fecb15d90d8075ed1edb963f455cb91b0a1.zip
Midiplay plugin ehancements
- Improved robustness - Improved sound quality - Use mixer and DSP Patch by Igor Poretsky Change-Id: I6fa617158cbaa53ae842295cdbdbe3a478e49ded
Diffstat (limited to 'apps/plugins/midi/synth.c')
-rw-r--r--apps/plugins/midi/synth.c41
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 */
447int32_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 */
451void synthSamples(int32_t *buf_ptr, unsigned int num_samples) ICODE_ATTR; 448size_t synthSamples(int32_t *buf_ptr, size_t num_samples) ICODE_ATTR;
452void synthSamples(int32_t *buf_ptr, unsigned int num_samples) 449size_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