summaryrefslogtreecommitdiffstats
path: root/apps/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins')
-rw-r--r--apps/plugins/midi/guspat.c327
-rw-r--r--apps/plugins/midi/guspat.h94
-rw-r--r--apps/plugins/midi/midifile.c427
-rw-r--r--apps/plugins/midi/midiutil.c222
-rw-r--r--apps/plugins/midi/sequencer.c470
-rw-r--r--apps/plugins/midi/synth.c650
-rw-r--r--apps/plugins/midi2wav.c231
7 files changed, 1181 insertions, 1240 deletions
diff --git a/apps/plugins/midi/guspat.c b/apps/plugins/midi/guspat.c
index 2172072eb1..23b6811542 100644
--- a/apps/plugins/midi/guspat.c
+++ b/apps/plugins/midi/guspat.c
@@ -21,197 +21,176 @@ extern struct plugin_api * rb;
unsigned int readWord(int file)
{
- return (readChar(file)<<0) | (readChar(file)<<8); // | (readChar(file)<<8) | (readChar(file)<<0);
+ return (readChar(file)<<0) | (readChar(file)<<8); // | (readChar(file)<<8) | (readChar(file)<<0);
}
unsigned int readDWord(int file)
{
- return (readChar(file)<<0) | (readChar(file)<<8) | (readChar(file)<<16) | (readChar(file)<<24);
+ return (readChar(file)<<0) | (readChar(file)<<8) | (readChar(file)<<16) | (readChar(file)<<24);
}
struct GWaveform * loadWaveform(int file)
{
- struct GWaveform * wav = (struct GWaveform *)allocate(sizeof(struct GWaveform));
- rb->memset(wav, 0, sizeof(struct GWaveform));
-
- wav->name=readData(file, 7);
- printf("\nWAVE NAME = [%s]", wav->name);
- wav->fractions=readChar(file);
- wav->wavSize=readDWord(file);
- wav->startLoop=readDWord(file);
- wav->endLoop=readDWord(file);
- wav->sampRate=readWord(file);
-
- wav->lowFreq=readDWord(file);
- wav->highFreq=readDWord(file);
- wav->rootFreq=readDWord(file);
-
- wav->tune=readWord(file);
-
- wav->balance=readChar(file);
- wav->envRate=readData(file, 6);
- wav->envOffset=readData(file, 6);
-
- wav->tremSweep=readChar(file);
- wav->tremRate==readChar(file);
- wav->tremDepth=readChar(file);
- wav->vibSweep=readChar(file);
- wav->vibRate=readChar(file);
- wav->vibDepth=readChar(file);
- wav->mode=readChar(file);
-
- wav->scaleFreq=readWord(file);
- wav->scaleFactor=readWord(file);
- printf("\nScaleFreq = %d ScaleFactor = %d RootFreq = %d", wav->scaleFreq, wav->scaleFactor, wav->rootFreq);
- wav->res=readData(file, 36);
- wav->data=readData(file, wav->wavSize);
-
- wav->numSamples = wav->wavSize / 2;
- int a=0;
-
- return wav;
- if(wav->mode & 1 == 0) //Whoops, 8 bit
- {
- wav->numSamples = wav->wavSize;
-
- //Allocate a block for the rest of it
- //It should end up right after the previous one.
- wav->wavSize = wav->wavSize * 2;
- void * foo = allocate(wav->wavSize);
-
-
- for(a=0; a<1000; a++)
- printf("\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
-
-
- for(a=wav->wavSize-1; a>0; a-=2)
- {
-
- }
- // int b1=wf->data[s]+((wf->mode & 2) << 6);
- // return b1<<8;
- }
-
- /*
-//#if !defined(SIMULATOR)
- for(a=0; a<wav->wavSize; a+=2)
- {
- unsigned char tmp;
- tmp = wav->data[2*a];
- wav->data[2*a] = wav->data[2*a+1];
- wav->data[2*a+1] = tmp;
- }
-//#endif
-
- if(wav->mode & 2)
- {
- for(a=0; a<wav->wavSize/2; a++)
- {
- ((short *) wav->data)[a] = ((short *) wav->data)[a] - 32767;
- }
- }
-*/
-
-
-
- //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;
+ struct GWaveform * wav = (struct GWaveform *)allocate(sizeof(struct GWaveform));
+ rb->memset(wav, 0, sizeof(struct GWaveform));
+
+ wav->name=readData(file, 7);
+ printf("\nWAVE NAME = [%s]", wav->name);
+ wav->fractions=readChar(file);
+ wav->wavSize=readDWord(file);
+ wav->startLoop=readDWord(file);
+ wav->endLoop=readDWord(file);
+ wav->sampRate=readWord(file);
+
+ wav->lowFreq=readDWord(file);
+ wav->highFreq=readDWord(file);
+ wav->rootFreq=readDWord(file);
+
+ wav->tune=readWord(file);
+
+ wav->balance=readChar(file);
+ wav->envRate=readData(file, 6);
+ wav->envOffset=readData(file, 6);
+
+ wav->tremSweep=readChar(file);
+ wav->tremRate==readChar(file);
+ wav->tremDepth=readChar(file);
+ wav->vibSweep=readChar(file);
+ wav->vibRate=readChar(file);
+ wav->vibDepth=readChar(file);
+ wav->mode=readChar(file);
+
+ wav->scaleFreq=readWord(file);
+ wav->scaleFactor=readWord(file);
+ printf("\nScaleFreq = %d ScaleFactor = %d RootFreq = %d", wav->scaleFreq, wav->scaleFactor, wav->rootFreq);
+ wav->res=readData(file, 36);
+ wav->data=readData(file, wav->wavSize);
+
+ wav->numSamples = wav->wavSize / 2;
+ wav->startLoop = wav->startLoop >> 1;
+ wav->endLoop = wav->endLoop >> 1;
+ unsigned int a=0;
+
+ /* half baked 8 bit conversion UNFINISHED*/
+ /*
+ if(wav->mode & 1 == 0) //Whoops, 8 bit
+ {
+ wav->numSamples = wav->wavSize;
+
+ //Allocate a block for the rest of it
+ //It should end up right after the previous one.
+ wav->wavSize = wav->wavSize * 2;
+ void * foo = allocate(wav->wavSize);
+
+
+ for(a=0; a<1000; a++)
+ printf("\n!!!!!!!!!!!!!!!!!!!!!!!!!!!");
+
+
+ for(a=wav->wavSize-1; a>0; a-=2)
+ {
+
+ }
+ // int b1=wf->data[s]+((wf->mode & 2) << 6);
+ // return b1<<8;
+ }
+ */
+
+
+ /* Iriver needs byteswapping.. big endian, go figure. Gus files are little endian */
+
+#if !defined(SIMULATOR)
+ for(a=0; a<wav->numSamples; a++)
+ {
+ ((unsigned short *) wav->data)[a] = SWAB16(((unsigned short *) wav->data)[a]);
+ }
+#endif
+
+ /* Convert unsigned to signed by subtracting 32768 */
+ if(wav->mode & 2)
+ {
+ for(a=0; a<wav->numSamples; a++)
+ ((short *) wav->data)[a] = ((unsigned short *) wav->data)[a] - 32768;
+
+ }
+
+ return wav;
}
int selectWaveform(struct GPatch * pat, int midiNote)
{
- int tabFreq = gustable[midiNote]/100; //Comparison
- int a=0;
- for(a=0; a<pat->numWaveforms; a++)
- {
- if(pat->waveforms[a]->lowFreq/100 <= tabFreq &&
- pat->waveforms[a]->highFreq/100 >= tabFreq)
- {
- return a;
- }
- }
- return 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 &&
+ pat->waveforms[a]->highFreq/100 >= tabFreq)
+ {
+ return a;
+ }
+ }
+ return 0;
}
struct GPatch * gusload(char * filename)
{
- struct GPatch * gp = (struct GPatch *)allocate(sizeof(struct GPatch));
- rb->memset(gp, 0, sizeof(struct GPatch));
-
- int file = rb->open(filename, O_RDONLY);
-
- if(file == -1)
- {
- char message[50];
- rb->snprintf(message, 50, "Error opening %s", filename);
- rb->splash(HZ*2, true, message);
- return NULL;
- }
-
- gp->header=readData(file, 12);
- gp->gravisid=readData(file, 10);
- gp->desc=readData(file, 60);
- gp->inst=readChar(file);
- gp->voc=readChar(file);
- gp->chan=readChar(file);
- gp->numWaveforms=readWord(file); //readWord(file);
- gp->vol=readWord(file);
- gp->datSize=readDWord(file);
- gp->res=readData(file, 36);
-
- gp->instrID=readWord(file);
- gp->instrName=readData(file,16);
- gp->instrSize=readDWord(file);
- gp->layers=readChar(file);
- gp->instrRes=readData(file,40);
-
-
- gp->layerDup=readChar(file);
- gp->layerID=readChar(file);
- gp->layerSize=readDWord(file);
- 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);
-
- int a=0;
- for(a=0; a<gp->numWaves; a++)
- gp->waveforms[a] = loadWaveform(file);
-
-
- printf("\nPrecomputing note table");
-
- for(a=0; a<128; a++)
- {
- gp->noteTable[a] = selectWaveform(gp, a);
- }
- rb->close(file);
-
- return gp;
+ struct GPatch * gp = (struct GPatch *)allocate(sizeof(struct GPatch));
+ rb->memset(gp, 0, sizeof(struct GPatch));
+
+ int file = rb->open(filename, O_RDONLY);
+
+ if(file == -1)
+ {
+ char message[50];
+ rb->snprintf(message, 50, "Error opening %s", filename);
+ rb->splash(HZ*2, true, message);
+ return NULL;
+ }
+
+ gp->header=readData(file, 12);
+ gp->gravisid=readData(file, 10);
+ gp->desc=readData(file, 60);
+ gp->inst=readChar(file);
+ gp->voc=readChar(file);
+ gp->chan=readChar(file);
+ gp->numWaveforms=readWord(file);
+ gp->vol=readWord(file);
+ gp->datSize=readDWord(file);
+ gp->res=readData(file, 36);
+
+ gp->instrID=readWord(file);
+ gp->instrName=readData(file,16);
+ gp->instrSize=readDWord(file);
+ gp->layers=readChar(file);
+ gp->instrRes=readData(file,40);
+
+
+ gp->layerDup=readChar(file);
+ gp->layerID=readChar(file);
+ gp->layerSize=readDWord(file);
+ gp->numWaves=readChar(file);
+ gp->layerRes=readData(file,40);
+
+
+ printf("\nFILE: %s", filename);
+ printf("\nlayerSamples=%d", gp->numWaves);
+
+ int a=0;
+ for(a=0; a<gp->numWaves; a++)
+ gp->waveforms[a] = loadWaveform(file);
+
+
+ printf("\nPrecomputing note table");
+
+ for(a=0; a<128; a++)
+ {
+ gp->noteTable[a] = selectWaveform(gp, a);
+ }
+ rb->close(file);
+
+ return gp;
}
diff --git a/apps/plugins/midi/guspat.h b/apps/plugins/midi/guspat.h
index 6e41a85d23..e35f54b57a 100644
--- a/apps/plugins/midi/guspat.h
+++ b/apps/plugins/midi/guspat.h
@@ -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,
@@ -33,63 +33,63 @@ static const unsigned int gustable[]=
struct GWaveform
{
- unsigned char * name;
- unsigned char fractions;
- unsigned int wavSize;
- unsigned int numSamples;
- unsigned int startLoop;
- unsigned int endLoop;
- unsigned int sampRate;
- unsigned int lowFreq;
- unsigned int highFreq;
- unsigned int rootFreq;
- unsigned int tune;
- unsigned int balance;
- unsigned char * envRate;
- unsigned char * envOffset;
+ unsigned char * name;
+ unsigned char fractions;
+ unsigned int wavSize;
+ unsigned int numSamples;
+ unsigned int startLoop;
+ unsigned int endLoop;
+ unsigned int sampRate;
+ unsigned int lowFreq;
+ unsigned int highFreq;
+ unsigned int rootFreq;
+ unsigned int tune;
+ unsigned int balance;
+ unsigned char * envRate;
+ unsigned char * envOffset;
- unsigned char tremSweep;
- unsigned char tremRate;
- unsigned char tremDepth;
- unsigned char vibSweep;
- unsigned char vibRate;
- unsigned char vibDepth;
- unsigned char mode;
+ unsigned char tremSweep;
+ unsigned char tremRate;
+ unsigned char tremDepth;
+ unsigned char vibSweep;
+ unsigned char vibRate;
+ unsigned char vibDepth;
+ unsigned char mode;
- unsigned int scaleFreq;
- unsigned int scaleFactor;
+ unsigned int scaleFreq;
+ unsigned int scaleFactor;
- unsigned char * res;
- signed char * data;
+ unsigned char * res;
+ signed char * data;
};
struct GPatch
{
- unsigned int patchNumber;
- unsigned char * header;
- unsigned char * gravisid;
- unsigned char * desc;
- unsigned char inst, voc, chan;
- unsigned int numWaveforms;
- unsigned int datSize;
- unsigned int vol;
- unsigned char * res;
+ unsigned int patchNumber;
+ unsigned char * header;
+ unsigned char * gravisid;
+ unsigned char * desc;
+ unsigned char inst, voc, chan;
+ unsigned int numWaveforms;
+ unsigned int datSize;
+ unsigned int vol;
+ unsigned char * res;
- unsigned int instrID;
- unsigned char * instrName;
- unsigned int instrSize;
- unsigned int layers;
- unsigned char * instrRes;
+ unsigned int instrID;
+ unsigned char * instrName;
+ unsigned int instrSize;
+ unsigned int layers;
+ unsigned char * instrRes;
- unsigned char layerDup;
- unsigned char layerID;
- unsigned int layerSize;
- unsigned char numWaves;
- unsigned char * layerRes;
+ unsigned char layerDup;
+ unsigned char layerID;
+ unsigned int layerSize;
+ unsigned char numWaves;
+ unsigned char * layerRes;
- unsigned char noteTable[128];
- struct GWaveform * waveforms[255];
+ unsigned char noteTable[128];
+ struct GWaveform * waveforms[255];
};
diff --git a/apps/plugins/midi/midifile.c b/apps/plugins/midi/midifile.c
index c786b8e5a6..412cc6104d 100644
--- a/apps/plugins/midi/midifile.c
+++ b/apps/plugins/midi/midifile.c
@@ -26,233 +26,232 @@ void bail(const char *);
struct MIDIfile * loadFile(char * filename)
{
- struct MIDIfile * mf;
- int file = rb->open (filename, O_RDONLY);
-
- if(file==0)
- {
- bail("Could not open file\n");
- }
-
- mf = (struct MIDIfile*)allocate(sizeof(struct MIDIfile));
-
- if(mf==NULL)
- {
- rb->close(file);
- bail("Could not allocate memory for MIDIfile struct\n");
- }
-
- rb->memset(mf, 0, sizeof(struct MIDIfile));
-
- if(readID(file) != ID_MTHD)
- {
- rb->close(file);
- bail("Invalid file header chunk.");
- }
-
- if(readFourBytes(file)!=6)
- {
- rb->close(file);
- bail("Header chunk size invalid.");
- }
-
- if(readTwoBytes(file)==2)
- {
- rb->close(file);
- bail("MIDI file type not supported");
- }
-
- mf->numTracks = readTwoBytes(file);
- mf->div = readTwoBytes(file);
-
- int track=0;
-
- printf("\nnumTracks=%d div=%d\nBegin reading track data\n", mf->numTracks, mf->div);
-
-// return;
-
-
- while(! eof(file) && track < mf->numTracks)
- {
- unsigned char id = readID(file);
-
-
- if(id == ID_EOF)
- {
- if(mf->numTracks != track)
- {
- printf("\nError: file claims to have %d tracks.\n I only see %d here.\n", mf->numTracks, track);
- mf->numTracks = track;
- }
- return mf;
- }
-
- if(id == ID_MTRK)
- {
- mf->tracks[track] = readTrack(file);
- //exit(0);
- track++;
- } else
- {
- printf("\n SKIPPING TRACK");
- int len = readFourBytes(file);
- while(--len)
- readChar(file);
- }
- }
- return mf;
+ struct MIDIfile * mf;
+ int file = rb->open (filename, O_RDONLY);
+
+ if(file==-1)
+ {
+ bail("Could not open file\n");
+ }
+
+ mf = (struct MIDIfile*)allocate(sizeof(struct MIDIfile));
+
+ if(mf==NULL)
+ {
+ rb->close(file);
+ bail("Could not allocate memory for MIDIfile struct\n");
+ }
+
+ rb->memset(mf, 0, sizeof(struct MIDIfile));
+
+ if(readID(file) != ID_MTHD)
+ {
+ rb->close(file);
+ bail("Invalid file header chunk.");
+ }
+
+ if(readFourBytes(file)!=6)
+ {
+ rb->close(file);
+ bail("Header chunk size invalid.");
+ }
+
+ if(readTwoBytes(file)==2)
+ {
+ rb->close(file);
+ bail("MIDI file type not supported");
+ }
+
+ mf->numTracks = readTwoBytes(file);
+ mf->div = readTwoBytes(file);
+
+ int track=0;
+
+ printf("\nnumTracks=%d div=%d\nBegin reading track data\n", mf->numTracks, mf->div);
+
+
+ while(! eof(file) && track < mf->numTracks)
+ {
+ unsigned char id = readID(file);
+
+
+ if(id == ID_EOF)
+ {
+ if(mf->numTracks != track)
+ {
+ printf("\nError: file claims to have %d tracks.\n I only see %d here.\n", mf->numTracks, track);
+ mf->numTracks = track;
+ }
+ return mf;
+ }
+
+ if(id == ID_MTRK)
+ {
+ mf->tracks[track] = readTrack(file);
+ //exit(0);
+ track++;
+ } else
+ {
+ printf("\n SKIPPING TRACK");
+ int len = readFourBytes(file);
+ while(--len)
+ readChar(file);
+ }
+ }
+ return mf;
}
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->delta = readVarData(file);
-
-
- int t=readChar(file);
-
- if((t&0x80) == 0x80) //if not a running status event
- {
- ev->status = t;
- if(t == 0xFF)
- {
- ev->d1 = readChar(file);
- ev->len = readVarData(file);
-
- //Allocate and read in the data block
- if(dest != NULL)
- {
- ev->evData = readData(file, ev->len);
- printf("\nDATA: <%s>", ev->evData);
- }
- else
- {
- //Don't allocate anything, just see how much it would tale
- //To make memory usage efficient
-
- int a=0;
- for(a=0; a<ev->len; a++)
- readChar(file); //Skip skip
- }
-
- if(ev->d1 == 0x2F)
- {
- return 0; //Termination meta-event
- }
- } else //If part of a running status event
- {
- rStatus = t;
- ev->status = t;
- ev->d1 = readChar(file);
-
- if ( ((t & 0xF0) != 0xD0) && ((t & 0xF0) != 0xC0) && ((t & 0xF0) > 0x40) )
- {
- ev->d2 = readChar(file);
- } else
- ev->d2 = 127;
- }
- } else //Running Status
- {
- ev->status = rStatus;
- ev->d1 = t;
- if ( ((rStatus & 0xF0) != 0xD0) && ((rStatus & 0xF0) != 0xC0) && ((rStatus & 0xF0) > 0x40) )
- {
- ev->d2 = readChar(file);
- } else
- ev->d2 = 127;
- }
- return 1;
+ 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->delta = readVarData(file);
+
+
+ int t=readChar(file);
+
+ if((t&0x80) == 0x80) /* if not a running status event */
+ {
+ ev->status = t;
+ if(t == 0xFF)
+ {
+ ev->d1 = readChar(file);
+ ev->len = readVarData(file);
+
+ /* Allocate and read in the data block */
+ if(dest != NULL)
+ {
+ ev->evData = readData(file, ev->len);
+ printf("\nDATA: <%s>", ev->evData);
+ }
+ else
+ {
+ /*
+ * 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 */
+ }
+ } else /* If part of a running status event */
+ {
+ rStatus = t;
+ ev->status = t;
+ ev->d1 = readChar(file);
+
+ if ( ((t & 0xF0) != 0xD0) && ((t & 0xF0) != 0xC0) && ((t & 0xF0) > 0x40) )
+ {
+ ev->d2 = readChar(file);
+ } else
+ ev->d2 = 127;
+ }
+ } else /* Running Status */
+ {
+ ev->status = rStatus;
+ ev->d1 = t;
+ if ( ((rStatus & 0xF0) != 0xD0) && ((rStatus & 0xF0) != 0xC0) && ((rStatus & 0xF0) > 0x40) )
+ {
+ ev->d2 = readChar(file);
+ } else
+ ev->d2 = 127;
+ }
+ return 1;
}
struct Track * readTrack(int file)
{
- struct Track * trk = (struct Track *)allocate(sizeof(struct Track));
- rb->memset(trk, 0, sizeof(struct Track));
+ struct Track * trk = (struct Track *)allocate(sizeof(struct Track));
+ rb->memset(trk, 0, sizeof(struct Track));
- trk->size = readFourBytes(file);
- trk->pos = 0;
- trk->delta = 0;
+ trk->size = readFourBytes(file);
+ trk->pos = 0;
+ trk->delta = 0;
- int numEvents=0;
+ int numEvents=0;
- int pos = rb->lseek(file, 0, SEEK_CUR);
+ 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
- rb->lseek(file, pos, SEEK_SET);
+ 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);
- void * dataPtr = allocate(trackSize);
- trk->dataBlock = dataPtr;
+ int trackSize = (numEvents+1) * sizeof(struct Event);
+ void * dataPtr = allocate(trackSize);
+ trk->dataBlock = dataPtr;
- numEvents=0;
+ numEvents=0;
- while(readEvent(file, dataPtr))
- {
- if(trackSize < dataPtr-trk->dataBlock)
- {
- printf("\nTrack parser memory out of bounds");
- exit(1);
- }
- dataPtr+=sizeof(struct Event);
- numEvents++;
- }
- trk->numEvents = numEvents;
+ while(readEvent(file, dataPtr))
+ {
+ if(trackSize < dataPtr-trk->dataBlock)
+ {
+ printf("\nTrack parser memory out of bounds");
+ exit(1);
+ }
+ dataPtr+=sizeof(struct Event);
+ numEvents++;
+ }
+ trk->numEvents = numEvents;
- return trk;
+ return trk;
}
int readID(int file)
{
- char id[5];
- id[4]=0;
- BYTE a;
-
- for(a=0; a<4; a++)
- id[a]=readChar(file);
- if(eof(file))
- {
- printf("\End of file reached.");
- return ID_EOF;
- }
- if(rb->strcmp(id, "MThd")==0)
- return ID_MTHD;
- if(rb->strcmp(id, "MTrk")==0)
- return ID_MTRK;
- return ID_UNKNOWN;
+ char id[5];
+ id[4]=0;
+ BYTE a;
+
+ for(a=0; a<4; a++)
+ id[a]=readChar(file);
+ if(eof(file))
+ {
+ printf("\End of file reached.");
+ return ID_EOF;
+ }
+ if(rb->strcmp(id, "MThd")==0)
+ return ID_MTHD;
+ if(rb->strcmp(id, "MTrk")==0)
+ return ID_MTRK;
+ return ID_UNKNOWN;
}
int readFourBytes(int file)
{
- int data=0;
- BYTE a=0;
- for(a=0; a<4; a++)
- data=(data<<8)+readChar(file);
- return data;
+ int data=0;
+ BYTE a=0;
+ for(a=0; a<4; a++)
+ data=(data<<8)+readChar(file);
+ return data;
}
int readTwoBytes(int file)
{
- int data=(readChar(file)<<8)+readChar(file);
- return data;
+ int data=(readChar(file)<<8)+readChar(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,37 +269,35 @@ 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)
- return;
- int a=0;
- //Unload each track
- for(a=0; a<mf->numTracks; a++)
- {
- int b=0;
-
- if(mf->tracks[a] != NULL)
- for(b=0; b<mf->tracks[a]->numEvents; b++)
- {
- if(((struct Event*)((mf->tracks[a]->dataBlock)+b*sizeof(struct Event)))->evData!=NULL)
- free(((struct Event*)((mf->tracks[a]->dataBlock)+b*sizeof(struct Event)))->evData);
- }
-
- if(mf->tracks[a]!=NULL && mf->tracks[a]->dataBlock != NULL)
- free(mf->tracks[a]->dataBlock); //Unload the event block
-
- if(mf->tracks[a]!=NULL)
- free(mf->tracks[a]); //Unload the track structure itself
- }
- free(mf); //Unload the main struct
+ if(mf == NULL)
+ return;
+ int a=0;
+ //Unload each track
+ for(a=0; a<mf->numTracks; a++)
+ {
+ int b=0;
+
+ if(mf->tracks[a] != NULL)
+ for(b=0; b<mf->tracks[a]->numEvents; b++)
+ {
+ if(((struct Event*)((mf->tracks[a]->dataBlock)+b*sizeof(struct Event)))->evData!=NULL)
+ free(((struct Event*)((mf->tracks[a]->dataBlock)+b*sizeof(struct Event)))->evData);
+ }
+
+ if(mf->tracks[a]!=NULL && mf->tracks[a]->dataBlock != NULL)
+ free(mf->tracks[a]->dataBlock); //Unload the event block
+
+ if(mf->tracks[a]!=NULL)
+ free(mf->tracks[a]); //Unload the track structure itself
+ }
+ free(mf); //Unload the main struct
}
*/
void bail(const char * err)
{
- rb->splash(HZ*3, true, err);
- exit(0);
+ rb->splash(HZ*3, true, err);
+ exit(0);
}
diff --git a/apps/plugins/midi/midiutil.c b/apps/plugins/midi/midiutil.c
index bf25d1d277..d0b968e52c 100644
--- a/apps/plugins/midi/midiutil.c
+++ b/apps/plugins/midi/midiutil.c
@@ -20,39 +20,39 @@
#define BYTE unsigned char
//Data chunk ID types, returned by readID()
-#define ID_UNKNOWN -1
-#define ID_MTHD 1
-#define ID_MTRK 2
-#define ID_EOF 3
+#define ID_UNKNOWN -1
+#define ID_MTHD 1
+#define ID_MTRK 2
+#define ID_EOF 3
//MIDI Commands
-#define MIDI_NOTE_OFF 128
-#define MIDI_NOTE_ON 144
-#define MIDI_AFTERTOUCH 160
-#define MIDI_CONTROL 176
-#define MIDI_PRGM 192
-#define MIDI_PITCHW 224
+#define MIDI_NOTE_OFF 128
+#define MIDI_NOTE_ON 144
+#define MIDI_AFTERTOUCH 160
+#define MIDI_CONTROL 176
+#define MIDI_PRGM 192
+#define MIDI_PITCHW 224
//MIDI Controllers
-#define CTRL_VOLUME 7
-#define CTRL_BALANCE 8
-#define CTRL_PANNING 10
-#define CHANNEL 1
+#define CTRL_VOLUME 7
+#define CTRL_BALANCE 8
+#define CTRL_PANNING 10
+#define CHANNEL 1
//Most of these are deprecated.. rampdown is used, maybe one other one too
-#define STATE_ATTACK 1
-#define STATE_DECAY 2
-#define STATE_SUSTAIN 3
-#define STATE_RELEASE 4
-#define STATE_RAMPDOWN 5
+#define STATE_ATTACK 1
+#define STATE_DECAY 2
+#define STATE_SUSTAIN 3
+#define STATE_RELEASE 4
+#define STATE_RAMPDOWN 5
//Loop states
#define STATE_LOOPING 7
-#define STATE_NONLOOPING 8
+#define STATE_NONLOOPING 8
//Various bits in the GUS mode byte
-#define LOOP_ENABLED 4
+#define LOOP_ENABLED 4
#define LOOP_PINGPONG 8
#define LOOP_REVERSE 16
@@ -63,81 +63,69 @@
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;
- unsigned char status, d1, d2;
- unsigned int len;
- unsigned char * evData;
+ unsigned int delta;
+ unsigned char status, d1, d2;
+ unsigned int len;
+ unsigned char * evData;
};
struct Track
{
- unsigned int size;
- unsigned int numEvents;
- unsigned int delta; //For sequencing
- unsigned int pos; //For sequencing
- void * dataBlock;
+ unsigned int size;
+ unsigned int numEvents;
+ unsigned int delta; /* For sequencing */
+ unsigned int pos; /* For sequencing */
+ void * dataBlock;
};
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
- struct Track * tracks[48];
- unsigned char patches[128];
- int numPatches;
+ int Length;
+ unsigned short numTracks;
+ 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;
- unsigned int cp;
- unsigned char state, loopState, loopDir;
- unsigned char note, vol, ch, isUsed;
- int curRate, curOffset, targetOffset;
- unsigned int curPoint;
+ struct GWaveform * wf;
+ unsigned int delta;
+ unsigned int decay;
+ unsigned int cp;
+ unsigned char state, loopState, loopDir;
+ unsigned char note, vol, ch, isUsed;
+ int curRate, curOffset, targetOffset;
+ unsigned int curPoint;
};
*/
+
struct SynthObject
{
-// int tmp;
- struct GWaveform * wf;
- int delta;
- int decay;
- int cp;
- int state, loopState, loopDir;
- int note, vol, ch, isUsed;
- int curRate, curOffset, targetOffset;
- int curPoint;
+ struct GWaveform * wf;
+ int delta;
+ int decay;
+ unsigned int cp;
+ int state, loopState, loopDir;
+ int note, vol, ch, isUsed;
+ int curRate, curOffset, targetOffset;
+ int curPoint;
};
struct SynthObject voices[MAX_VOICES] IDATA_ATTR;
@@ -156,91 +144,91 @@ int midimain(void * filename);
void *alloc(int size)
{
- static char *offset = NULL;
- static int totalSize = 0;
- char *ret;
+ static char *offset = NULL;
+ static int totalSize = 0;
+ char *ret;
- int remainder = size % 4;
+ int remainder = size % 4;
- size = size + 4-remainder;
+ size = size + 4-remainder;
- if (offset == NULL)
- {
- offset = rb->plugin_get_audio_buffer(&totalSize);
- }
+ if (offset == NULL)
+ {
+ offset = rb->plugin_get_audio_buffer(&totalSize);
+ }
- if (size + 4 > totalSize)
- {
- return NULL;
- }
+ if (size + 4 > totalSize)
+ {
+ return NULL;
+ }
- ret = offset + 4;
- *((unsigned int *)offset) = size;
+ ret = offset + 4;
+ *((unsigned int *)offset) = size;
- offset += size + 4;
- totalSize -= size + 4;
- return ret;
+ offset += size + 4;
+ totalSize -= size + 4;
+ return ret;
}
-//Rick's code
+/* Rick's code */
/*
void *alloc(int size)
{
- static char *offset = NULL;
- static int totalSize = 0;
- char *ret;
+ static char *offset = NULL;
+ static int totalSize = 0;
+ char *ret;
- if (offset == NULL)
- {
- offset = rb->plugin_get_audio_buffer(&totalSize);
- }
+ if (offset == NULL)
+ {
+ offset = rb->plugin_get_audio_buffer(&totalSize);
+ }
- if (size + 4 > totalSize)
- {
- return NULL;
- }
+ if (size + 4 > totalSize)
+ {
+ return NULL;
+ }
- ret = offset + 4;
- *((unsigned int *)offset) = size;
+ ret = offset + 4;
+ *((unsigned int *)offset) = size;
- offset += size + 4;
- totalSize -= size + 4;
- return ret;
+ offset += size + 4;
+ totalSize -= size + 4;
+ return ret;
}*/
void * allocate(int size)
{
- return alloc(size);
+ return alloc(size);
}
unsigned char readChar(int file)
{
- char buf[2];
- rb->read(file, &buf, 1);
- return buf[0];
+ char buf[2];
+ rb->read(file, &buf, 1);
+ return buf[0];
}
unsigned char * readData(int file, int len)
{
- unsigned char * dat = allocate(len);
- rb->read(file, dat, len);
- return dat;
+ unsigned char * dat = allocate(len);
+ rb->read(file, dat, len);
+ return dat;
}
int eof(int fd)
{
- int curPos = rb->lseek(fd, 0, SEEK_CUR);
+ int curPos = rb->lseek(fd, 0, SEEK_CUR);
- int size = rb->lseek(fd, 0, SEEK_END);
+ int size = rb->lseek(fd, 0, SEEK_END);
- rb->lseek(fd, curPos, SEEK_SET);
- return size+1 == rb->lseek(fd, 0, SEEK_CUR);
+ rb->lseek(fd, curPos, SEEK_SET);
+ return size+1 == rb->lseek(fd, 0, SEEK_CUR);
}
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 */
}
diff --git a/apps/plugins/midi/sequencer.c b/apps/plugins/midi/sequencer.c
index 836866a5df..4781963645 100644
--- a/apps/plugins/midi/sequencer.c
+++ b/apps/plugins/midi/sequencer.c
@@ -24,233 +24,220 @@ long tempo=375000;
void setVol(int ch, int vol)
{
- printf("\nvolume[%d] %d ==> %d", ch, chVol[ch], vol);
- chVol[ch]=vol;
+ printf("\nvolume[%d] %d ==> %d", ch, chVol[ch], vol);
+ chVol[ch]=vol;
}
void setPan(int ch, int pan)
{
- printf("\npanning[%d] %d ==> %d", ch, chPanRight[ch], pan);
+ printf("\npanning[%d] %d ==> %d", ch, chPanRight[ch], pan);
- chPanLeft[ch]=128-pan;
- chPanRight[ch]=pan;
+ chPanLeft[ch]=128-pan;
+ chPanRight[ch]=pan;
}
void setPatch(int ch, int pat)
{
- chPat[ch]=pat;
+ chPat[ch]=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[]=
{
- 58386,58491,58597,58703,58809,58915,59022,59128,59235,59342,59449,59557,59664,59772,59880,59988,60097,60205,
- 60314,60423,60532,60642,60751,60861,60971,61081,61191,61302,61413,61524,61635,61746,61858,61970,62081,62194,
- 62306,62419,62531,62644,62757,62871,62984,63098,63212,63326,63441,63555,63670,63785,63901,64016,64132,64248,
- 64364,64480,64596,64713,64830,64947,65065,65182,65300,65418,65536,65654,65773,65892,66011,66130,66250,66369,
- 66489,66609,66730,66850,66971,67092,67213,67335,67456,67578,67700,67823,67945,68068,68191,68314,68438,68561,
- 68685,68809,68933,69058,69183,69308,69433,69558,69684,69810,69936,70062,70189,70316,70443,70570,70698,70825,
- 70953,71082,71210,71339,71468,71597,71726,71856,71985,72115,72246,72376,72507,72638,72769,72901,73032,73164,
- 73297,73429
+ 58386,58491,58597,58703,58809,58915,59022,59128,59235,59342,59449,59557,59664,59772,59880,59988,60097,60205,
+ 60314,60423,60532,60642,60751,60861,60971,61081,61191,61302,61413,61524,61635,61746,61858,61970,62081,62194,
+ 62306,62419,62531,62644,62757,62871,62984,63098,63212,63326,63441,63555,63670,63785,63901,64016,64132,64248,
+ 64364,64480,64596,64713,64830,64947,65065,65182,65300,65418,65536,65654,65773,65892,66011,66130,66250,66369,
+ 66489,66609,66730,66850,66971,67092,67213,67335,67456,67578,67700,67823,67945,68068,68191,68314,68438,68561,
+ 68685,68809,68933,69058,69183,69308,69433,69558,69684,69810,69936,70062,70189,70316,70443,70570,70698,70825,
+ 70953,71082,71210,71339,71468,71597,71726,71856,71985,72115,72246,72376,72507,72638,72769,72901,73032,73164,
+ 73297,73429
};
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;
+ 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;
}
void setPW(int ch, int msb)
{
- printf("\npitchw[%d] %d ==> %d", ch, chPW[ch], msb);
- chPW[ch] = msb;
-
- int a=0;
- for(a = 0; a<MAX_VOICES; a++)
- {
- if(voices[a].isUsed==1 && voices[a].ch == ch)
- {
- findDelta(&voices[a], ch, voices[a].note);
- }
- }
+ printf("\npitchw[%d] %d ==> %d", ch, chPW[ch], msb);
+ chPW[ch] = msb;
+
+ int a=0;
+ for(a = 0; a<MAX_VOICES; a++)
+ {
+ if(voices[a].isUsed==1 && voices[a].ch == ch)
+ {
+ findDelta(&voices[a], ch, voices[a].note);
+ }
+ }
}
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 == 2) return;
- if(ch == 3) return;
- if(ch == 4) return;
- if(ch == 5) return;
- if(ch == 6) return;
- if(ch == 7) return;
- if(ch == 8) return;
- if(ch == 9) return;
- if(ch == 10) return;
- if(ch == 11) return;
- if(ch == 12) return;
- if(ch == 13) return;
- if(ch == 14) return;
- if(ch == 15) return;
+ if(ch == 0) return;
+ if(ch == 1) return;
+ if(ch == 2) return;
+ if(ch == 3) return;
+// if(ch == 4) return;
+ if(ch == 5) return;
+ if(ch == 6) return;
+ if(ch == 7) return;
+ if(ch == 8) return;
+ if(ch == 9) return;
+ if(ch == 10) return;
+ if(ch == 11) return;
+ if(ch == 12) return;
+ if(ch == 13) return;
+ if(ch == 14) return;
+ if(ch == 15) return;
*/
- int a=0;
- for(a=0; a<MAX_VOICES; a++)
- {
- if(voices[a].ch == ch && voices[a].note == note)
- break;
-
- if(voices[a].isUsed==0)
- break;
- }
- if(a==MAX_VOICES-1)
- {
- printf("\nOVERFLOW: Too many voices playing at once. No more left");
- 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
- }
- 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
- */
-
-
- /*
- 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
- voices[a].isUsed=1;
- setPoint(&voices[a], 0);
- } else
- {
- if(drumSet[note]!=NULL)
- {
- if(note<35)
- printf("\nNOTE LESS THAN 35, AND A DRUM PATCH EXISTS FOR THIS? WHAT THE HELL?");
-
- struct GWaveform * wf = drumSet[note]->waveforms[0];
- voices[a].wf=wf;
- voices[a].delta = (((gustable[note]<<10) / wf->rootFreq) * wf->sampRate / SAMPLE_RATE);
- if(wf->mode & 28)
- printf("\nWoah, a drum patch has a loop. Stripping the loop...");
- wf->mode = wf->mode & (255-28);
- //Turn it on
- voices[a].isUsed=1;
- setPoint(&voices[a], 0);
-
- } else
- {
- printf("\nWarning: drum %d does not have a patch defined... Ignoring it", note);
- }
- }
+ int a=0;
+ for(a=0; a<MAX_VOICES; a++)
+ {
+ if(voices[a].ch == ch && voices[a].note == note)
+ break;
+
+ if(voices[a].isUsed==0)
+ break;
+ }
+ if(a==MAX_VOICES-1)
+ {
+ printf("\nOVERFLOW: Too many voices playing at once. No more left");
+ 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 available */
+ }
+ voices[a].ch=ch;
+ voices[a].note=note;
+ voices[a].vol=vol;
+ voices[a].cp=0;
+ voices[a].state=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
+ */
+
+ if(ch!=9)
+ {
+ findDelta(&voices[a], ch, note);
+ /* Turn it on */
+ voices[a].isUsed=1;
+ setPoint(&voices[a], 0);
+ } else
+ {
+ if(drumSet[note]!=NULL)
+ {
+ if(note<35)
+ printf("\nNOTE LESS THAN 35, AND A DRUM PATCH EXISTS FOR THIS? WHAT THE HELL?");
+
+ struct GWaveform * wf = drumSet[note]->waveforms[0];
+ voices[a].wf=wf;
+ voices[a].delta = (((gustable[note]<<10) / wf->rootFreq) * wf->sampRate / SAMPLE_RATE);
+ if(wf->mode & 28)
+ printf("\nWoah, a drum patch has a loop. Stripping the loop...");
+ wf->mode = wf->mode & (255-28);
+
+ /* Turn it on */
+ voices[a].isUsed=1;
+ setPoint(&voices[a], 0);
+
+ } else
+ {
+ printf("\nWarning: drum %d does not have a patch defined... Ignoring it", note);
+ }
+ }
}
void releaseNote(int ch, int note)
{
- if(ch==9) // && note != 27 && note != 31 && note != 28)
- return;
- int a=0;
- for(a=0; a<MAX_VOICES; a++)
- {
- if(voices[a].ch == ch && voices[a].note == 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);
- }
- }
- }
+ if(ch==9)
+ return;
+
+ int a=0;
+ for(a=0; a<MAX_VOICES; a++)
+ {
+ if(voices[a].ch == ch && voices[a].note == note)
+ {
+ if((voices[a].wf->mode & 28))
+ {
+ setPoint(&voices[a], 3);
+ }
+ }
+ }
}
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);
- return;
- }
-
- if( ((ev->status & 0xF0) == MIDI_CONTROL) && (ev->d1 == CTRL_PANNING))
- {
- setPan((ev->status & 0xF), ev->d2);
- return;
- }
-
- if(((ev->status & 0xF0) == MIDI_PITCHW))
- {
- setPW((ev->status & 0xF), ev->d2);
- return;
- }
-
- if(((ev->status & 0xF0) == MIDI_NOTE_ON) && (ev->d2 != 0))
- {
- pressNote(ev->status & 0x0F, ev->d1, ev->d2);
- return;
- }
-
- if(((ev->status & 0xF0) == MIDI_NOTE_ON) && (ev->d2 == 0)) //Release by vol=0
- {
- releaseNote(ev->status & 0x0F, ev->d1);
- return;
- }
-
-
- if((ev->status & 0xF0) == MIDI_NOTE_OFF)
- {
- releaseNote(ev->status & 0x0F, ev->d1);
- return;
- }
-
- if((ev->status & 0xF0) == MIDI_PRGM)
- {
- if((ev->status & 0x0F) == 9)
- printf("\nNOT PATCHING: Someone tried patching Channel 9 onto something?");
- else
- setPatch(ev->status & 0x0F, ev->d1);
- }
+ if( ((ev->status & 0xF0) == MIDI_CONTROL) && (ev->d1 == CTRL_VOLUME) )
+ {
+ setVol((ev->status & 0xF), ev->d2);
+ return;
+ }
+
+ if( ((ev->status & 0xF0) == MIDI_CONTROL) && (ev->d1 == CTRL_PANNING))
+ {
+ setPan((ev->status & 0xF), ev->d2);
+ return;
+ }
+
+ if(((ev->status & 0xF0) == MIDI_PITCHW))
+ {
+ setPW((ev->status & 0xF), ev->d2);
+ return;
+ }
+
+ if(((ev->status & 0xF0) == MIDI_NOTE_ON) && (ev->d2 != 0))
+ {
+ pressNote(ev->status & 0x0F, ev->d1, ev->d2);
+ return;
+ }
+
+ if(((ev->status & 0xF0) == MIDI_NOTE_ON) && (ev->d2 == 0)) /* Release by vol=0 */
+ {
+ releaseNote(ev->status & 0x0F, ev->d1);
+ return;
+ }
+
+
+ if((ev->status & 0xF0) == MIDI_NOTE_OFF)
+ {
+ releaseNote(ev->status & 0x0F, ev->d1);
+ return;
+ }
+
+ if((ev->status & 0xF0) == MIDI_PRGM)
+ {
+ if((ev->status & 0x0F) == 9)
+ printf("\nNOT PATCHING: Someone tried patching Channel 9 onto something?");
+ else
+ setPatch(ev->status & 0x0F, ev->d1);
+ }
}
@@ -259,61 +246,60 @@ void sendEvent(struct Event * ev)
int tick(struct MIDIfile * mf)
{
- if(mf==NULL)
- return 0;
-
- int a=0;
- int tracksAdv=0;
- for(a=0; a<mf->numTracks; a++)
- {
- struct Track * tr = mf->tracks[a];
-
- if(tr == NULL)
- printf("\nNULL TRACK: %d", a);
-
-
- //BIG DEBUG STATEMENT
- //printf("\nTrack %2d, Event = %4d of %4d, Delta = %5d, Next = %4d", a, tr->pos, tr->numEvents, tr->delta, getEvent(tr, tr->pos)->delta);
-
-
- if(tr != NULL && (tr->pos < tr->numEvents))
- {
- tr->delta++;
- 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)
- {
- sendEvent(e);
- if(((e->status&0xF0) == MIDI_PRGM))
- {
- printf("\nPatch Event, patch[%d] ==> %d", e->status&0xF, e->d1);
- }
- }
- else
- {
- if(e->d1 == 0x51)
- {
- tempo = (((short)e->evData[0])<<16)|(((short)e->evData[1])<<8)|(e->evData[2]);
- printf("\nMeta-Event: Tempo Set = %d", tempo);
- bpm=mf->div*1000000/tempo;
- numberOfSamples=SAMPLE_RATE/bpm;
-
- }
- }
- tr->delta = 0;
- tr->pos++;
- if(tr->pos>=(tr->numEvents-1))
- break;
- }
- }
- }
-
- if(tracksAdv != 0)
- return 1;
- else
- return 0;
+ if(mf==NULL)
+ return 0;
+
+ int a=0;
+ int tracksAdv=0;
+ for(a=0; a<mf->numTracks; a++)
+ {
+ struct Track * tr = mf->tracks[a];
+
+ if(tr == NULL)
+ printf("\nNULL TRACK: %d", a);
+
+
+ //BIG DEBUG STATEMENT
+ //printf("\nTrack %2d, Event = %4d of %4d, Delta = %5d, Next = %4d", a, tr->pos, tr->numEvents, tr->delta, getEvent(tr, tr->pos)->delta);
+
+
+ if(tr != NULL && (tr->pos < tr->numEvents))
+ {
+ tr->delta++;
+ tracksAdv++;
+ while(getEvent(tr, tr->pos)->delta <= tr->delta)
+ {
+ struct Event * e = getEvent(tr, tr->pos);
+
+ if(e->status != 0xFF)
+ {
+ sendEvent(e);
+ if(((e->status&0xF0) == MIDI_PRGM))
+ {
+ printf("\nPatch Event, patch[%d] ==> %d", e->status&0xF, e->d1);
+ }
+ }
+ else
+ {
+ if(e->d1 == 0x51)
+ {
+ tempo = (((short)e->evData[0])<<16)|(((short)e->evData[1])<<8)|(e->evData[2]);
+ printf("\nMeta-Event: Tempo Set = %d", tempo);
+ bpm=mf->div*1000000/tempo;
+ numberOfSamples=SAMPLE_RATE/bpm;
+
+ }
+ }
+ tr->delta = 0;
+ tr->pos++;
+ if(tr->pos>=(tr->numEvents-1))
+ break;
+ }
+ }
+ }
+
+ if(tracksAdv != 0)
+ return 1;
+ else
+ return 0;
}
diff --git a/apps/plugins/midi/synth.c b/apps/plugins/midi/synth.c
index bafaf1c7ca..50becf32a4 100644
--- a/apps/plugins/midi/synth.c
+++ b/apps/plugins/midi/synth.c
@@ -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');
-
- 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);
+ 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);
}
-//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;
- }
-
- 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;
-
- //Scan the file to see what needs to be loaded
- for(a=0; a<mf->numTracks; a++)
- {
- int ts=0;
-
- 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++)
- {
-
- 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;
- }
- }
- }
-
- 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];
-
- //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);
-
- if(patchUsed[a]==1)
- patchSet[a]=gusload(fn);
-
-// if(patchSet[a] == NULL)
-// return -1;
-
- 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;
- }
-
- //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;
-
- if(drumUsed[idx]==1)
- drumSet[idx]=gusload(fn);
-
-// if(drumSet[idx] == NULL)
-// return -1;
-
- while((c != '\n') && (c != 255) && (!eof(file)))
- c = readChar(file);
- }
- rb->close(file);
- return 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;
+ }
+
+ /*
+ * 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++)
+ {
+ unsigned int ts=0;
+
+ 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++)
+ {
+
+ 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;
+ }
+ }
+ }
+
+ 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];
+
+ /* 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);
+
+ if(patchUsed[a]==1)
+ {
+ patchSet[a]=gusload(fn);
+
+ if(patchSet[a] == NULL) /* There was an error loading it */
+ return -1;
+ }
+
+ 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;
+ }
+
+ /* 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;
+
+ if(drumUsed[idx]==1)
+ {
+ drumSet[idx]=gusload(fn);
+
+ if(drumSet[idx] == NULL) /* Error loading patch */
+ return -1;
+ }
+
+ 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->wf==NULL)
- {
- printf("\nCrap... null waveform...");
- exit(1);
- }
- if(so->wf->envRate==NULL)
- {
- printf("\nWaveform has no envelope set");
- exit(1);
- }
-
- so->curPoint = 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;
-
- /*
- 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;
-
-
- so->targetOffset = so->wf->envOffset[pt]<<(20);
- if(pt==0)
- so->curOffset = 0;
+ 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);
+ }
+
+ so->curPoint = 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;
+
+ /*
+ * 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;
+
+
+ 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;
- }
- }
-
- 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;
- }
- }
-
- //Better, working, linear interpolation
- s1=getSample((cpShifted));
- s = s1 + ((signed)((s2 - s1) * (so->cp & 1023))>>10);
-
-
-//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->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->curOffset < 0)
- so->isUsed=0; //This is OK
-
-
- s = (s * (so->curOffset >> 22) >> 6);
-
-// ............. TO HERE
-
-
- if(so->state == STATE_RAMPDOWN)
- {
- so->decay--;
- if(so->decay == 0)
- so->isUsed=0;
- }
-
- s = s * so->decay; s = s >> 10;
-
- return s*((signed short int)so->vol*(signed short int)chVol[so->ch])>>14;
+ /* 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) && (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);
+
+
+/* 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->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->curOffset < 0)
+ so->isUsed=0; /* This is OK because offset faded it out already */
+
+
+ s = (s * (so->curOffset >> 22) >> 8);
+
+/* ............. TO HERE */
+
+
+ if(so->state == STATE_RAMPDOWN)
+ {
+ so->decay--;
+ if(so->decay == 0)
+ so->isUsed=0;
+ s = (s * so->decay) >> 8;
+ }
+
+ 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;
- }
- }
-
- //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.
+ *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. */
}
diff --git a/apps/plugins/midi2wav.c b/apps/plugins/midi2wav.c
index 6dc7a626b5..241d56defb 100644
--- a/apps/plugins/midi2wav.c
+++ b/apps/plugins/midi2wav.c
@@ -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 /
-// #define LOCAL_DSP
+ /*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;
@@ -66,27 +67,28 @@ struct plugin_api * rb;
enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
{
- TEST_PLUGIN_API(api);
- rb = api;
- TEST_PLUGIN_API(api);
- (void)parameter;
- rb = api;
-
- if(parameter == NULL)
- {
- rb->splash(HZ*2, true, " Play .MID file ");
- return PLUGIN_OK;
- }
- rb->splash(HZ, true, parameter);
- if(midimain(parameter) == -1)
- {
- return PLUGIN_ERROR;
- }
- rb->splash(HZ*3, true, "FINISHED PLAYING");
- return PLUGIN_OK;
+ TEST_PLUGIN_API(api);
+ rb = api;
+ TEST_PLUGIN_API(api);
+ (void)parameter;
+ rb = api;
+
+ if(parameter == NULL)
+ {
+ rb->splash(HZ*2, true, " Play .MID file ");
+ return PLUGIN_OK;
+ }
+
+ rb->splash(HZ, true, parameter);
+ if(midimain(parameter) == -1)
+ {
+ return PLUGIN_ERROR;
+ }
+ rb->splash(HZ*3, true, "FINISHED PLAYING");
+ 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;
@@ -98,132 +100,133 @@ int outputSampleTwo IDATA_ATTR;
int midimain(void * filename)
{
- printf("\nHello.\n");
+ printf("\nHello.\n");
- rb->splash(HZ/5, true, "LOADING MIDI");
+ rb->splash(HZ/5, true, "LOADING MIDI");
- struct MIDIfile * mf = loadFile(filename);
+ struct MIDIfile * mf = loadFile(filename);
- rb->splash(HZ/5, true, "LOADING PATCHES");
- if (initSynth(mf, "/.rockbox/patchset/patchset.cfg", "/.rockbox/patchset/drums.cfg") == -1)
- {
- return -1;
- }
+ rb->splash(HZ/5, true, "LOADING PATCHES");
+ if (initSynth(mf, "/.rockbox/patchset/patchset.cfg", "/.rockbox/patchset/drums.cfg") == -1)
+ {
+ 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;
+ fd=rb->open("/dsp.raw", O_WRONLY);
+ int arg, status;
+ int bit, samp, ch;
- arg = 16; // sample size
- status = ioctl(fd, SOUND_PCM_WRITE_BITS, &arg);
- status = ioctl(fd, SOUND_PCM_READ_BITS, &arg);
- bit=arg;
+ 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
- status = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &arg);
- status = ioctl(fd, SOUND_PCM_READ_CHANNELS, &arg);
- ch=arg;
+ 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
- status = ioctl(fd, SOUND_PCM_WRITE_RATE, &arg);
- status = ioctl(fd, SOUND_PCM_READ_RATE, &arg);
- samp=arg;
+ arg = SAMPLE_RATE; /* Yeah. sampling rate */
+ status = ioctl(fd, SOUND_PCM_WRITE_RATE, &arg);
+ status = ioctl(fd, SOUND_PCM_READ_RATE, &arg);
+ samp=arg;
#else
- file_info_struct file_info;
- file_info.samplerate = SAMPLE_RATE;
- file_info.infile = fd;
- file_info.channels = 2;
- file_info.bitspersample = 16;
- local_init("/miditest.tmp", "/miditest.wav", &file_info, rb);
- fd = file_info.outfile;
+ file_info_struct file_info;
+ file_info.samplerate = SAMPLE_RATE;
+ file_info.infile = fd;
+ file_info.channels = 2;
+ file_info.bitspersample = 16;
+ local_init("/miditest.tmp", "/miditest.wav", &file_info, rb);
+ fd = file_info.outfile;
#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");
- printf("\nOkay, starting sequencing");
+ currentSample=0; /* Sample counting variable */
+ outputBufferPosition = 0;
- currentSample=0; //Sample counting variable
- outputBufferPosition = 0;
+ bpm=mf->div*1000000/tempo;
+ numberOfSamples=SAMPLE_RATE/bpm;
- bpm=mf->div*1000000/tempo;
- numberOfSamples=SAMPLE_RATE/bpm;
+ /* Tick() will return 0 if there are no more events left to play */
+ while(tick(mf))
+ {
+ /*
+ * Tempo recalculation moved to sequencer.c to be done on a tempo event only
+ *
+ */
+ for(currentSample=0; currentSample<numberOfSamples; currentSample++)
+ {
+ synthSample(&outputSampleOne, &outputSampleTwo);
- //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.
+ /*
+ * 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.
+ */
- //Yes we need to do this math each time because the tempo
- //could have changed.
+ outputBuffer[outputBufferPosition]=outputSampleOne&0XFF; // Low byte first
+ outputBufferPosition++;
+ outputBuffer[outputBufferPosition]=outputSampleOne>>8; //High byte second
+ outputBufferPosition++;
- // On second thought, this can be moved to the event that
- //recalculates the tempo, to save a little bit of CPU time.
- for(currentSample=0; currentSample<numberOfSamples; currentSample++)
- {
+ outputBuffer[outputBufferPosition]=outputSampleTwo&0XFF; // Low byte first
+ outputBufferPosition++;
+ outputBuffer[outputBufferPosition]=outputSampleTwo>>8; //High byte second
+ outputBufferPosition++;
- synthSample(&outputSampleOne, &outputSampleTwo);
+ /*
+ * 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);
+ outputBufferPosition=0;
+ }
+ }
+ }
- //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
- outputBufferPosition++;
-
- outputBuffer[outputBufferPosition]=outputSampleTwo&0XFF; // Low byte first
- outputBufferPosition++;
- outputBuffer[outputBufferPosition]=outputSampleTwo>>8; //High byte second
- 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.
- if(outputBufferPosition>=2000)
- {
- rb->write(fd, outputBuffer, 2000);
- outputBufferPosition=0;
- }
- }
- }
-
-// unloadFile(mf);
- printf("\n");
+ printf("\n");
#if !defined(LOCAL_DSP)
- close_wav(&file_info);
+ close_wav(&file_info);
#else
- rb->close(fd);
+ rb->close(fd);
#endif
- return 0;
+ return 0;
}