diff options
| author | Nils Wallménius <nils@rockbox.org> | 2007-10-08 19:28:41 +0000 |
|---|---|---|
| committer | Nils Wallménius <nils@rockbox.org> | 2007-10-08 19:28:41 +0000 |
| commit | f619f8167646632d6eab10f529638eebbdda6af6 (patch) | |
| tree | 119a1f4051d59808a25612421f613cb09ee1e9d5 /apps/plugins/midi | |
| parent | d712e252fecf814a48814034a55ba60a1b194598 (diff) | |
| download | rockbox-f619f8167646632d6eab10f529638eebbdda6af6.zip rockbox-f619f8167646632d6eab10f529638eebbdda6af6.tar.gz rockbox-f619f8167646632d6eab10f529638eebbdda6af6.tar.bz2 rockbox-f619f8167646632d6eab10f529638eebbdda6af6.tar.xz | |
Change loop structure for sample synthesizing. Gives a nice speedup on both coldfire and arm targets.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15036 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/midi')
| -rw-r--r-- | apps/plugins/midi/midiplay.c | 39 | ||||
| -rw-r--r-- | apps/plugins/midi/synth.c | 46 | ||||
| -rw-r--r-- | apps/plugins/midi/synth.h | 55 |
3 files changed, 64 insertions, 76 deletions
diff --git a/apps/plugins/midi/midiplay.c b/apps/plugins/midi/midiplay.c index c557433..99f0571 100644 --- a/apps/plugins/midi/midiplay.c +++ b/apps/plugins/midi/midiplay.c @@ -148,32 +148,31 @@ bool lastswap=1; static inline void synthbuf(void) { - int32_t *outptr; - register int i; - int currentSample=0; - int synthtemp[2]; + int32_t *outptr; + int i; #ifndef SYNC - if(lastswap==swap) return; - lastswap=swap; + if(lastswap==swap) return; + lastswap=swap; - outptr=(swap ? gmbuf : gmbuf+BUF_SIZE); + outptr=(swap ? gmbuf : gmbuf+BUF_SIZE); #else - outptr=gmbuf; + outptr=gmbuf; #endif - for(i=0; i<BUF_SIZE; i++) - { - synthSample(&synthtemp[0], &synthtemp[1]); - currentSample++; - *outptr=((synthtemp[0]&0xFFFF) << 16) | (synthtemp[1]&0xFFFF); - outptr++; - if(currentSample==numberOfSamples) - { - if( tick() == 0 ) quit=1; - currentSample=0; - } - } + for(i=0; i<BUF_SIZE/numberOfSamples; i++) + { + synthSamples((int32_t*)outptr, numberOfSamples); + outptr += numberOfSamples; + if( tick() == 0 ) + quit=1; + } + + if(BUF_SIZE%numberOfSamples) + { + synthSamples((int32_t*)outptr, BUF_SIZE%numberOfSamples); + outptr += BUF_SIZE%numberOfSamples; + } } void get_more(unsigned char** start, size_t* size) diff --git a/apps/plugins/midi/synth.c b/apps/plugins/midi/synth.c index 327f32e..568c7bb 100644 --- a/apps/plugins/midi/synth.c +++ b/apps/plugins/midi/synth.c @@ -255,8 +255,7 @@ inline void stopVoice(struct SynthObject * so) so->decay = 0; } -int synthVoice(struct SynthObject * so) ICODE_ATTR; -int synthVoice(struct SynthObject * so) +static inline int synthVoice(struct SynthObject * so) { struct GWaveform * wf; register int s; @@ -404,3 +403,46 @@ int synthVoice(struct SynthObject * so) return s*so->volscale>>14; } +/* synth num_samples samples and write them to the */ +/* buffer pointed to by buf_ptr */ +void synthSamples(int32_t *buf_ptr, unsigned int num_samples) ICODE_ATTR; +void synthSamples(int32_t *buf_ptr, unsigned int num_samples) +{ + int i; + register int dL; + register int dR; + register int sample; + register struct SynthObject *voicept; + while(num_samples>0) + { + dL=0; + dR=0; + voicept=&voices[0]; + + for(i=MAX_VOICES; i > 0; i--) + { + if(voicept->isUsed==1) + { + sample = synthVoice(voicept); + dL += sample; + sample *= chPan[voicept->ch]; + dR += sample; + } + voicept++; + } + + dL = (dL << 7) - dR; + + /* combine the left and right 16 bit samples into 32 bits and write */ + /* to the buffer, left sample in the high word and right in the low word */ + *buf_ptr=(((dL&0x7FFF80) << 9) | ((dR&0x7FFF80) >> 7)); + + buf_ptr++; + num_samples--; + } + /* TODO: Automatic Gain Control, anyone? */ + /* Or, should this be implemented on the DSP's output volume instead? */ + + return; /* No more ghetto lowpass filter. Linear interpolation works well. */ +} + diff --git a/apps/plugins/midi/synth.h b/apps/plugins/midi/synth.h index e04f9f4..5f9edf8 100644 --- a/apps/plugins/midi/synth.h +++ b/apps/plugins/midi/synth.h @@ -17,61 +17,8 @@ * ****************************************************************************/ int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig); -int synthVoice(struct SynthObject * so); void setPoint(struct SynthObject * so, int pt); - -static inline void synthSample(int * mixL, int * mixR) -{ - int i; - register int dL=0; - register int dR=0; - register int sample = 0; - register struct SynthObject *voicept=voices; - - for(i=MAX_VOICES/2; i > 0; i--) - { - if(voicept->isUsed==1) - { - sample = synthVoice(voicept); - dL += sample; - sample *= chPan[voicept->ch]; - dR += sample; - } - voicept++; - if(voicept->isUsed==1) - { - sample = synthVoice(voicept); - dL += sample; - sample *= chPan[voicept->ch]; - dR += sample; - } - voicept++; - } - -/* if MAX_VOICES is not even we do this to get the last voice */ -#if MAX_VOICES%2 - if (MAX_VOICES%2) - { - if(voicept->isUsed==1) - { - sample = synthVoice(voicept); - dL += sample; - sample *= chPan[voicept->ch]; - dR += sample; - } - } -#endif - - dL = (dL << 7) - dR; - - *mixL=dL >> 7; - *mixR=dR >> 7; - - /* TODO: Automatic Gain Control, anyone? */ - /* Or, should this be implemented on the DSP's output volume instead? */ - - return; /* No more ghetto lowpass filter. Linear interpolation works well. */ -} +void synthSamples(int32_t *buf_ptr, unsigned int num_samples); static inline struct Event * getEvent(struct Track * tr, int evNum) { |