From 9ec1ff8cf5230b502c4f45be39fe75990ce842f1 Mon Sep 17 00:00:00 2001 From: Stepan Moskovchenko Date: Wed, 20 Apr 2005 21:07:13 +0000 Subject: 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 --- apps/plugins/midi/guspat.c | 327 ++++++++++----------- apps/plugins/midi/guspat.h | 94 +++--- apps/plugins/midi/midifile.c | 427 ++++++++++++++------------- apps/plugins/midi/midiutil.c | 222 +++++++-------- apps/plugins/midi/sequencer.c | 470 +++++++++++++++--------------- apps/plugins/midi/synth.c | 650 +++++++++++++++++++++--------------------- apps/plugins/midi2wav.c | 231 +++++++-------- 7 files changed, 1181 insertions(+), 1240 deletions(-) (limited to 'apps/plugins') 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; awavSize; 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; awavSize/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; awavSize; 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; anumSamples; 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; anumSamples; 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; anumWaveforms; 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; anumWaveforms; 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; anumWaves; 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; anumWaves; 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; alen; 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; alen; 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; anumTracks; a++) - { - int b=0; - - if(mf->tracks[a] != NULL) - for(b=0; btracks[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; anumTracks; a++) + { + int b=0; + + if(mf->tracks[a] != NULL) + for(b=0; btracks[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 %d", ch, chPW[ch], msb); + chPW[ch] = msb; + + int a=0; + for(a = 0; arootFreq; - 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; awaveforms[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; amode & 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; amode & 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; anumTracks; 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; anumTracks; 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; anumTracks; 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; tstracks[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; anumTracks; 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; tstracks[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>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>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 #include #include #include #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>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>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; } -- cgit