forked from len0rd/rockbox
Fixed warnings, adapted to Rockbox coding style, optimized to 78% realtime.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6329 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
74e9d545ef
commit
9ec1ff8cf5
7 changed files with 1056 additions and 1115 deletions
|
@ -20,158 +20,164 @@ extern struct plugin_api * rb;
|
|||
|
||||
struct Event * getEvent(struct Track * tr, int evNum)
|
||||
{
|
||||
return tr->dataBlock + (evNum*sizeof(struct Event));
|
||||
return tr->dataBlock + (evNum*sizeof(struct Event));
|
||||
}
|
||||
|
||||
void readTextBlock(int file, char * buf)
|
||||
{
|
||||
char c = 0;
|
||||
do
|
||||
{
|
||||
c = readChar(file);
|
||||
} while(c == '\n' || c == ' ' || c=='\t');
|
||||
char c = 0;
|
||||
do
|
||||
{
|
||||
c = readChar(file);
|
||||
} while(c == '\n' || c == ' ' || c=='\t');
|
||||
|
||||
rb->lseek(file, -1, SEEK_CUR);
|
||||
int cp = 0;
|
||||
do
|
||||
{
|
||||
c = readChar(file);
|
||||
buf[cp] = c;
|
||||
cp++;
|
||||
} while (c != '\n' && c != ' ' && c != '\t' && !eof(file));
|
||||
buf[cp-1]=0;
|
||||
rb->lseek(file, -1, SEEK_CUR);
|
||||
rb->lseek(file, -1, SEEK_CUR);
|
||||
int cp = 0;
|
||||
do
|
||||
{
|
||||
c = readChar(file);
|
||||
buf[cp] = c;
|
||||
cp++;
|
||||
} while (c != '\n' && c != ' ' && c != '\t' && !eof(file));
|
||||
buf[cp-1]=0;
|
||||
rb->lseek(file, -1, SEEK_CUR);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Filename is the name of the config file
|
||||
//The MIDI file should have been loaded at this point
|
||||
/* Filename is the name of the config file */
|
||||
/* The MIDI file should have been loaded at this point */
|
||||
int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig)
|
||||
{
|
||||
char patchUsed[128];
|
||||
char drumUsed[128];
|
||||
int a=0;
|
||||
for(a=0; a<MAX_VOICES; a++)
|
||||
{
|
||||
voices[a].cp=0;
|
||||
voices[a].vol=0;
|
||||
voices[a].ch=0;
|
||||
voices[a].isUsed=0;
|
||||
voices[a].note=0;
|
||||
}
|
||||
char patchUsed[128];
|
||||
char drumUsed[128];
|
||||
int a=0;
|
||||
for(a=0; a<MAX_VOICES; a++)
|
||||
{
|
||||
voices[a].cp=0;
|
||||
voices[a].vol=0;
|
||||
voices[a].ch=0;
|
||||
voices[a].isUsed=0;
|
||||
voices[a].note=0;
|
||||
}
|
||||
|
||||
for(a=0; a<16; a++)
|
||||
{
|
||||
chVol[a]=100; //Default, not quite full blast..
|
||||
chPanLeft[a]=64; //Center
|
||||
chPanRight[a]=64; //Center
|
||||
chPat[a]=0; //Ac Gr Piano
|
||||
chPW[a]=64; // .. not .. bent ?
|
||||
}
|
||||
for(a=0; a<128; a++)
|
||||
{
|
||||
patchSet[a]=NULL;
|
||||
drumSet[a]=NULL;
|
||||
patchUsed[a]=0;
|
||||
drumUsed[a]=0;
|
||||
}
|
||||
for(a=0; a<16; a++)
|
||||
{
|
||||
chVol[a]=100; /* Default, not quite full blast.. */
|
||||
chPanLeft[a]=64; /* Center */
|
||||
chPanRight[a]=64; /* Center */
|
||||
chPat[a]=0; /* Ac Gr Piano */
|
||||
chPW[a]=64; /* .. not .. bent ? */
|
||||
}
|
||||
for(a=0; a<128; a++)
|
||||
{
|
||||
patchSet[a]=NULL;
|
||||
drumSet[a]=NULL;
|
||||
patchUsed[a]=0;
|
||||
drumUsed[a]=0;
|
||||
}
|
||||
|
||||
//Always load the piano.
|
||||
//Some files will assume its loaded without specifically
|
||||
//issuing a Patch command... then we wonder why we can't hear anything
|
||||
patchUsed[0]=1;
|
||||
/*
|
||||
* Always load the piano.
|
||||
* Some files will assume its loaded without specifically
|
||||
* issuing a Patch command... then we wonder why we can't hear anything
|
||||
*/
|
||||
patchUsed[0]=1;
|
||||
|
||||
//Scan the file to see what needs to be loaded
|
||||
for(a=0; a<mf->numTracks; a++)
|
||||
{
|
||||
int ts=0;
|
||||
/* Scan the file to see what needs to be loaded */
|
||||
for(a=0; a<mf->numTracks; a++)
|
||||
{
|
||||
unsigned int ts=0;
|
||||
|
||||
if(mf->tracks[a] == NULL)
|
||||
{
|
||||
printf("\nNULL TRACK !!!");
|
||||
rb->splash(HZ*2, true, "Null Track in loader.");
|
||||
return -1;
|
||||
}
|
||||
if(mf->tracks[a] == NULL)
|
||||
{
|
||||
printf("\nNULL TRACK !!!");
|
||||
rb->splash(HZ*2, true, "Null Track in loader.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(ts=0; ts<mf->tracks[a]->numEvents; ts++)
|
||||
{
|
||||
for(ts=0; ts<mf->tracks[a]->numEvents; ts++)
|
||||
{
|
||||
|
||||
if((getEvent(mf->tracks[a], ts)->status) == (MIDI_NOTE_ON+9))
|
||||
drumUsed[getEvent(mf->tracks[a], ts)->d1]=1;
|
||||
if((getEvent(mf->tracks[a], ts)->status) == (MIDI_NOTE_ON+9))
|
||||
drumUsed[getEvent(mf->tracks[a], ts)->d1]=1;
|
||||
|
||||
if( (getEvent(mf->tracks[a], ts)->status & 0xF0) == MIDI_PRGM)
|
||||
{
|
||||
if(patchUsed[getEvent(mf->tracks[a], ts)->d1]==0)
|
||||
printf("\nI need to load patch %d.", getEvent(mf->tracks[a], ts)->d1);
|
||||
patchUsed[getEvent(mf->tracks[a], ts)->d1]=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( (getEvent(mf->tracks[a], ts)->status & 0xF0) == MIDI_PRGM)
|
||||
{
|
||||
if(patchUsed[getEvent(mf->tracks[a], ts)->d1]==0)
|
||||
printf("\nI need to load patch %d.", getEvent(mf->tracks[a], ts)->d1);
|
||||
patchUsed[getEvent(mf->tracks[a], ts)->d1]=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int file = rb->open(filename, O_RDONLY);
|
||||
if(file == -1)
|
||||
{
|
||||
rb->splash(HZ*2, true, "Bad patch config.\nDid you install the patchset?");
|
||||
return -1;
|
||||
}
|
||||
int file = rb->open(filename, O_RDONLY);
|
||||
if(file == -1)
|
||||
{
|
||||
rb->splash(HZ*2, true, "Bad patch config.\nDid you install the patchset?");
|
||||
return -1;
|
||||
}
|
||||
|
||||
char name[40];
|
||||
char fn[40];
|
||||
char name[40];
|
||||
char fn[40];
|
||||
|
||||
//Scan our config file and load the right patches as needed
|
||||
int c = 0;
|
||||
rb->snprintf(name, 40, "");
|
||||
for(a=0; a<128; a++)
|
||||
{
|
||||
while(readChar(file)!=' ' && !eof(file));
|
||||
readTextBlock(file, name);
|
||||
/* Scan our config file and load the right patches as needed */
|
||||
int c = 0;
|
||||
rb->snprintf(name, 40, "");
|
||||
for(a=0; a<128; a++)
|
||||
{
|
||||
while(readChar(file)!=' ' && !eof(file));
|
||||
readTextBlock(file, name);
|
||||
|
||||
rb->snprintf(fn, 40, "/.rockbox/patchset/%s.pat", name);
|
||||
printf("\nLOADING: <%s> ", fn);
|
||||
rb->snprintf(fn, 40, "/.rockbox/patchset/%s.pat", name);
|
||||
printf("\nLOADING: <%s> ", fn);
|
||||
|
||||
if(patchUsed[a]==1)
|
||||
patchSet[a]=gusload(fn);
|
||||
if(patchUsed[a]==1)
|
||||
{
|
||||
patchSet[a]=gusload(fn);
|
||||
|
||||
// if(patchSet[a] == NULL)
|
||||
// return -1;
|
||||
if(patchSet[a] == NULL) /* There was an error loading it */
|
||||
return -1;
|
||||
}
|
||||
|
||||
while((c != '\n'))
|
||||
c = readChar(file);
|
||||
}
|
||||
rb->close(file);
|
||||
while((c != '\n'))
|
||||
c = readChar(file);
|
||||
}
|
||||
rb->close(file);
|
||||
|
||||
file = rb->open(drumConfig, O_RDONLY);
|
||||
if(file == -1)
|
||||
{
|
||||
rb->splash(HZ*2, true, "Bad drum config.\nDid you install the patchset?");
|
||||
return -1;
|
||||
}
|
||||
file = rb->open(drumConfig, O_RDONLY);
|
||||
if(file == -1)
|
||||
{
|
||||
rb->splash(HZ*2, true, "Bad drum config.\nDid you install the patchset?");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//Scan our config file and load the drum data
|
||||
int idx=0;
|
||||
char number[30];
|
||||
while(!eof(file))
|
||||
{
|
||||
readTextBlock(file, number);
|
||||
readTextBlock(file, name);
|
||||
rb->snprintf(fn, 40, "/.rockbox/patchset/%s.pat", name);
|
||||
/* Scan our config file and load the drum data */
|
||||
int idx=0;
|
||||
char number[30];
|
||||
while(!eof(file))
|
||||
{
|
||||
readTextBlock(file, number);
|
||||
readTextBlock(file, name);
|
||||
rb->snprintf(fn, 40, "/.rockbox/patchset/%s.pat", name);
|
||||
|
||||
idx = rb->atoi(number);
|
||||
if(idx == 0)
|
||||
break;
|
||||
idx = rb->atoi(number);
|
||||
if(idx == 0)
|
||||
break;
|
||||
|
||||
if(drumUsed[idx]==1)
|
||||
drumSet[idx]=gusload(fn);
|
||||
if(drumUsed[idx]==1)
|
||||
{
|
||||
drumSet[idx]=gusload(fn);
|
||||
|
||||
// if(drumSet[idx] == NULL)
|
||||
// return -1;
|
||||
if(drumSet[idx] == NULL) /* Error loading patch */
|
||||
return -1;
|
||||
}
|
||||
|
||||
while((c != '\n') && (c != 255) && (!eof(file)))
|
||||
c = readChar(file);
|
||||
}
|
||||
rb->close(file);
|
||||
return 0;
|
||||
while((c != '\n') && (c != 255) && (!eof(file)))
|
||||
c = readChar(file);
|
||||
}
|
||||
rb->close(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -182,7 +188,7 @@ struct GWaveform * wf IDATA_ATTR;
|
|||
int s IDATA_ATTR;
|
||||
short s1 IDATA_ATTR;
|
||||
short s2 IDATA_ATTR;
|
||||
short sample IDATA_ATTR; //For synthSample
|
||||
short sample IDATA_ATTR; /* For synthSample */
|
||||
unsigned int cpShifted IDATA_ATTR;
|
||||
|
||||
unsigned char b1 IDATA_ATTR;
|
||||
|
@ -191,31 +197,9 @@ unsigned char b2 IDATA_ATTR;
|
|||
|
||||
inline int getSample(int s)
|
||||
{
|
||||
|
||||
//16 bit samples
|
||||
if(wf->mode&1)
|
||||
{
|
||||
|
||||
if(s<<1 >= wf->wavSize)
|
||||
{
|
||||
printf("\n!!!!! %d \t %d", s<<1, wf->wavSize);
|
||||
return 0;
|
||||
}
|
||||
// signed short a = ((short *)wf->data)[s];
|
||||
|
||||
//Sign conversion moved into guspat.c
|
||||
b1=wf->data[s<<1]+((wf->mode & 2) << 6);
|
||||
b2=wf->data[(s<<1)|1]+((wf->mode & 2) << 6);
|
||||
return (b1 | (b2<<8)) ;
|
||||
|
||||
//Get rid of this sometime
|
||||
}
|
||||
else
|
||||
{ //8-bit samples
|
||||
//Do we even have anything 8-bit in our set?
|
||||
int b1=wf->data[s]+((wf->mode & 2) << 6);
|
||||
return b1<<8;
|
||||
}
|
||||
/* Sign conversion moved to guspat.c */
|
||||
/* 8bit conversion NOT YET IMPLEMENTED in guspat.c */
|
||||
return ((short *) wf->data)[s];
|
||||
}
|
||||
|
||||
|
||||
|
@ -223,190 +207,194 @@ inline int getSample(int s)
|
|||
|
||||
inline void setPoint(struct SynthObject * so, int pt)
|
||||
{
|
||||
if(so->ch==9) //Drums, no ADSR
|
||||
{
|
||||
so->curOffset = 1<<27;
|
||||
so->curRate = 1;
|
||||
return;
|
||||
}
|
||||
if(so->ch==9) /* Drums, no ADSR */
|
||||
{
|
||||
so->curOffset = 1<<27;
|
||||
so->curRate = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if(so->wf==NULL)
|
||||
{
|
||||
printf("\nCrap... null waveform...");
|
||||
exit(1);
|
||||
}
|
||||
if(so->wf->envRate==NULL)
|
||||
{
|
||||
printf("\nWaveform has no envelope set");
|
||||
exit(1);
|
||||
}
|
||||
if(so->wf==NULL)
|
||||
{
|
||||
printf("\nCrap... null waveform...");
|
||||
exit(1);
|
||||
}
|
||||
if(so->wf->envRate==NULL)
|
||||
{
|
||||
printf("\nWaveform has no envelope set");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
so->curPoint = pt;
|
||||
so->curPoint = pt;
|
||||
|
||||
int r=0;
|
||||
int rate = so->wf->envRate[pt];
|
||||
int r=0;
|
||||
int rate = so->wf->envRate[pt];
|
||||
|
||||
r=3-((rate>>6) & 0x3); // Some blatant Timidity code for rate conversion...
|
||||
r*=3;
|
||||
r = (rate & 0x3f) << r;
|
||||
r=3-((rate>>6) & 0x3); /* Some blatant Timidity code for rate conversion... */
|
||||
r*=3;
|
||||
r = (rate & 0x3f) << r;
|
||||
|
||||
/*
|
||||
Okay. This is the rate shift. Timidity defaults to 9, and sets
|
||||
it to 10 if you use the fast decay option. Slow decay sounds better
|
||||
on some files, except on some other files... you get chords that aren't
|
||||
done decaying yet.. and they dont harmonize with the next chord and it
|
||||
sounds like utter crap. Yes, even Timitidy does that. So I'm going to
|
||||
default this to 10, and maybe later have an option to set it to 9
|
||||
for longer decays.
|
||||
*/
|
||||
so->curRate = r<<10;
|
||||
/*
|
||||
* Okay. This is the rate shift. Timidity defaults to 9, and sets
|
||||
* it to 10 if you use the fast decay option. Slow decay sounds better
|
||||
* on some files, except on some other files... you get chords that aren't
|
||||
* done decaying yet.. and they dont harmonize with the next chord and it
|
||||
* sounds like utter crap. Yes, even Timitidy does that. So I'm going to
|
||||
* default this to 10, and maybe later have an option to set it to 9
|
||||
* for longer decays.
|
||||
*/
|
||||
so->curRate = r<<10;
|
||||
|
||||
//Do this here because the patches assume a 44100 sampling rate
|
||||
//We've halved our sampling rate, ergo the ADSR code will be
|
||||
//called half the time. Ergo, double the rate to keep stuff
|
||||
//sounding right.
|
||||
so->curRate = so->curRate << 1;
|
||||
/*
|
||||
* Do this here because the patches assume a 44100 sampling rate
|
||||
* We've halved our sampling rate, ergo the ADSR code will be
|
||||
* called half the time. Ergo, double the rate to keep stuff
|
||||
* sounding right.
|
||||
*/
|
||||
so->curRate = so->curRate << 1;
|
||||
|
||||
|
||||
so->targetOffset = so->wf->envOffset[pt]<<(20);
|
||||
if(pt==0)
|
||||
so->curOffset = 0;
|
||||
so->targetOffset = so->wf->envOffset[pt]<<(20);
|
||||
if(pt==0)
|
||||
so->curOffset = 0;
|
||||
}
|
||||
|
||||
|
||||
inline void stopVoice(struct SynthObject * so)
|
||||
{
|
||||
if(so->state == STATE_RAMPDOWN)
|
||||
return;
|
||||
so->state = STATE_RAMPDOWN;
|
||||
so->decay = 255;
|
||||
if(so->state == STATE_RAMPDOWN)
|
||||
return;
|
||||
so->state = STATE_RAMPDOWN;
|
||||
so->decay = 255;
|
||||
|
||||
}
|
||||
|
||||
|
||||
inline signed short int synthVoice()
|
||||
{
|
||||
so = &voices[currentVoice];
|
||||
wf = so->wf;
|
||||
so = &voices[currentVoice];
|
||||
wf = so->wf;
|
||||
|
||||
|
||||
if(so->state != STATE_RAMPDOWN)
|
||||
{
|
||||
so->cp += so->delta;
|
||||
}
|
||||
if(so->state != STATE_RAMPDOWN)
|
||||
{
|
||||
so->cp += so->delta;
|
||||
}
|
||||
|
||||
cpShifted = so->cp >> 10;
|
||||
cpShifted = so->cp >> 10;
|
||||
|
||||
if( (cpShifted >= (wf->wavSize>>1)) && (so->state != STATE_RAMPDOWN))
|
||||
stopVoice(so);
|
||||
if( (cpShifted > (wf->numSamples) && (so->state != STATE_RAMPDOWN)))
|
||||
{
|
||||
stopVoice(so);
|
||||
}
|
||||
|
||||
s2 = getSample((cpShifted)+1);
|
||||
|
||||
if((wf->mode & (LOOP_REVERSE|LOOP_PINGPONG)) && so->loopState == STATE_LOOPING && (cpShifted <= (wf->startLoop>>1)))
|
||||
{
|
||||
if(wf->mode & LOOP_REVERSE)
|
||||
{
|
||||
so->cp = (wf->endLoop)<<9;
|
||||
cpShifted = so->cp >> 10;
|
||||
s2=getSample((cpShifted));
|
||||
} else
|
||||
{
|
||||
so->delta = -so->delta;
|
||||
so->loopDir = LOOPDIR_FORWARD;
|
||||
}
|
||||
}
|
||||
/* LOOP_REVERSE|LOOP_PINGPONG = 24 */
|
||||
if((wf->mode & (24)) && so->loopState == STATE_LOOPING && (cpShifted <= (wf->startLoop)))
|
||||
{
|
||||
if(wf->mode & LOOP_REVERSE)
|
||||
{
|
||||
so->cp = (wf->endLoop)<<10;
|
||||
cpShifted = wf->endLoop;
|
||||
s2=getSample((cpShifted));
|
||||
} else
|
||||
{
|
||||
so->delta = -so->delta;
|
||||
so->loopDir = LOOPDIR_FORWARD;
|
||||
}
|
||||
}
|
||||
|
||||
if((wf->mode & 28) && (so->cp>>10 >= wf->endLoop>>1))
|
||||
{
|
||||
so->loopState = STATE_LOOPING;
|
||||
if((wf->mode & (24)) == 0)
|
||||
{
|
||||
so->cp = (wf->startLoop)<<9;
|
||||
cpShifted = so->cp >> 10;
|
||||
s2=getSample((cpShifted));
|
||||
} else
|
||||
{
|
||||
so->delta = -so->delta;
|
||||
so->loopDir = LOOPDIR_REVERSE;
|
||||
}
|
||||
}
|
||||
if((wf->mode & 28) && (cpShifted >= wf->endLoop))
|
||||
{
|
||||
so->loopState = STATE_LOOPING;
|
||||
if((wf->mode & (24)) == 0)
|
||||
{
|
||||
so->cp = (wf->startLoop)<<10;
|
||||
cpShifted = wf->startLoop;
|
||||
s2=getSample((cpShifted));
|
||||
} else
|
||||
{
|
||||
so->delta = -so->delta;
|
||||
so->loopDir = LOOPDIR_REVERSE;
|
||||
}
|
||||
}
|
||||
|
||||
//Better, working, linear interpolation
|
||||
s1=getSample((cpShifted));
|
||||
s = s1 + ((signed)((s2 - s1) * (so->cp & 1023))>>10);
|
||||
/* Better, working, linear interpolation */
|
||||
s1=getSample((cpShifted));
|
||||
s = s1 + ((signed)((s2 - s1) * (so->cp & 1023))>>10);
|
||||
|
||||
|
||||
//ADSR COMMENT WOULD GO FROM HERE.........
|
||||
/* ADSR COMMENT WOULD GO FROM HERE.........*/
|
||||
|
||||
if(so->curRate == 0)
|
||||
stopVoice(so);
|
||||
if(so->curRate == 0)
|
||||
stopVoice(so);
|
||||
|
||||
|
||||
if(so->ch != 9) //Stupid ADSR code... and don't do ADSR for drums
|
||||
{
|
||||
if(so->curOffset < so->targetOffset)
|
||||
{
|
||||
so->curOffset += (so->curRate);
|
||||
if(so -> curOffset > so->targetOffset && so->curPoint != 2)
|
||||
{
|
||||
if(so->curPoint != 5)
|
||||
setPoint(so, so->curPoint+1);
|
||||
else
|
||||
stopVoice(so);
|
||||
}
|
||||
} else
|
||||
{
|
||||
so->curOffset -= (so->curRate);
|
||||
if(so -> curOffset < so->targetOffset && so->curPoint != 2)
|
||||
{
|
||||
if(so->ch != 9) /* Stupid ADSR code... and don't do ADSR for drums */
|
||||
{
|
||||
if(so->curOffset < so->targetOffset)
|
||||
{
|
||||
so->curOffset += (so->curRate);
|
||||
if(so -> curOffset > so->targetOffset && so->curPoint != 2)
|
||||
{
|
||||
if(so->curPoint != 5)
|
||||
setPoint(so, so->curPoint+1);
|
||||
else
|
||||
stopVoice(so);
|
||||
}
|
||||
} else
|
||||
{
|
||||
so->curOffset -= (so->curRate);
|
||||
if(so -> curOffset < so->targetOffset && so->curPoint != 2)
|
||||
{
|
||||
|
||||
if(so->curPoint != 5)
|
||||
setPoint(so, so->curPoint+1);
|
||||
else
|
||||
stopVoice(so);
|
||||
if(so->curPoint != 5)
|
||||
setPoint(so, so->curPoint+1);
|
||||
else
|
||||
stopVoice(so);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(so->curOffset < 0)
|
||||
so->isUsed=0; //This is OK
|
||||
if(so->curOffset < 0)
|
||||
so->isUsed=0; /* This is OK because offset faded it out already */
|
||||
|
||||
|
||||
s = (s * (so->curOffset >> 22) >> 6);
|
||||
s = (s * (so->curOffset >> 22) >> 8);
|
||||
|
||||
// ............. TO HERE
|
||||
/* ............. TO HERE */
|
||||
|
||||
|
||||
if(so->state == STATE_RAMPDOWN)
|
||||
{
|
||||
so->decay--;
|
||||
if(so->decay == 0)
|
||||
so->isUsed=0;
|
||||
}
|
||||
if(so->state == STATE_RAMPDOWN)
|
||||
{
|
||||
so->decay--;
|
||||
if(so->decay == 0)
|
||||
so->isUsed=0;
|
||||
s = (s * so->decay) >> 8;
|
||||
}
|
||||
|
||||
s = s * so->decay; s = s >> 10;
|
||||
|
||||
return s*((signed short int)so->vol*(signed short int)chVol[so->ch])>>14;
|
||||
return s*((signed short int)so->vol*(signed short int)chVol[so->ch])>>14;
|
||||
}
|
||||
|
||||
|
||||
inline void synthSample(int * mixL, int * mixR)
|
||||
{
|
||||
// signed int leftMix=0, rightMix=0,
|
||||
*mixL = 0;
|
||||
*mixR = 0;
|
||||
for(currentVoice=0; currentVoice<MAX_VOICES; currentVoice++)
|
||||
{
|
||||
if(voices[currentVoice].isUsed==1)
|
||||
{
|
||||
sample = synthVoice(currentVoice);
|
||||
*mixL += (sample*chPanLeft[voices[currentVoice].ch])>>7;
|
||||
*mixR += (sample*chPanRight[voices[currentVoice].ch])>>7;
|
||||
}
|
||||
}
|
||||
*mixL = 0;
|
||||
*mixR = 0;
|
||||
for(currentVoice=0; currentVoice<MAX_VOICES; currentVoice++)
|
||||
{
|
||||
if(voices[currentVoice].isUsed==1)
|
||||
{
|
||||
sample = synthVoice(currentVoice);
|
||||
*mixL += (sample*chPanLeft[voices[currentVoice].ch])>>7;
|
||||
*mixR += (sample*chPanRight[voices[currentVoice].ch])>>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 intrpolation works well.
|
||||
/* TODO: Automatic Gain Control, anyone? */
|
||||
/* Or, should this be implemented on the DSP's output volume instead? */
|
||||
|
||||
return; /* No more ghetto lowpass filter.. linear intrpolation works well. */
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue