1
0
Fork 0
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:
Stepan Moskovchenko 2005-04-20 21:07:13 +00:00
parent 74e9d545ef
commit 9ec1ff8cf5
7 changed files with 1056 additions and 1115 deletions

View file

@ -67,9 +67,12 @@ struct GWaveform * loadWaveform(int file)
wav->data=readData(file, wav->wavSize);
wav->numSamples = wav->wavSize / 2;
int a=0;
wav->startLoop = wav->startLoop >> 1;
wav->endLoop = wav->endLoop >> 1;
unsigned int a=0;
return wav;
/* half baked 8 bit conversion UNFINISHED*/
/*
if(wav->mode & 1 == 0) //Whoops, 8 bit
{
wav->numSamples = wav->wavSize;
@ -81,7 +84,7 @@ struct GWaveform * loadWaveform(int file)
for(a=0; a<1000; a++)
printf("\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
printf("\n!!!!!!!!!!!!!!!!!!!!!!!!!!!");
for(a=wav->wavSize-1; a>0; a-=2)
@ -91,39 +94,26 @@ struct GWaveform * loadWaveform(int file)
// int b1=wf->data[s]+((wf->mode & 2) << 6);
// return b1<<8;
}
*/
/*
//#if !defined(SIMULATOR)
for(a=0; a<wav->wavSize; a+=2)
/* Iriver needs byteswapping.. big endian, go figure. Gus files are little endian */
#if !defined(SIMULATOR)
for(a=0; a<wav->numSamples; a++)
{
unsigned char tmp;
tmp = wav->data[2*a];
wav->data[2*a] = wav->data[2*a+1];
wav->data[2*a+1] = tmp;
((unsigned short *) wav->data)[a] = SWAB16(((unsigned short *) wav->data)[a]);
}
//#endif
#endif
/* Convert unsigned to signed by subtracting 32768 */
if(wav->mode & 2)
{
for(a=0; a<wav->wavSize/2; a++)
{
((short *) wav->data)[a] = ((short *) wav->data)[a] - 32767;
}
}
*/
for(a=0; a<wav->numSamples; a++)
((short *) wav->data)[a] = ((unsigned short *) wav->data)[a] - 32768;
//If we have a 16 bit waveform
/* if(wav->mode & 1 && (wav->mode & 2))
{
for(a=0; a<wav->wavSize; a+=2) //Convert it to
{
wav->data[a]=wav->data[a]+(1 << 7);
wav->data[a|1]=wav->data[(a)|1]+(1 << 7);
}
}
*/
return wav;
}
@ -131,8 +121,9 @@ struct GWaveform * loadWaveform(int file)
int selectWaveform(struct GPatch * pat, int midiNote)
{
int tabFreq = gustable[midiNote]/100; //Comparison
int a=0;
/* We divide by 100 here because everyone's freq formula is slightly different */
unsigned int tabFreq = gustable[midiNote]/100; /* Comparison */
unsigned int a=0;
for(a=0; a<pat->numWaveforms; a++)
{
if(pat->waveforms[a]->lowFreq/100 <= tabFreq &&
@ -166,7 +157,7 @@ struct GPatch * gusload(char * filename)
gp->inst=readChar(file);
gp->voc=readChar(file);
gp->chan=readChar(file);
gp->numWaveforms=readWord(file); //readWord(file);
gp->numWaveforms=readWord(file);
gp->vol=readWord(file);
gp->datSize=readDWord(file);
gp->res=readData(file, 36);
@ -184,19 +175,7 @@ struct GPatch * gusload(char * filename)
gp->numWaves=readChar(file);
gp->layerRes=readData(file,40);
/* printf("\n%s\n%s\n%s", gp->header, gp->gravisid, gp->desc);
printf("\nInst = %d", gp->inst);
printf("\nVoc = %d", gp->voc);
printf("\nChan = %d", gp->chan);
printf("\nWav = %d", gp->numWaveforms);
printf("\nVol = %d", gp->vol);
printf("\nSize = %d", gp->datSize);
printf("\n\ninstrID = %d", gp->instrID);
printf("\ninstrName = %s", gp->instrName);
// printf("\ninstrSize = %d", gp->instrSize);
// printf("\nlayers = %d", gp->layers);
*/
printf("\nFILE: %s", filename);
printf("\nlayerSamples=%d", gp->numWaves);

View file

@ -16,7 +16,7 @@
*
****************************************************************************/
//This came from one of the Gravis documents
/* This came from one of the Gravis documents */
static const unsigned int gustable[]=
{
8175, 8661, 9177, 9722, 10300, 10913, 11562, 12249, 12978, 13750, 14567, 15433,

View file

@ -29,7 +29,7 @@ struct MIDIfile * loadFile(char * filename)
struct MIDIfile * mf;
int file = rb->open (filename, O_RDONLY);
if(file==0)
if(file==-1)
{
bail("Could not open file\n");
}
@ -69,8 +69,6 @@ struct MIDIfile * loadFile(char * filename)
printf("\nnumTracks=%d div=%d\nBegin reading track data\n", mf->numTracks, mf->div);
// return;
while(! eof(file) && track < mf->numTracks)
{
@ -107,21 +105,21 @@ struct MIDIfile * loadFile(char * filename)
int rStatus = 0;
//Returns 0 if done, 1 if keep going
/* Returns 0 if done, 1 if keep going */
int readEvent(int file, void * dest)
{
struct Event dummy;
struct Event * ev = (struct Event *) dest;
if(ev == NULL)
ev = &dummy; //If we are just counting events instead of loading them
ev = &dummy; /* If we are just counting events instead of loading them */
ev->delta = readVarData(file);
int t=readChar(file);
if((t&0x80) == 0x80) //if not a running status event
if((t&0x80) == 0x80) /* if not a running status event */
{
ev->status = t;
if(t == 0xFF)
@ -129,7 +127,7 @@ int readEvent(int file, void * dest)
ev->d1 = readChar(file);
ev->len = readVarData(file);
//Allocate and read in the data block
/* Allocate and read in the data block */
if(dest != NULL)
{
ev->evData = readData(file, ev->len);
@ -137,19 +135,20 @@ int readEvent(int file, void * dest)
}
else
{
//Don't allocate anything, just see how much it would tale
//To make memory usage efficient
int a=0;
/*
* Don't allocate anything, just see how much it would tale
* To make memory usage efficient
*/
unsigned int a=0;
for(a=0; a<ev->len; a++)
readChar(file); //Skip skip
}
if(ev->d1 == 0x2F)
{
return 0; //Termination meta-event
return 0; /* Termination meta-event */
}
} else //If part of a running status event
} else /* If part of a running status event */
{
rStatus = t;
ev->status = t;
@ -161,7 +160,7 @@ int readEvent(int file, void * dest)
} else
ev->d2 = 127;
}
} else //Running Status
} else /* Running Status */
{
ev->status = rStatus;
ev->d1 = t;
@ -189,9 +188,9 @@ struct Track * readTrack(int file)
int pos = rb->lseek(file, 0, SEEK_CUR);
while(readEvent(file, NULL)) //Memory saving technique
numEvents++; //Attempt to read in events, count how many
//THEN allocate memory and read them in
while(readEvent(file, NULL)) /* Memory saving technique */
numEvents++; /* Attempt to read in events, count how many */
/* THEN allocate memory and read them in */
rb->lseek(file, pos, SEEK_SET);
int trackSize = (numEvents+1) * sizeof(struct Event);
@ -252,7 +251,7 @@ int readTwoBytes(int file)
return data;
}
//This came from the MIDI file format guide
/* This came from the MIDI file format guide */
int readVarData(int file)
{
unsigned int value;
@ -270,8 +269,6 @@ int readVarData(int file)
/*
//This function should not be needed because we
//can just release the whole memory buffer at once
void unloadFile(struct MIDIfile * mf)
{
if(mf == NULL)

View file

@ -63,27 +63,17 @@
extern struct plugin_api * rb;
int chVol[16] IDATA_ATTR; //Channel volume
int chPanLeft[16] IDATA_ATTR; //Channel panning
int chVol[16] IDATA_ATTR; /* Channel volume */
int chPanLeft[16] IDATA_ATTR; /* Channel panning */
int chPanRight[16] IDATA_ATTR;
int chPat[16]; //Channel patch
int chPW[16]; //Channel pitch wheel, MSB only
int chPat[16]; /* Channel patch */
int chPW[16]; /* Channel pitch wheel, MSB only */
/*
unsigned char chVol[16]; //Channel volume
unsigned char chPanLeft[16]; //Channel panning
unsigned char chPanRight[16];
unsigned char chPat[16]; //Channel patch
unsigned char chPW[16]; //Channel pitch wheel, MSB only
*/
struct GPatch * gusload(char *);
struct GPatch * patchSet[128];
struct GPatch * drumSet[128];
//char myarray[80] IDATA_ATTR;
struct Event
{
unsigned int delta;
@ -96,8 +86,8 @@ struct Track
{
unsigned int size;
unsigned int numEvents;
unsigned int delta; //For sequencing
unsigned int pos; //For sequencing
unsigned int delta; /* For sequencing */
unsigned int pos; /* For sequencing */
void * dataBlock;
};
@ -105,18 +95,16 @@ struct Track
struct MIDIfile
{
int Length;
//int Format; //We don't really care what type it is
unsigned short numTracks;
unsigned short div; //Time division, X ticks per millisecond
unsigned short div; /* Time division, X ticks per millisecond */
struct Track * tracks[48];
unsigned char patches[128];
int numPatches;
};
/*
struct SynthObject
{
// int tmp;
struct GWaveform * wf;
unsigned int delta;
unsigned int decay;
@ -127,13 +115,13 @@ struct SynthObject
unsigned int curPoint;
};
*/
struct SynthObject
{
// int tmp;
struct GWaveform * wf;
int delta;
int decay;
int cp;
unsigned int cp;
int state, loopState, loopDir;
int note, vol, ch, isUsed;
int curRate, curOffset, targetOffset;
@ -183,7 +171,7 @@ void *alloc(int size)
}
//Rick's code
/* Rick's code */
/*
void *alloc(int size)
{
@ -242,5 +230,5 @@ void printf(char *fmt, ...) {fmt=fmt; }
void exit(int code)
{
code = code; //Stub function, kill warning for now
code = code; /* Stub function, kill warning for now */
}

View file

@ -44,10 +44,10 @@ void setPatch(int ch, int pat)
/*
Pitch Bend table, Computed by
for i=0:127, fprintf('%d,', round(2^16*2^((i-64)/384))); end
(When typed into Matlab)
16 bit pitch bend table
* Pitch Bend table, Computed by
* for i=0:127, fprintf('%d,', round(2^16*2^((i-64)/384))); end
* (When typed into Matlab)
* 16 bit pitch bend table
*/
long pitchTbl[]=
{
@ -67,8 +67,8 @@ void findDelta(struct SynthObject * so, int ch, int note)
struct GWaveform * wf = patchSet[chPat[ch]]->waveforms[patchSet[chPat[ch]]->noteTable[note]];
so->wf=wf;
so->delta = (((gustable[note]<<10) / wf->rootFreq) * wf->sampRate / SAMPLE_RATE);
so->delta = so->delta * pitchTbl[chPW[ch]] >> 16;
so->delta = (((gustable[note]<<10) / (wf->rootFreq)) * wf->sampRate / (SAMPLE_RATE));
so->delta = (so->delta * pitchTbl[chPW[ch]])>> 16;
}
void setPW(int ch, int msb)
@ -88,12 +88,14 @@ void setPW(int ch, int msb)
void pressNote(int ch, int note, int vol)
{
//Silences all channels but one, for easy debugging, for me.
/*
if(ch == 0) return;
// if(ch == 1) return;
if(ch == 1) return;
if(ch == 2) return;
if(ch == 3) return;
if(ch == 4) return;
// if(ch == 4) return;
if(ch == 5) return;
if(ch == 6) return;
if(ch == 7) return;
@ -121,40 +123,29 @@ void pressNote(int ch, int note, int vol)
printf("\nVOICE DUMP: ");
for(a=0; a<48; a++)
printf("\n#%d Ch=%d Note=%d curRate=%d curOffset=%d curPoint=%d targetOffset=%d", a, voices[a].ch, voices[a].note, voices[a].curRate, voices[a].curOffset, voices[a].curPoint, voices[a].targetOffset);
return; //None avaolable
return; /* None available */
}
voices[a].ch=ch;
voices[a].note=note;
voices[a].vol=vol;
voices[a].cp=0;
voices[a].state=STATE_ATTACK;
// voices[a].pstate=STATE_ATTACK;
voices[a].decay=255;
voices[a].loopState=STATE_NONLOOPING;
voices[a].loopDir = LOOPDIR_FORWARD;
/*
OKAY. Gt = Gus Table value
rf = Root Frequency of wave
SR = sound sampling rate
sr = WAVE sampling rate
* OKAY. Gt = Gus Table value
* rf = Root Frequency of wave
* SR = sound sampling rate
* sr = WAVE sampling rate
*/
/*
unsigned int gt = gustable[note];
unsigned int rf = wf->rootFreq;
unsigned int SR = SAMPLE_RATE;
unsigned int sr = wf->sampRate;
voices[a].delta=((((gt<<10) / rf) * sr / SR));
*/
if(ch!=9)
{
findDelta(&voices[a], ch, note);
//Turn it on
/* Turn it on */
voices[a].isUsed=1;
setPoint(&voices[a], 0);
} else
@ -170,7 +161,8 @@ void pressNote(int ch, int note, int vol)
if(wf->mode & 28)
printf("\nWoah, a drum patch has a loop. Stripping the loop...");
wf->mode = wf->mode & (255-28);
//Turn it on
/* Turn it on */
voices[a].isUsed=1;
setPoint(&voices[a], 0);
@ -184,8 +176,9 @@ void pressNote(int ch, int note, int vol)
void releaseNote(int ch, int note)
{
if(ch==9) // && note != 27 && note != 31 && note != 28)
if(ch==9)
return;
int a=0;
for(a=0; a<MAX_VOICES; a++)
{
@ -193,10 +186,6 @@ void releaseNote(int ch, int note)
{
if((voices[a].wf->mode & 28))
{
// voices[a].tmp=40;
// voices[a].state = STATE_RELEASE; //Ramp down
// voices[a].state = STATE_RAMPDOWN; //Ramp down
setPoint(&voices[a], 3);
}
}
@ -205,8 +194,6 @@ void releaseNote(int ch, int note)
void sendEvent(struct Event * ev)
{
// printf("\nEVENT S=%2x D1=%2x D2=%2x", ev->status, ev->d1, ev->d2);
if( ((ev->status & 0xF0) == MIDI_CONTROL) && (ev->d1 == CTRL_VOLUME) )
{
setVol((ev->status & 0xF), ev->d2);
@ -231,7 +218,7 @@ void sendEvent(struct Event * ev)
return;
}
if(((ev->status & 0xF0) == MIDI_NOTE_ON) && (ev->d2 == 0)) //Release by vol=0
if(((ev->status & 0xF0) == MIDI_NOTE_ON) && (ev->d2 == 0)) /* Release by vol=0 */
{
releaseNote(ev->status & 0x0F, ev->d1);
return;
@ -282,7 +269,6 @@ int tick(struct MIDIfile * mf)
tracksAdv++;
while(getEvent(tr, tr->pos)->delta <= tr->delta)
{
// printf("\nDelta = %d", tr->delta);
struct Event * e = getEvent(tr, tr->pos);
if(e->status != 0xFF)

View file

@ -45,8 +45,8 @@ void readTextBlock(int file, char * buf)
//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];
@ -63,11 +63,11 @@ int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig)
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 ?
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++)
{
@ -77,15 +77,17 @@ int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig)
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
/*
* 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
/* Scan the file to see what needs to be loaded */
for(a=0; a<mf->numTracks; a++)
{
int ts=0;
unsigned int ts=0;
if(mf->tracks[a] == NULL)
{
@ -119,7 +121,7 @@ int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig)
char name[40];
char fn[40];
//Scan our config file and load the right patches as needed
/* Scan our config file and load the right patches as needed */
int c = 0;
rb->snprintf(name, 40, "");
for(a=0; a<128; a++)
@ -131,10 +133,12 @@ int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig)
printf("\nLOADING: <%s> ", 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);
@ -148,7 +152,7 @@ int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig)
return -1;
}
//Scan our config file and load the drum data
/* Scan our config file and load the drum data */
int idx=0;
char number[30];
while(!eof(file))
@ -162,10 +166,12 @@ int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig)
break;
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);
@ -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,7 +207,7 @@ inline int getSample(int s)
inline void setPoint(struct SynthObject * so, int pt)
{
if(so->ch==9) //Drums, no ADSR
if(so->ch==9) /* Drums, no ADSR */
{
so->curOffset = 1<<27;
so->curRate = 1;
@ -246,25 +230,27 @@ inline void setPoint(struct SynthObject * so, int pt)
int r=0;
int rate = so->wf->envRate[pt];
r=3-((rate>>6) & 0x3); // Some blatant Timidity code for rate conversion...
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.
* 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.
/*
* 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;
@ -297,17 +283,20 @@ inline signed short int synthVoice()
cpShifted = so->cp >> 10;
if( (cpShifted >= (wf->wavSize>>1)) && (so->state != STATE_RAMPDOWN))
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)))
/* 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)<<9;
cpShifted = so->cp >> 10;
so->cp = (wf->endLoop)<<10;
cpShifted = wf->endLoop;
s2=getSample((cpShifted));
} else
{
@ -316,13 +305,13 @@ inline signed short int synthVoice()
}
}
if((wf->mode & 28) && (so->cp>>10 >= wf->endLoop>>1))
if((wf->mode & 28) && (cpShifted >= wf->endLoop))
{
so->loopState = STATE_LOOPING;
if((wf->mode & (24)) == 0)
{
so->cp = (wf->startLoop)<<9;
cpShifted = so->cp >> 10;
so->cp = (wf->startLoop)<<10;
cpShifted = wf->startLoop;
s2=getSample((cpShifted));
} else
{
@ -331,18 +320,18 @@ inline signed short int synthVoice()
}
}
//Better, working, linear interpolation
/* 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->ch != 9) //Stupid ADSR code... and don't do ADSR for drums
if(so->ch != 9) /* Stupid ADSR code... and don't do ADSR for drums */
{
if(so->curOffset < so->targetOffset)
{
@ -370,12 +359,12 @@ inline signed short int synthVoice()
}
if(so->curOffset < 0)
so->isUsed=0; //This is OK
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)
@ -383,17 +372,15 @@ inline signed short int synthVoice()
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;
}
inline void synthSample(int * mixL, int * mixR)
{
// signed int leftMix=0, rightMix=0,
*mixL = 0;
*mixR = 0;
for(currentVoice=0; currentVoice<MAX_VOICES; currentVoice++)
@ -406,7 +393,8 @@ inline void synthSample(int * mixL, int * mixR)
}
}
//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. */
}

View file

@ -20,21 +20,22 @@
#define MAX_VOICES 100
//Only define LOCAL_DSP on Simulator or else we're asking for trouble
/* Only define LOCAL_DSP on Simulator or else we're asking for trouble */
#if defined(SIMULATOR)
//Enable this to write to the soundcard via a /dsv/dsp symlink in /
/*Enable this to write to the soundcard via a /dsv/dsp symlink in */
// #define LOCAL_DSP
#endif
#if defined(LOCAL_DSP)
// This is for writing to the DSP directly from the Simulator
/* This is for writing to the DSP directly from the Simulator */
#include <stdio.h>
#include <stdlib.h>
#include <linux/soundcard.h>
#include <sys/ioctl.h>
#endif
#include "../../firmware/export/system.h"
#include "../../plugin.h"
@ -53,9 +54,9 @@ long bpm;
int fd=-1; //File descriptor where the output is written
int fd=-1; /* File descriptor where the output is written */
extern long tempo; //The sequencer keeps track of this
extern long tempo; /* The sequencer keeps track of this */
struct plugin_api * rb;
@ -77,6 +78,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
rb->splash(HZ*2, true, " Play .MID file ");
return PLUGIN_OK;
}
rb->splash(HZ, true, parameter);
if(midimain(parameter) == -1)
{
@ -86,7 +88,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
return PLUGIN_OK;
}
signed char outputBuffer[3000] IDATA_ATTR; //signed char.. gonna run out of iram ... !
signed char outputBuffer[3000] IDATA_ATTR; /* signed char.. gonna run out of iram ... ! */
int currentSample IDATA_ATTR;
@ -110,27 +112,29 @@ int midimain(void * filename)
return -1;
}
//This lets you hear the music through the sound card if you are on Simulator
//Make a symlink, archos/dsp.raw and make it point to /dev/dsp or whatever
//your sound device is.
/*
* This lets you hear the music through the sound card if you are on Simulator
* Make a symlink, archos/dsp.raw and make it point to /dev/dsp or whatever
* your sound device is.
*/
#if defined(LOCAL_DSP)
fd=rb->open("/dsp.raw", O_WRONLY);
int arg, status;
int bit, samp, ch;
arg = 16; // sample size
arg = 16; /* sample size */
status = ioctl(fd, SOUND_PCM_WRITE_BITS, &arg);
status = ioctl(fd, SOUND_PCM_READ_BITS, &arg);
bit=arg;
arg = 2; //Number of channels, 1=mono
arg = 2; /* Number of channels, 1=mono */
status = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &arg);
status = ioctl(fd, SOUND_PCM_READ_CHANNELS, &arg);
ch=arg;
arg = SAMPLE_RATE; //Yeah. sampling rate
arg = SAMPLE_RATE; /* Yeah. sampling rate */
status = ioctl(fd, SOUND_PCM_WRITE_RATE, &arg);
status = ioctl(fd, SOUND_PCM_READ_RATE, &arg);
samp=arg;
@ -145,25 +149,25 @@ int midimain(void * filename)
#endif
rb->splash(HZ/5, true, " Starting Playback ");
rb->splash(HZ/5, true, " I hope this works... ");
// tick() will do one MIDI clock tick. Then, there's a loop here that
// will generate the right number of samples per MIDI tick. The whole
// MIDI playback is timed in terms of this value.. there are no forced
// delays or anything. It just produces enough samples for each tick, and
// the playback of these samples is what makes the timings right.
//
// This seems to work quite well.
/*
* tick() will do one MIDI clock tick. Then, there's a loop here that
* will generate the right number of samples per MIDI tick. The whole
* MIDI playback is timed in terms of this value.. there are no forced
* delays or anything. It just produces enough samples for each tick, and
* the playback of these samples is what makes the timings right.
*
* This seems to work quite well.
*/
printf("\nOkay, starting sequencing");
currentSample=0; //Sample counting variable
currentSample=0; /* Sample counting variable */
outputBufferPosition = 0;
@ -172,28 +176,26 @@ int midimain(void * filename)
//Tick() will return 0 if there are no more events left to play
/* Tick() will return 0 if there are no more events left to play */
while(tick(mf))
{
//Some annoying math to compute the number of samples
//to syntehsize per each MIDI tick.
//Yes we need to do this math each time because the tempo
//could have changed.
// On second thought, this can be moved to the event that
//recalculates the tempo, to save a little bit of CPU time.
/*
* Tempo recalculation moved to sequencer.c to be done on a tempo event only
*
*/
for(currentSample=0; currentSample<numberOfSamples; currentSample++)
{
synthSample(&outputSampleOne, &outputSampleTwo);
//16-bit audio because, well, it's better
// But really because ALSA's OSS emulation sounds extremely
//noisy and distorted when in 8-bit mode. I still do not know
//why this happens.
/*
* 16-bit audio because, well, it's better
* But really because ALSA's OSS emulation sounds extremely
* noisy and distorted when in 8-bit mode. I still do not know
* why this happens.
*/
outputBuffer[outputBufferPosition]=outputSampleOne&0XFF; // Low byte first
outputBufferPosition++;
outputBuffer[outputBufferPosition]=outputSampleOne>>8; //High byte second
@ -205,9 +207,11 @@ int midimain(void * filename)
outputBufferPosition++;
//As soon as we produce 2000 bytes of sound,
//write it to the sound card. Why 2000? I have
//no idea. It's 1 AM and I am dead tired.
/*
* As soon as we produce 2000 bytes of sound,
* write it to the sound card. Why 2000? I have
* no idea. It's 1 AM and I am dead tired.
*/
if(outputBufferPosition>=2000)
{
rb->write(fd, outputBuffer, 2000);
@ -216,7 +220,6 @@ int midimain(void * filename)
}
}
// unloadFile(mf);
printf("\n");
#if !defined(LOCAL_DSP)