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
This commit is contained in:
Nils Wallménius 2007-10-08 19:28:41 +00:00
parent d712e252fe
commit f619f81676
3 changed files with 64 additions and 76 deletions

View file

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

View file

@ -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. */
}

View file

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