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
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 @@
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 @@
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 @@
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)
{