summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStepan Moskovchenko <stevenm@rockbox.org>2005-04-20 21:07:13 +0000
committerStepan Moskovchenko <stevenm@rockbox.org>2005-04-20 21:07:13 +0000
commit9ec1ff8cf5230b502c4f45be39fe75990ce842f1 (patch)
tree98fe264f4d67054164df8b3637e8440da32fc26a
parent74e9d545ef46111fcbd71073becc8b04b8fbca27 (diff)
downloadrockbox-9ec1ff8cf5230b502c4f45be39fe75990ce842f1.tar.gz
rockbox-9ec1ff8cf5230b502c4f45be39fe75990ce842f1.zip
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
-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;
21 21
22unsigned int readWord(int file) 22unsigned int readWord(int file)
23{ 23{
24 return (readChar(file)<<0) | (readChar(file)<<8); // | (readChar(file)<<8) | (readChar(file)<<0); 24 return (readChar(file)<<0) | (readChar(file)<<8); // | (readChar(file)<<8) | (readChar(file)<<0);
25} 25}
26 26
27unsigned int readDWord(int file) 27unsigned int readDWord(int file)
28{ 28{
29 return (readChar(file)<<0) | (readChar(file)<<8) | (readChar(file)<<16) | (readChar(file)<<24); 29 return (readChar(file)<<0) | (readChar(file)<<8) | (readChar(file)<<16) | (readChar(file)<<24);
30} 30}
31 31
32struct GWaveform * loadWaveform(int file) 32struct GWaveform * loadWaveform(int file)
33{ 33{
34 struct GWaveform * wav = (struct GWaveform *)allocate(sizeof(struct GWaveform)); 34 struct GWaveform * wav = (struct GWaveform *)allocate(sizeof(struct GWaveform));
35 rb->memset(wav, 0, sizeof(struct GWaveform)); 35 rb->memset(wav, 0, sizeof(struct GWaveform));
36 36
37 wav->name=readData(file, 7); 37 wav->name=readData(file, 7);
38 printf("\nWAVE NAME = [%s]", wav->name); 38 printf("\nWAVE NAME = [%s]", wav->name);
39 wav->fractions=readChar(file); 39 wav->fractions=readChar(file);
40 wav->wavSize=readDWord(file); 40 wav->wavSize=readDWord(file);
41 wav->startLoop=readDWord(file); 41 wav->startLoop=readDWord(file);
42 wav->endLoop=readDWord(file); 42 wav->endLoop=readDWord(file);
43 wav->sampRate=readWord(file); 43 wav->sampRate=readWord(file);
44 44
45 wav->lowFreq=readDWord(file); 45 wav->lowFreq=readDWord(file);
46 wav->highFreq=readDWord(file); 46 wav->highFreq=readDWord(file);
47 wav->rootFreq=readDWord(file); 47 wav->rootFreq=readDWord(file);
48 48
49 wav->tune=readWord(file); 49 wav->tune=readWord(file);
50 50
51 wav->balance=readChar(file); 51 wav->balance=readChar(file);
52 wav->envRate=readData(file, 6); 52 wav->envRate=readData(file, 6);
53 wav->envOffset=readData(file, 6); 53 wav->envOffset=readData(file, 6);
54 54
55 wav->tremSweep=readChar(file); 55 wav->tremSweep=readChar(file);
56 wav->tremRate==readChar(file); 56 wav->tremRate==readChar(file);
57 wav->tremDepth=readChar(file); 57 wav->tremDepth=readChar(file);
58 wav->vibSweep=readChar(file); 58 wav->vibSweep=readChar(file);
59 wav->vibRate=readChar(file); 59 wav->vibRate=readChar(file);
60 wav->vibDepth=readChar(file); 60 wav->vibDepth=readChar(file);
61 wav->mode=readChar(file); 61 wav->mode=readChar(file);
62 62
63 wav->scaleFreq=readWord(file); 63 wav->scaleFreq=readWord(file);
64 wav->scaleFactor=readWord(file); 64 wav->scaleFactor=readWord(file);
65 printf("\nScaleFreq = %d ScaleFactor = %d RootFreq = %d", wav->scaleFreq, wav->scaleFactor, wav->rootFreq); 65 printf("\nScaleFreq = %d ScaleFactor = %d RootFreq = %d", wav->scaleFreq, wav->scaleFactor, wav->rootFreq);
66 wav->res=readData(file, 36); 66 wav->res=readData(file, 36);
67 wav->data=readData(file, wav->wavSize); 67 wav->data=readData(file, wav->wavSize);
68 68
69 wav->numSamples = wav->wavSize / 2; 69 wav->numSamples = wav->wavSize / 2;
70 int a=0; 70 wav->startLoop = wav->startLoop >> 1;
71 71 wav->endLoop = wav->endLoop >> 1;
72 return wav; 72 unsigned int a=0;
73 if(wav->mode & 1 == 0) //Whoops, 8 bit 73
74 { 74 /* half baked 8 bit conversion UNFINISHED*/
75 wav->numSamples = wav->wavSize; 75 /*
76 76 if(wav->mode & 1 == 0) //Whoops, 8 bit
77 //Allocate a block for the rest of it 77 {
78 //It should end up right after the previous one. 78 wav->numSamples = wav->wavSize;
79 wav->wavSize = wav->wavSize * 2; 79
80 void * foo = allocate(wav->wavSize); 80 //Allocate a block for the rest of it
81 81 //It should end up right after the previous one.
82 82 wav->wavSize = wav->wavSize * 2;
83 for(a=0; a<1000; a++) 83 void * foo = allocate(wav->wavSize);
84 printf("\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); 84
85 85
86 86 for(a=0; a<1000; a++)
87 for(a=wav->wavSize-1; a>0; a-=2) 87 printf("\n!!!!!!!!!!!!!!!!!!!!!!!!!!!");
88 { 88
89 89
90 } 90 for(a=wav->wavSize-1; a>0; a-=2)
91 // int b1=wf->data[s]+((wf->mode & 2) << 6); 91 {
92 // return b1<<8; 92
93 } 93 }
94 94 // int b1=wf->data[s]+((wf->mode & 2) << 6);
95 /* 95 // return b1<<8;
96//#if !defined(SIMULATOR) 96 }
97 for(a=0; a<wav->wavSize; a+=2) 97 */
98 { 98
99 unsigned char tmp; 99
100 tmp = wav->data[2*a]; 100 /* Iriver needs byteswapping.. big endian, go figure. Gus files are little endian */
101 wav->data[2*a] = wav->data[2*a+1]; 101
102 wav->data[2*a+1] = tmp; 102#if !defined(SIMULATOR)
103 } 103 for(a=0; a<wav->numSamples; a++)
104//#endif 104 {
105 105 ((unsigned short *) wav->data)[a] = SWAB16(((unsigned short *) wav->data)[a]);
106 if(wav->mode & 2) 106 }
107 { 107#endif
108 for(a=0; a<wav->wavSize/2; a++) 108
109 { 109 /* Convert unsigned to signed by subtracting 32768 */
110 ((short *) wav->data)[a] = ((short *) wav->data)[a] - 32767; 110 if(wav->mode & 2)
111 } 111 {
112 } 112 for(a=0; a<wav->numSamples; a++)
113*/ 113 ((short *) wav->data)[a] = ((unsigned short *) wav->data)[a] - 32768;
114 114
115 115 }
116 116
117 //If we have a 16 bit waveform 117 return wav;
118/* if(wav->mode & 1 && (wav->mode & 2))
119 {
120 for(a=0; a<wav->wavSize; a+=2) //Convert it to
121 {
122 wav->data[a]=wav->data[a]+(1 << 7);
123 wav->data[a|1]=wav->data[(a)|1]+(1 << 7);
124 }
125 }
126*/
127 return wav;
128} 118}
129 119
130 120
131 121
132int selectWaveform(struct GPatch * pat, int midiNote) 122int selectWaveform(struct GPatch * pat, int midiNote)
133{ 123{
134 int tabFreq = gustable[midiNote]/100; //Comparison 124 /* We divide by 100 here because everyone's freq formula is slightly different */
135 int a=0; 125 unsigned int tabFreq = gustable[midiNote]/100; /* Comparison */
136 for(a=0; a<pat->numWaveforms; a++) 126 unsigned int a=0;
137 { 127 for(a=0; a<pat->numWaveforms; a++)
138 if(pat->waveforms[a]->lowFreq/100 <= tabFreq && 128 {
139 pat->waveforms[a]->highFreq/100 >= tabFreq) 129 if(pat->waveforms[a]->lowFreq/100 <= tabFreq &&
140 { 130 pat->waveforms[a]->highFreq/100 >= tabFreq)
141 return a; 131 {
142 } 132 return a;
143 } 133 }
144 return 0; 134 }
135 return 0;
145} 136}
146 137
147 138
148struct GPatch * gusload(char * filename) 139struct GPatch * gusload(char * filename)
149{ 140{
150 struct GPatch * gp = (struct GPatch *)allocate(sizeof(struct GPatch)); 141 struct GPatch * gp = (struct GPatch *)allocate(sizeof(struct GPatch));
151 rb->memset(gp, 0, sizeof(struct GPatch)); 142 rb->memset(gp, 0, sizeof(struct GPatch));
152 143
153 int file = rb->open(filename, O_RDONLY); 144 int file = rb->open(filename, O_RDONLY);
154 145
155 if(file == -1) 146 if(file == -1)
156 { 147 {
157 char message[50]; 148 char message[50];
158 rb->snprintf(message, 50, "Error opening %s", filename); 149 rb->snprintf(message, 50, "Error opening %s", filename);
159 rb->splash(HZ*2, true, message); 150 rb->splash(HZ*2, true, message);
160 return NULL; 151 return NULL;
161 } 152 }
162 153
163 gp->header=readData(file, 12); 154 gp->header=readData(file, 12);
164 gp->gravisid=readData(file, 10); 155 gp->gravisid=readData(file, 10);
165 gp->desc=readData(file, 60); 156 gp->desc=readData(file, 60);
166 gp->inst=readChar(file); 157 gp->inst=readChar(file);
167 gp->voc=readChar(file); 158 gp->voc=readChar(file);
168 gp->chan=readChar(file); 159 gp->chan=readChar(file);
169 gp->numWaveforms=readWord(file); //readWord(file); 160 gp->numWaveforms=readWord(file);
170 gp->vol=readWord(file); 161 gp->vol=readWord(file);
171 gp->datSize=readDWord(file); 162 gp->datSize=readDWord(file);
172 gp->res=readData(file, 36); 163 gp->res=readData(file, 36);
173 164
174 gp->instrID=readWord(file); 165 gp->instrID=readWord(file);
175 gp->instrName=readData(file,16); 166 gp->instrName=readData(file,16);
176 gp->instrSize=readDWord(file); 167 gp->instrSize=readDWord(file);
177 gp->layers=readChar(file); 168 gp->layers=readChar(file);
178 gp->instrRes=readData(file,40); 169 gp->instrRes=readData(file,40);
179 170
180 171
181 gp->layerDup=readChar(file); 172 gp->layerDup=readChar(file);
182 gp->layerID=readChar(file); 173 gp->layerID=readChar(file);
183 gp->layerSize=readDWord(file); 174 gp->layerSize=readDWord(file);
184 gp->numWaves=readChar(file); 175 gp->numWaves=readChar(file);
185 gp->layerRes=readData(file,40); 176 gp->layerRes=readData(file,40);
186 177
187/* printf("\n%s\n%s\n%s", gp->header, gp->gravisid, gp->desc); 178
188 printf("\nInst = %d", gp->inst); 179 printf("\nFILE: %s", filename);
189 printf("\nVoc = %d", gp->voc); 180 printf("\nlayerSamples=%d", gp->numWaves);
190 printf("\nChan = %d", gp->chan); 181
191 printf("\nWav = %d", gp->numWaveforms); 182 int a=0;
192 printf("\nVol = %d", gp->vol); 183 for(a=0; a<gp->numWaves; a++)
193 printf("\nSize = %d", gp->datSize); 184 gp->waveforms[a] = loadWaveform(file);
194 185
195 printf("\n\ninstrID = %d", gp->instrID); 186
196 printf("\ninstrName = %s", gp->instrName); 187 printf("\nPrecomputing note table");
197// printf("\ninstrSize = %d", gp->instrSize); 188
198// printf("\nlayers = %d", gp->layers); 189 for(a=0; a<128; a++)
199*/ 190 {
200 printf("\nFILE: %s", filename); 191 gp->noteTable[a] = selectWaveform(gp, a);
201 printf("\nlayerSamples=%d", gp->numWaves); 192 }
202 193 rb->close(file);
203 int a=0; 194
204 for(a=0; a<gp->numWaves; a++) 195 return gp;
205 gp->waveforms[a] = loadWaveform(file);
206
207
208 printf("\nPrecomputing note table");
209
210 for(a=0; a<128; a++)
211 {
212 gp->noteTable[a] = selectWaveform(gp, a);
213 }
214 rb->close(file);
215
216 return gp;
217} 196}
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 @@
16 * 16 *
17 ****************************************************************************/ 17 ****************************************************************************/
18 18
19//This came from one of the Gravis documents 19/* This came from one of the Gravis documents */
20static const unsigned int gustable[]= 20static const unsigned int gustable[]=
21{ 21{
22 8175, 8661, 9177, 9722, 10300, 10913, 11562, 12249, 12978, 13750, 14567, 15433, 22 8175, 8661, 9177, 9722, 10300, 10913, 11562, 12249, 12978, 13750, 14567, 15433,
@@ -33,63 +33,63 @@ static const unsigned int gustable[]=
33 33
34struct GWaveform 34struct GWaveform
35{ 35{
36 unsigned char * name; 36 unsigned char * name;
37 unsigned char fractions; 37 unsigned char fractions;
38 unsigned int wavSize; 38 unsigned int wavSize;
39 unsigned int numSamples; 39 unsigned int numSamples;
40 unsigned int startLoop; 40 unsigned int startLoop;
41 unsigned int endLoop; 41 unsigned int endLoop;
42 unsigned int sampRate; 42 unsigned int sampRate;
43 unsigned int lowFreq; 43 unsigned int lowFreq;
44 unsigned int highFreq; 44 unsigned int highFreq;
45 unsigned int rootFreq; 45 unsigned int rootFreq;
46 unsigned int tune; 46 unsigned int tune;
47 unsigned int balance; 47 unsigned int balance;
48 unsigned char * envRate; 48 unsigned char * envRate;
49 unsigned char * envOffset; 49 unsigned char * envOffset;
50 50
51 unsigned char tremSweep; 51 unsigned char tremSweep;
52 unsigned char tremRate; 52 unsigned char tremRate;
53 unsigned char tremDepth; 53 unsigned char tremDepth;
54 unsigned char vibSweep; 54 unsigned char vibSweep;
55 unsigned char vibRate; 55 unsigned char vibRate;
56 unsigned char vibDepth; 56 unsigned char vibDepth;
57 unsigned char mode; 57 unsigned char mode;
58 58
59 unsigned int scaleFreq; 59 unsigned int scaleFreq;
60 unsigned int scaleFactor; 60 unsigned int scaleFactor;
61 61
62 unsigned char * res; 62 unsigned char * res;
63 signed char * data; 63 signed char * data;
64}; 64};
65 65
66 66
67struct GPatch 67struct GPatch
68{ 68{
69 unsigned int patchNumber; 69 unsigned int patchNumber;
70 unsigned char * header; 70 unsigned char * header;
71 unsigned char * gravisid; 71 unsigned char * gravisid;
72 unsigned char * desc; 72 unsigned char * desc;
73 unsigned char inst, voc, chan; 73 unsigned char inst, voc, chan;
74 unsigned int numWaveforms; 74 unsigned int numWaveforms;
75 unsigned int datSize; 75 unsigned int datSize;
76 unsigned int vol; 76 unsigned int vol;
77 unsigned char * res; 77 unsigned char * res;
78 78
79 79
80 unsigned int instrID; 80 unsigned int instrID;
81 unsigned char * instrName; 81 unsigned char * instrName;
82 unsigned int instrSize; 82 unsigned int instrSize;
83 unsigned int layers; 83 unsigned int layers;
84 unsigned char * instrRes; 84 unsigned char * instrRes;
85 85
86 unsigned char layerDup; 86 unsigned char layerDup;
87 unsigned char layerID; 87 unsigned char layerID;
88 unsigned int layerSize; 88 unsigned int layerSize;
89 unsigned char numWaves; 89 unsigned char numWaves;
90 unsigned char * layerRes; 90 unsigned char * layerRes;
91 91
92 unsigned char noteTable[128]; 92 unsigned char noteTable[128];
93 struct GWaveform * waveforms[255]; 93 struct GWaveform * waveforms[255];
94}; 94};
95 95
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 *);
26 26
27struct MIDIfile * loadFile(char * filename) 27struct MIDIfile * loadFile(char * filename)
28{ 28{
29 struct MIDIfile * mf; 29 struct MIDIfile * mf;
30 int file = rb->open (filename, O_RDONLY); 30 int file = rb->open (filename, O_RDONLY);
31 31
32 if(file==0) 32 if(file==-1)
33 { 33 {
34 bail("Could not open file\n"); 34 bail("Could not open file\n");
35 } 35 }
36 36
37 mf = (struct MIDIfile*)allocate(sizeof(struct MIDIfile)); 37 mf = (struct MIDIfile*)allocate(sizeof(struct MIDIfile));
38 38
39 if(mf==NULL) 39 if(mf==NULL)
40 { 40 {
41 rb->close(file); 41 rb->close(file);
42 bail("Could not allocate memory for MIDIfile struct\n"); 42 bail("Could not allocate memory for MIDIfile struct\n");
43 } 43 }
44 44
45 rb->memset(mf, 0, sizeof(struct MIDIfile)); 45 rb->memset(mf, 0, sizeof(struct MIDIfile));
46 46
47 if(readID(file) != ID_MTHD) 47 if(readID(file) != ID_MTHD)
48 { 48 {
49 rb->close(file); 49 rb->close(file);
50 bail("Invalid file header chunk."); 50 bail("Invalid file header chunk.");
51 } 51 }
52 52
53 if(readFourBytes(file)!=6) 53 if(readFourBytes(file)!=6)
54 { 54 {
55 rb->close(file); 55 rb->close(file);
56 bail("Header chunk size invalid."); 56 bail("Header chunk size invalid.");
57 } 57 }
58 58
59 if(readTwoBytes(file)==2) 59 if(readTwoBytes(file)==2)
60 { 60 {
61 rb->close(file); 61 rb->close(file);
62 bail("MIDI file type not supported"); 62 bail("MIDI file type not supported");
63 } 63 }
64 64
65 mf->numTracks = readTwoBytes(file); 65 mf->numTracks = readTwoBytes(file);
66 mf->div = readTwoBytes(file); 66 mf->div = readTwoBytes(file);
67 67
68 int track=0; 68 int track=0;
69 69
70 printf("\nnumTracks=%d div=%d\nBegin reading track data\n", mf->numTracks, mf->div); 70 printf("\nnumTracks=%d div=%d\nBegin reading track data\n", mf->numTracks, mf->div);
71 71
72// return; 72
73 73 while(! eof(file) && track < mf->numTracks)
74 74 {
75 while(! eof(file) && track < mf->numTracks) 75 unsigned char id = readID(file);
76 { 76
77 unsigned char id = readID(file); 77
78 78 if(id == ID_EOF)
79 79 {
80 if(id == ID_EOF) 80 if(mf->numTracks != track)
81 { 81 {
82 if(mf->numTracks != track) 82 printf("\nError: file claims to have %d tracks.\n I only see %d here.\n", mf->numTracks, track);
83 { 83 mf->numTracks = track;
84 printf("\nError: file claims to have %d tracks.\n I only see %d here.\n", mf->numTracks, track); 84 }
85 mf->numTracks = track; 85 return mf;
86 } 86 }
87 return mf; 87
88 } 88 if(id == ID_MTRK)
89 89 {
90 if(id == ID_MTRK) 90 mf->tracks[track] = readTrack(file);
91 { 91 //exit(0);
92 mf->tracks[track] = readTrack(file); 92 track++;
93 //exit(0); 93 } else
94 track++; 94 {
95 } else 95 printf("\n SKIPPING TRACK");
96 { 96 int len = readFourBytes(file);
97 printf("\n SKIPPING TRACK"); 97 while(--len)
98 int len = readFourBytes(file); 98 readChar(file);
99 while(--len) 99 }
100 readChar(file); 100 }
101 } 101 return mf;
102 }
103 return mf;
104 102
105} 103}
106 104
107 105
108int rStatus = 0; 106int rStatus = 0;
109 107
110//Returns 0 if done, 1 if keep going 108/* Returns 0 if done, 1 if keep going */
111int readEvent(int file, void * dest) 109int readEvent(int file, void * dest)
112{ 110{
113 struct Event dummy; 111 struct Event dummy;
114 struct Event * ev = (struct Event *) dest; 112 struct Event * ev = (struct Event *) dest;
115 113
116 if(ev == NULL) 114 if(ev == NULL)
117 ev = &dummy; //If we are just counting events instead of loading them 115 ev = &dummy; /* If we are just counting events instead of loading them */
118 116
119 ev->delta = readVarData(file); 117 ev->delta = readVarData(file);
120 118
121 119
122 int t=readChar(file); 120 int t=readChar(file);
123 121
124 if((t&0x80) == 0x80) //if not a running status event 122 if((t&0x80) == 0x80) /* if not a running status event */
125 { 123 {
126 ev->status = t; 124 ev->status = t;
127 if(t == 0xFF) 125 if(t == 0xFF)
128 { 126 {
129 ev->d1 = readChar(file); 127 ev->d1 = readChar(file);
130 ev->len = readVarData(file); 128 ev->len = readVarData(file);
131 129
132 //Allocate and read in the data block 130 /* Allocate and read in the data block */
133 if(dest != NULL) 131 if(dest != NULL)
134 { 132 {
135 ev->evData = readData(file, ev->len); 133 ev->evData = readData(file, ev->len);
136 printf("\nDATA: <%s>", ev->evData); 134 printf("\nDATA: <%s>", ev->evData);
137 } 135 }
138 else 136 else
139 { 137 {
140 //Don't allocate anything, just see how much it would tale 138 /*
141 //To make memory usage efficient 139 * Don't allocate anything, just see how much it would tale
142 140 * To make memory usage efficient
143 int a=0; 141 */
144 for(a=0; a<ev->len; a++) 142 unsigned int a=0;
145 readChar(file); //Skip skip 143 for(a=0; a<ev->len; a++)
146 } 144 readChar(file); //Skip skip
147 145 }
148 if(ev->d1 == 0x2F) 146
149 { 147 if(ev->d1 == 0x2F)
150 return 0; //Termination meta-event 148 {
151 } 149 return 0; /* Termination meta-event */
152 } else //If part of a running status event 150 }
153 { 151 } else /* If part of a running status event */
154 rStatus = t; 152 {
155 ev->status = t; 153 rStatus = t;
156 ev->d1 = readChar(file); 154 ev->status = t;
157 155 ev->d1 = readChar(file);
158 if ( ((t & 0xF0) != 0xD0) && ((t & 0xF0) != 0xC0) && ((t & 0xF0) > 0x40) ) 156
159 { 157 if ( ((t & 0xF0) != 0xD0) && ((t & 0xF0) != 0xC0) && ((t & 0xF0) > 0x40) )
160 ev->d2 = readChar(file); 158 {
161 } else 159 ev->d2 = readChar(file);
162 ev->d2 = 127; 160 } else
163 } 161 ev->d2 = 127;
164 } else //Running Status 162 }
165 { 163 } else /* Running Status */
166 ev->status = rStatus; 164 {
167 ev->d1 = t; 165 ev->status = rStatus;
168 if ( ((rStatus & 0xF0) != 0xD0) && ((rStatus & 0xF0) != 0xC0) && ((rStatus & 0xF0) > 0x40) ) 166 ev->d1 = t;
169 { 167 if ( ((rStatus & 0xF0) != 0xD0) && ((rStatus & 0xF0) != 0xC0) && ((rStatus & 0xF0) > 0x40) )
170 ev->d2 = readChar(file); 168 {
171 } else 169 ev->d2 = readChar(file);
172 ev->d2 = 127; 170 } else
173 } 171 ev->d2 = 127;
174 return 1; 172 }
173 return 1;
175} 174}
176 175
177 176
178 177
179struct Track * readTrack(int file) 178struct Track * readTrack(int file)
180{ 179{
181 struct Track * trk = (struct Track *)allocate(sizeof(struct Track)); 180 struct Track * trk = (struct Track *)allocate(sizeof(struct Track));
182 rb->memset(trk, 0, sizeof(struct Track)); 181 rb->memset(trk, 0, sizeof(struct Track));
183 182
184 trk->size = readFourBytes(file); 183 trk->size = readFourBytes(file);
185 trk->pos = 0; 184 trk->pos = 0;
186 trk->delta = 0; 185 trk->delta = 0;
187 186
188 int numEvents=0; 187 int numEvents=0;
189 188
190 int pos = rb->lseek(file, 0, SEEK_CUR); 189 int pos = rb->lseek(file, 0, SEEK_CUR);
191 190
192 while(readEvent(file, NULL)) //Memory saving technique 191 while(readEvent(file, NULL)) /* Memory saving technique */
193 numEvents++; //Attempt to read in events, count how many 192 numEvents++; /* Attempt to read in events, count how many */
194 //THEN allocate memory and read them in 193 /* THEN allocate memory and read them in */
195 rb->lseek(file, pos, SEEK_SET); 194 rb->lseek(file, pos, SEEK_SET);
196 195
197 int trackSize = (numEvents+1) * sizeof(struct Event); 196 int trackSize = (numEvents+1) * sizeof(struct Event);
198 void * dataPtr = allocate(trackSize); 197 void * dataPtr = allocate(trackSize);
199 trk->dataBlock = dataPtr; 198 trk->dataBlock = dataPtr;
200 199
201 numEvents=0; 200 numEvents=0;
202 201
203 while(readEvent(file, dataPtr)) 202 while(readEvent(file, dataPtr))
204 { 203 {
205 if(trackSize < dataPtr-trk->dataBlock) 204 if(trackSize < dataPtr-trk->dataBlock)
206 { 205 {
207 printf("\nTrack parser memory out of bounds"); 206 printf("\nTrack parser memory out of bounds");
208 exit(1); 207 exit(1);
209 } 208 }
210 dataPtr+=sizeof(struct Event); 209 dataPtr+=sizeof(struct Event);
211 numEvents++; 210 numEvents++;
212 } 211 }
213 trk->numEvents = numEvents; 212 trk->numEvents = numEvents;
214 213
215 return trk; 214 return trk;
216} 215}
217 216
218 217
219int readID(int file) 218int readID(int file)
220{ 219{
221 char id[5]; 220 char id[5];
222 id[4]=0; 221 id[4]=0;
223 BYTE a; 222 BYTE a;
224 223
225 for(a=0; a<4; a++) 224 for(a=0; a<4; a++)
226 id[a]=readChar(file); 225 id[a]=readChar(file);
227 if(eof(file)) 226 if(eof(file))
228 { 227 {
229 printf("\End of file reached."); 228 printf("\End of file reached.");
230 return ID_EOF; 229 return ID_EOF;
231 } 230 }
232 if(rb->strcmp(id, "MThd")==0) 231 if(rb->strcmp(id, "MThd")==0)
233 return ID_MTHD; 232 return ID_MTHD;
234 if(rb->strcmp(id, "MTrk")==0) 233 if(rb->strcmp(id, "MTrk")==0)
235 return ID_MTRK; 234 return ID_MTRK;
236 return ID_UNKNOWN; 235 return ID_UNKNOWN;
237} 236}
238 237
239 238
240int readFourBytes(int file) 239int readFourBytes(int file)
241{ 240{
242 int data=0; 241 int data=0;
243 BYTE a=0; 242 BYTE a=0;
244 for(a=0; a<4; a++) 243 for(a=0; a<4; a++)
245 data=(data<<8)+readChar(file); 244 data=(data<<8)+readChar(file);
246 return data; 245 return data;
247} 246}
248 247
249int readTwoBytes(int file) 248int readTwoBytes(int file)
250{ 249{
251 int data=(readChar(file)<<8)+readChar(file); 250 int data=(readChar(file)<<8)+readChar(file);
252 return data; 251 return data;
253} 252}
254 253
255//This came from the MIDI file format guide 254/* This came from the MIDI file format guide */
256int readVarData(int file) 255int readVarData(int file)
257{ 256{
258 unsigned int value; 257 unsigned int value;
@@ -270,37 +269,35 @@ int readVarData(int file)
270 269
271 270
272/* 271/*
273//This function should not be needed because we
274//can just release the whole memory buffer at once
275void unloadFile(struct MIDIfile * mf) 272void unloadFile(struct MIDIfile * mf)
276{ 273{
277 if(mf == NULL) 274 if(mf == NULL)
278 return; 275 return;
279 int a=0; 276 int a=0;
280 //Unload each track 277 //Unload each track
281 for(a=0; a<mf->numTracks; a++) 278 for(a=0; a<mf->numTracks; a++)
282 { 279 {
283 int b=0; 280 int b=0;
284 281
285 if(mf->tracks[a] != NULL) 282 if(mf->tracks[a] != NULL)
286 for(b=0; b<mf->tracks[a]->numEvents; b++) 283 for(b=0; b<mf->tracks[a]->numEvents; b++)
287 { 284 {
288 if(((struct Event*)((mf->tracks[a]->dataBlock)+b*sizeof(struct Event)))->evData!=NULL) 285 if(((struct Event*)((mf->tracks[a]->dataBlock)+b*sizeof(struct Event)))->evData!=NULL)
289 free(((struct Event*)((mf->tracks[a]->dataBlock)+b*sizeof(struct Event)))->evData); 286 free(((struct Event*)((mf->tracks[a]->dataBlock)+b*sizeof(struct Event)))->evData);
290 } 287 }
291 288
292 if(mf->tracks[a]!=NULL && mf->tracks[a]->dataBlock != NULL) 289 if(mf->tracks[a]!=NULL && mf->tracks[a]->dataBlock != NULL)
293 free(mf->tracks[a]->dataBlock); //Unload the event block 290 free(mf->tracks[a]->dataBlock); //Unload the event block
294 291
295 if(mf->tracks[a]!=NULL) 292 if(mf->tracks[a]!=NULL)
296 free(mf->tracks[a]); //Unload the track structure itself 293 free(mf->tracks[a]); //Unload the track structure itself
297 } 294 }
298 free(mf); //Unload the main struct 295 free(mf); //Unload the main struct
299} 296}
300*/ 297*/
301void bail(const char * err) 298void bail(const char * err)
302{ 299{
303 rb->splash(HZ*3, true, err); 300 rb->splash(HZ*3, true, err);
304 exit(0); 301 exit(0);
305} 302}
306 303
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 @@
20#define BYTE unsigned char 20#define BYTE unsigned char
21 21
22//Data chunk ID types, returned by readID() 22//Data chunk ID types, returned by readID()
23#define ID_UNKNOWN -1 23#define ID_UNKNOWN -1
24#define ID_MTHD 1 24#define ID_MTHD 1
25#define ID_MTRK 2 25#define ID_MTRK 2
26#define ID_EOF 3 26#define ID_EOF 3
27 27
28//MIDI Commands 28//MIDI Commands
29#define MIDI_NOTE_OFF 128 29#define MIDI_NOTE_OFF 128
30#define MIDI_NOTE_ON 144 30#define MIDI_NOTE_ON 144
31#define MIDI_AFTERTOUCH 160 31#define MIDI_AFTERTOUCH 160
32#define MIDI_CONTROL 176 32#define MIDI_CONTROL 176
33#define MIDI_PRGM 192 33#define MIDI_PRGM 192
34#define MIDI_PITCHW 224 34#define MIDI_PITCHW 224
35 35
36 36
37//MIDI Controllers 37//MIDI Controllers
38#define CTRL_VOLUME 7 38#define CTRL_VOLUME 7
39#define CTRL_BALANCE 8 39#define CTRL_BALANCE 8
40#define CTRL_PANNING 10 40#define CTRL_PANNING 10
41#define CHANNEL 1 41#define CHANNEL 1
42 42
43//Most of these are deprecated.. rampdown is used, maybe one other one too 43//Most of these are deprecated.. rampdown is used, maybe one other one too
44#define STATE_ATTACK 1 44#define STATE_ATTACK 1
45#define STATE_DECAY 2 45#define STATE_DECAY 2
46#define STATE_SUSTAIN 3 46#define STATE_SUSTAIN 3
47#define STATE_RELEASE 4 47#define STATE_RELEASE 4
48#define STATE_RAMPDOWN 5 48#define STATE_RAMPDOWN 5
49 49
50//Loop states 50//Loop states
51#define STATE_LOOPING 7 51#define STATE_LOOPING 7
52#define STATE_NONLOOPING 8 52#define STATE_NONLOOPING 8
53 53
54//Various bits in the GUS mode byte 54//Various bits in the GUS mode byte
55#define LOOP_ENABLED 4 55#define LOOP_ENABLED 4
56#define LOOP_PINGPONG 8 56#define LOOP_PINGPONG 8
57#define LOOP_REVERSE 16 57#define LOOP_REVERSE 16
58 58
@@ -63,81 +63,69 @@
63extern struct plugin_api * rb; 63extern struct plugin_api * rb;
64 64
65 65
66int chVol[16] IDATA_ATTR; //Channel volume 66int chVol[16] IDATA_ATTR; /* Channel volume */
67int chPanLeft[16] IDATA_ATTR; //Channel panning 67int chPanLeft[16] IDATA_ATTR; /* Channel panning */
68int chPanRight[16] IDATA_ATTR; 68int chPanRight[16] IDATA_ATTR;
69int chPat[16]; //Channel patch 69int chPat[16]; /* Channel patch */
70int chPW[16]; //Channel pitch wheel, MSB only 70int chPW[16]; /* Channel pitch wheel, MSB only */
71 71
72 72
73/*
74unsigned char chVol[16]; //Channel volume
75unsigned char chPanLeft[16]; //Channel panning
76unsigned char chPanRight[16];
77unsigned char chPat[16]; //Channel patch
78unsigned char chPW[16]; //Channel pitch wheel, MSB only
79*/
80struct GPatch * gusload(char *); 73struct GPatch * gusload(char *);
81struct GPatch * patchSet[128]; 74struct GPatch * patchSet[128];
82struct GPatch * drumSet[128]; 75struct GPatch * drumSet[128];
83 76
84
85//char myarray[80] IDATA_ATTR;
86
87struct Event 77struct Event
88{ 78{
89 unsigned int delta; 79 unsigned int delta;
90 unsigned char status, d1, d2; 80 unsigned char status, d1, d2;
91 unsigned int len; 81 unsigned int len;
92 unsigned char * evData; 82 unsigned char * evData;
93}; 83};
94 84
95struct Track 85struct Track
96{ 86{
97 unsigned int size; 87 unsigned int size;
98 unsigned int numEvents; 88 unsigned int numEvents;
99 unsigned int delta; //For sequencing 89 unsigned int delta; /* For sequencing */
100 unsigned int pos; //For sequencing 90 unsigned int pos; /* For sequencing */
101 void * dataBlock; 91 void * dataBlock;
102}; 92};
103 93
104 94
105struct MIDIfile 95struct MIDIfile
106{ 96{
107 int Length; 97 int Length;
108 98 unsigned short numTracks;
109 //int Format; //We don't really care what type it is 99 unsigned short div; /* Time division, X ticks per millisecond */
110 unsigned short numTracks; 100 struct Track * tracks[48];
111 unsigned short div; //Time division, X ticks per millisecond 101 unsigned char patches[128];
112 struct Track * tracks[48]; 102 int numPatches;
113 unsigned char patches[128];
114 int numPatches;
115}; 103};
104
116/* 105/*
117struct SynthObject 106struct SynthObject
118{ 107{
119// int tmp; 108 struct GWaveform * wf;
120 struct GWaveform * wf; 109 unsigned int delta;
121 unsigned int delta; 110 unsigned int decay;
122 unsigned int decay; 111 unsigned int cp;
123 unsigned int cp; 112 unsigned char state, loopState, loopDir;
124 unsigned char state, loopState, loopDir; 113 unsigned char note, vol, ch, isUsed;
125 unsigned char note, vol, ch, isUsed; 114 int curRate, curOffset, targetOffset;
126 int curRate, curOffset, targetOffset; 115 unsigned int curPoint;
127 unsigned int curPoint;
128}; 116};
129*/ 117*/
118
130struct SynthObject 119struct SynthObject
131{ 120{
132// int tmp; 121 struct GWaveform * wf;
133 struct GWaveform * wf; 122 int delta;
134 int delta; 123 int decay;
135 int decay; 124 unsigned int cp;
136 int cp; 125 int state, loopState, loopDir;
137 int state, loopState, loopDir; 126 int note, vol, ch, isUsed;
138 int note, vol, ch, isUsed; 127 int curRate, curOffset, targetOffset;
139 int curRate, curOffset, targetOffset; 128 int curPoint;
140 int curPoint;
141}; 129};
142 130
143struct SynthObject voices[MAX_VOICES] IDATA_ATTR; 131struct SynthObject voices[MAX_VOICES] IDATA_ATTR;
@@ -156,91 +144,91 @@ int midimain(void * filename);
156 144
157void *alloc(int size) 145void *alloc(int size)
158{ 146{
159 static char *offset = NULL; 147 static char *offset = NULL;
160 static int totalSize = 0; 148 static int totalSize = 0;
161 char *ret; 149 char *ret;
162 150
163 int remainder = size % 4; 151 int remainder = size % 4;
164 152
165 size = size + 4-remainder; 153 size = size + 4-remainder;
166 154
167 if (offset == NULL) 155 if (offset == NULL)
168 { 156 {
169 offset = rb->plugin_get_audio_buffer(&totalSize); 157 offset = rb->plugin_get_audio_buffer(&totalSize);
170 } 158 }
171 159
172 if (size + 4 > totalSize) 160 if (size + 4 > totalSize)
173 { 161 {
174 return NULL; 162 return NULL;
175 } 163 }
176 164
177 ret = offset + 4; 165 ret = offset + 4;
178 *((unsigned int *)offset) = size; 166 *((unsigned int *)offset) = size;
179 167
180 offset += size + 4; 168 offset += size + 4;
181 totalSize -= size + 4; 169 totalSize -= size + 4;
182 return ret; 170 return ret;
183} 171}
184 172
185 173
186//Rick's code 174/* Rick's code */
187/* 175/*
188void *alloc(int size) 176void *alloc(int size)
189{ 177{
190 static char *offset = NULL; 178 static char *offset = NULL;
191 static int totalSize = 0; 179 static int totalSize = 0;
192 char *ret; 180 char *ret;
193 181
194 182
195 if (offset == NULL) 183 if (offset == NULL)
196 { 184 {
197 offset = rb->plugin_get_audio_buffer(&totalSize); 185 offset = rb->plugin_get_audio_buffer(&totalSize);
198 } 186 }
199 187
200 if (size + 4 > totalSize) 188 if (size + 4 > totalSize)
201 { 189 {
202 return NULL; 190 return NULL;
203 } 191 }
204 192
205 ret = offset + 4; 193 ret = offset + 4;
206 *((unsigned int *)offset) = size; 194 *((unsigned int *)offset) = size;
207 195
208 offset += size + 4; 196 offset += size + 4;
209 totalSize -= size + 4; 197 totalSize -= size + 4;
210 return ret; 198 return ret;
211}*/ 199}*/
212void * allocate(int size) 200void * allocate(int size)
213{ 201{
214 return alloc(size); 202 return alloc(size);
215} 203}
216 204
217unsigned char readChar(int file) 205unsigned char readChar(int file)
218{ 206{
219 char buf[2]; 207 char buf[2];
220 rb->read(file, &buf, 1); 208 rb->read(file, &buf, 1);
221 return buf[0]; 209 return buf[0];
222} 210}
223 211
224unsigned char * readData(int file, int len) 212unsigned char * readData(int file, int len)
225{ 213{
226 unsigned char * dat = allocate(len); 214 unsigned char * dat = allocate(len);
227 rb->read(file, dat, len); 215 rb->read(file, dat, len);
228 return dat; 216 return dat;
229} 217}
230 218
231int eof(int fd) 219int eof(int fd)
232{ 220{
233 int curPos = rb->lseek(fd, 0, SEEK_CUR); 221 int curPos = rb->lseek(fd, 0, SEEK_CUR);
234 222
235 int size = rb->lseek(fd, 0, SEEK_END); 223 int size = rb->lseek(fd, 0, SEEK_END);
236 224
237 rb->lseek(fd, curPos, SEEK_SET); 225 rb->lseek(fd, curPos, SEEK_SET);
238 return size+1 == rb->lseek(fd, 0, SEEK_CUR); 226 return size+1 == rb->lseek(fd, 0, SEEK_CUR);
239} 227}
240 228
241void printf(char *fmt, ...) {fmt=fmt; } 229void printf(char *fmt, ...) {fmt=fmt; }
242 230
243void exit(int code) 231void exit(int code)
244{ 232{
245 code = code; //Stub function, kill warning for now 233 code = code; /* Stub function, kill warning for now */
246} 234}
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;
24 24
25void setVol(int ch, int vol) 25void setVol(int ch, int vol)
26{ 26{
27 printf("\nvolume[%d] %d ==> %d", ch, chVol[ch], vol); 27 printf("\nvolume[%d] %d ==> %d", ch, chVol[ch], vol);
28 chVol[ch]=vol; 28 chVol[ch]=vol;
29} 29}
30 30
31void setPan(int ch, int pan) 31void setPan(int ch, int pan)
32{ 32{
33 printf("\npanning[%d] %d ==> %d", ch, chPanRight[ch], pan); 33 printf("\npanning[%d] %d ==> %d", ch, chPanRight[ch], pan);
34 34
35 chPanLeft[ch]=128-pan; 35 chPanLeft[ch]=128-pan;
36 chPanRight[ch]=pan; 36 chPanRight[ch]=pan;
37} 37}
38 38
39 39
40void setPatch(int ch, int pat) 40void setPatch(int ch, int pat)
41{ 41{
42 chPat[ch]=pat; 42 chPat[ch]=pat;
43} 43}
44 44
45 45
46/* 46/*
47 Pitch Bend table, Computed by 47 * Pitch Bend table, Computed by
48 for i=0:127, fprintf('%d,', round(2^16*2^((i-64)/384))); end 48 * for i=0:127, fprintf('%d,', round(2^16*2^((i-64)/384))); end
49 (When typed into Matlab) 49 * (When typed into Matlab)
50 16 bit pitch bend table 50 * 16 bit pitch bend table
51*/ 51*/
52long pitchTbl[]= 52long pitchTbl[]=
53{ 53{
54 58386,58491,58597,58703,58809,58915,59022,59128,59235,59342,59449,59557,59664,59772,59880,59988,60097,60205, 54 58386,58491,58597,58703,58809,58915,59022,59128,59235,59342,59449,59557,59664,59772,59880,59988,60097,60205,
55 60314,60423,60532,60642,60751,60861,60971,61081,61191,61302,61413,61524,61635,61746,61858,61970,62081,62194, 55 60314,60423,60532,60642,60751,60861,60971,61081,61191,61302,61413,61524,61635,61746,61858,61970,62081,62194,
56 62306,62419,62531,62644,62757,62871,62984,63098,63212,63326,63441,63555,63670,63785,63901,64016,64132,64248, 56 62306,62419,62531,62644,62757,62871,62984,63098,63212,63326,63441,63555,63670,63785,63901,64016,64132,64248,
57 64364,64480,64596,64713,64830,64947,65065,65182,65300,65418,65536,65654,65773,65892,66011,66130,66250,66369, 57 64364,64480,64596,64713,64830,64947,65065,65182,65300,65418,65536,65654,65773,65892,66011,66130,66250,66369,
58 66489,66609,66730,66850,66971,67092,67213,67335,67456,67578,67700,67823,67945,68068,68191,68314,68438,68561, 58 66489,66609,66730,66850,66971,67092,67213,67335,67456,67578,67700,67823,67945,68068,68191,68314,68438,68561,
59 68685,68809,68933,69058,69183,69308,69433,69558,69684,69810,69936,70062,70189,70316,70443,70570,70698,70825, 59 68685,68809,68933,69058,69183,69308,69433,69558,69684,69810,69936,70062,70189,70316,70443,70570,70698,70825,
60 70953,71082,71210,71339,71468,71597,71726,71856,71985,72115,72246,72376,72507,72638,72769,72901,73032,73164, 60 70953,71082,71210,71339,71468,71597,71726,71856,71985,72115,72246,72376,72507,72638,72769,72901,73032,73164,
61 73297,73429 61 73297,73429
62}; 62};
63 63
64 64
65void findDelta(struct SynthObject * so, int ch, int note) 65void findDelta(struct SynthObject * so, int ch, int note)
66{ 66{
67 67
68 struct GWaveform * wf = patchSet[chPat[ch]]->waveforms[patchSet[chPat[ch]]->noteTable[note]]; 68 struct GWaveform * wf = patchSet[chPat[ch]]->waveforms[patchSet[chPat[ch]]->noteTable[note]];
69 so->wf=wf; 69 so->wf=wf;
70 so->delta = (((gustable[note]<<10) / wf->rootFreq) * wf->sampRate / SAMPLE_RATE); 70 so->delta = (((gustable[note]<<10) / (wf->rootFreq)) * wf->sampRate / (SAMPLE_RATE));
71 so->delta = so->delta * pitchTbl[chPW[ch]] >> 16; 71 so->delta = (so->delta * pitchTbl[chPW[ch]])>> 16;
72} 72}
73 73
74void setPW(int ch, int msb) 74void setPW(int ch, int msb)
75{ 75{
76 printf("\npitchw[%d] %d ==> %d", ch, chPW[ch], msb); 76 printf("\npitchw[%d] %d ==> %d", ch, chPW[ch], msb);
77 chPW[ch] = msb; 77 chPW[ch] = msb;
78 78
79 int a=0; 79 int a=0;
80 for(a = 0; a<MAX_VOICES; a++) 80 for(a = 0; a<MAX_VOICES; a++)
81 { 81 {
82 if(voices[a].isUsed==1 && voices[a].ch == ch) 82 if(voices[a].isUsed==1 && voices[a].ch == ch)
83 { 83 {
84 findDelta(&voices[a], ch, voices[a].note); 84 findDelta(&voices[a], ch, voices[a].note);
85 } 85 }
86 } 86 }
87} 87}
88 88
89void pressNote(int ch, int note, int vol) 89void pressNote(int ch, int note, int vol)
90{ 90{
91
92//Silences all channels but one, for easy debugging, for me.
91/* 93/*
92 if(ch == 0) return; 94 if(ch == 0) return;
93// if(ch == 1) return; 95 if(ch == 1) return;
94 if(ch == 2) return; 96 if(ch == 2) return;
95 if(ch == 3) return; 97 if(ch == 3) return;
96 if(ch == 4) return; 98// if(ch == 4) return;
97 if(ch == 5) return; 99 if(ch == 5) return;
98 if(ch == 6) return; 100 if(ch == 6) return;
99 if(ch == 7) return; 101 if(ch == 7) return;
100 if(ch == 8) return; 102 if(ch == 8) return;
101 if(ch == 9) return; 103 if(ch == 9) return;
102 if(ch == 10) return; 104 if(ch == 10) return;
103 if(ch == 11) return; 105 if(ch == 11) return;
104 if(ch == 12) return; 106 if(ch == 12) return;
105 if(ch == 13) return; 107 if(ch == 13) return;
106 if(ch == 14) return; 108 if(ch == 14) return;
107 if(ch == 15) return; 109 if(ch == 15) return;
108*/ 110*/
109 int a=0; 111 int a=0;
110 for(a=0; a<MAX_VOICES; a++) 112 for(a=0; a<MAX_VOICES; a++)
111 { 113 {
112 if(voices[a].ch == ch && voices[a].note == note) 114 if(voices[a].ch == ch && voices[a].note == note)
113 break; 115 break;
114 116
115 if(voices[a].isUsed==0) 117 if(voices[a].isUsed==0)
116 break; 118 break;
117 } 119 }
118 if(a==MAX_VOICES-1) 120 if(a==MAX_VOICES-1)
119 { 121 {
120 printf("\nOVERFLOW: Too many voices playing at once. No more left"); 122 printf("\nOVERFLOW: Too many voices playing at once. No more left");
121 printf("\nVOICE DUMP: "); 123 printf("\nVOICE DUMP: ");
122 for(a=0; a<48; a++) 124 for(a=0; a<48; a++)
123 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); 125 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);
124 return; //None avaolable 126 return; /* None available */
125 } 127 }
126 voices[a].ch=ch; 128 voices[a].ch=ch;
127 voices[a].note=note; 129 voices[a].note=note;
128 voices[a].vol=vol; 130 voices[a].vol=vol;
129 voices[a].cp=0; 131 voices[a].cp=0;
130 voices[a].state=STATE_ATTACK; 132 voices[a].state=STATE_ATTACK;
131// voices[a].pstate=STATE_ATTACK; 133 voices[a].decay=255;
132 voices[a].decay=255; 134
133 135
134 136 voices[a].loopState=STATE_NONLOOPING;
135 voices[a].loopState=STATE_NONLOOPING; 137 voices[a].loopDir = LOOPDIR_FORWARD;
136 voices[a].loopDir = LOOPDIR_FORWARD; 138 /*
137 /* 139 * OKAY. Gt = Gus Table value
138 OKAY. Gt = Gus Table value 140 * rf = Root Frequency of wave
139 rf = Root Frequency of wave 141 * SR = sound sampling rate
140 SR = sound sampling rate 142 * sr = WAVE sampling rate
141 sr = WAVE sampling rate 143 */
142 */ 144
143 145 if(ch!=9)
144 146 {
145 /* 147 findDelta(&voices[a], ch, note);
146 unsigned int gt = gustable[note]; 148 /* Turn it on */
147 unsigned int rf = wf->rootFreq; 149 voices[a].isUsed=1;
148 unsigned int SR = SAMPLE_RATE; 150 setPoint(&voices[a], 0);
149 unsigned int sr = wf->sampRate; 151 } else
150 voices[a].delta=((((gt<<10) / rf) * sr / SR)); 152 {
151 */ 153 if(drumSet[note]!=NULL)
152 154 {
153 155 if(note<35)
154 if(ch!=9) 156 printf("\nNOTE LESS THAN 35, AND A DRUM PATCH EXISTS FOR THIS? WHAT THE HELL?");
155 { 157
156 findDelta(&voices[a], ch, note); 158 struct GWaveform * wf = drumSet[note]->waveforms[0];
157 //Turn it on 159 voices[a].wf=wf;
158 voices[a].isUsed=1; 160 voices[a].delta = (((gustable[note]<<10) / wf->rootFreq) * wf->sampRate / SAMPLE_RATE);
159 setPoint(&voices[a], 0); 161 if(wf->mode & 28)
160 } else 162 printf("\nWoah, a drum patch has a loop. Stripping the loop...");
161 { 163 wf->mode = wf->mode & (255-28);
162 if(drumSet[note]!=NULL) 164
163 { 165 /* Turn it on */
164 if(note<35) 166 voices[a].isUsed=1;
165 printf("\nNOTE LESS THAN 35, AND A DRUM PATCH EXISTS FOR THIS? WHAT THE HELL?"); 167 setPoint(&voices[a], 0);
166 168
167 struct GWaveform * wf = drumSet[note]->waveforms[0]; 169 } else
168 voices[a].wf=wf; 170 {
169 voices[a].delta = (((gustable[note]<<10) / wf->rootFreq) * wf->sampRate / SAMPLE_RATE); 171 printf("\nWarning: drum %d does not have a patch defined... Ignoring it", note);
170 if(wf->mode & 28) 172 }
171 printf("\nWoah, a drum patch has a loop. Stripping the loop..."); 173 }
172 wf->mode = wf->mode & (255-28);
173 //Turn it on
174 voices[a].isUsed=1;
175 setPoint(&voices[a], 0);
176
177 } else
178 {
179 printf("\nWarning: drum %d does not have a patch defined... Ignoring it", note);
180 }
181 }
182} 174}
183 175
184 176
185void releaseNote(int ch, int note) 177void releaseNote(int ch, int note)
186{ 178{
187 if(ch==9) // && note != 27 && note != 31 && note != 28) 179 if(ch==9)
188 return; 180 return;
189 int a=0; 181
190 for(a=0; a<MAX_VOICES; a++) 182 int a=0;
191 { 183 for(a=0; a<MAX_VOICES; a++)
192 if(voices[a].ch == ch && voices[a].note == note) 184 {
193 { 185 if(voices[a].ch == ch && voices[a].note == note)
194 if((voices[a].wf->mode & 28)) 186 {
195 { 187 if((voices[a].wf->mode & 28))
196 // voices[a].tmp=40; 188 {
197// voices[a].state = STATE_RELEASE; //Ramp down 189 setPoint(&voices[a], 3);
198 190 }
199// voices[a].state = STATE_RAMPDOWN; //Ramp down 191 }
200 setPoint(&voices[a], 3); 192 }
201 }
202 }
203 }
204} 193}
205 194
206void sendEvent(struct Event * ev) 195void sendEvent(struct Event * ev)
207{ 196{
208// printf("\nEVENT S=%2x D1=%2x D2=%2x", ev->status, ev->d1, ev->d2); 197 if( ((ev->status & 0xF0) == MIDI_CONTROL) && (ev->d1 == CTRL_VOLUME) )
209 198 {
210 if( ((ev->status & 0xF0) == MIDI_CONTROL) && (ev->d1 == CTRL_VOLUME) ) 199 setVol((ev->status & 0xF), ev->d2);
211 { 200 return;
212 setVol((ev->status & 0xF), ev->d2); 201 }
213 return; 202
214 } 203 if( ((ev->status & 0xF0) == MIDI_CONTROL) && (ev->d1 == CTRL_PANNING))
215 204 {
216 if( ((ev->status & 0xF0) == MIDI_CONTROL) && (ev->d1 == CTRL_PANNING)) 205 setPan((ev->status & 0xF), ev->d2);
217 { 206 return;
218 setPan((ev->status & 0xF), ev->d2); 207 }
219 return; 208
220 } 209 if(((ev->status & 0xF0) == MIDI_PITCHW))
221 210 {
222 if(((ev->status & 0xF0) == MIDI_PITCHW)) 211 setPW((ev->status & 0xF), ev->d2);
223 { 212 return;
224 setPW((ev->status & 0xF), ev->d2); 213 }
225 return; 214
226 } 215 if(((ev->status & 0xF0) == MIDI_NOTE_ON) && (ev->d2 != 0))
227 216 {
228 if(((ev->status & 0xF0) == MIDI_NOTE_ON) && (ev->d2 != 0)) 217 pressNote(ev->status & 0x0F, ev->d1, ev->d2);
229 { 218 return;
230 pressNote(ev->status & 0x0F, ev->d1, ev->d2); 219 }
231 return; 220
232 } 221 if(((ev->status & 0xF0) == MIDI_NOTE_ON) && (ev->d2 == 0)) /* Release by vol=0 */
233 222 {
234 if(((ev->status & 0xF0) == MIDI_NOTE_ON) && (ev->d2 == 0)) //Release by vol=0 223 releaseNote(ev->status & 0x0F, ev->d1);
235 { 224 return;
236 releaseNote(ev->status & 0x0F, ev->d1); 225 }
237 return; 226
238 } 227
239 228 if((ev->status & 0xF0) == MIDI_NOTE_OFF)
240 229 {
241 if((ev->status & 0xF0) == MIDI_NOTE_OFF) 230 releaseNote(ev->status & 0x0F, ev->d1);
242 { 231 return;
243 releaseNote(ev->status & 0x0F, ev->d1); 232 }
244 return; 233
245 } 234 if((ev->status & 0xF0) == MIDI_PRGM)
246 235 {
247 if((ev->status & 0xF0) == MIDI_PRGM) 236 if((ev->status & 0x0F) == 9)
248 { 237 printf("\nNOT PATCHING: Someone tried patching Channel 9 onto something?");
249 if((ev->status & 0x0F) == 9) 238 else
250 printf("\nNOT PATCHING: Someone tried patching Channel 9 onto something?"); 239 setPatch(ev->status & 0x0F, ev->d1);
251 else 240 }
252 setPatch(ev->status & 0x0F, ev->d1);
253 }
254} 241}
255 242
256 243
@@ -259,61 +246,60 @@ void sendEvent(struct Event * ev)
259 246
260int tick(struct MIDIfile * mf) 247int tick(struct MIDIfile * mf)
261{ 248{
262 if(mf==NULL) 249 if(mf==NULL)
263 return 0; 250 return 0;
264 251
265 int a=0; 252 int a=0;
266 int tracksAdv=0; 253 int tracksAdv=0;
267 for(a=0; a<mf->numTracks; a++) 254 for(a=0; a<mf->numTracks; a++)
268 { 255 {
269 struct Track * tr = mf->tracks[a]; 256 struct Track * tr = mf->tracks[a];
270 257
271 if(tr == NULL) 258 if(tr == NULL)
272 printf("\nNULL TRACK: %d", a); 259 printf("\nNULL TRACK: %d", a);
273 260
274 261
275 //BIG DEBUG STATEMENT 262 //BIG DEBUG STATEMENT
276 //printf("\nTrack %2d, Event = %4d of %4d, Delta = %5d, Next = %4d", a, tr->pos, tr->numEvents, tr->delta, getEvent(tr, tr->pos)->delta); 263 //printf("\nTrack %2d, Event = %4d of %4d, Delta = %5d, Next = %4d", a, tr->pos, tr->numEvents, tr->delta, getEvent(tr, tr->pos)->delta);
277 264
278 265
279 if(tr != NULL && (tr->pos < tr->numEvents)) 266 if(tr != NULL && (tr->pos < tr->numEvents))
280 { 267 {
281 tr->delta++; 268 tr->delta++;
282 tracksAdv++; 269 tracksAdv++;
283 while(getEvent(tr, tr->pos)->delta <= tr->delta) 270 while(getEvent(tr, tr->pos)->delta <= tr->delta)
284 { 271 {
285// printf("\nDelta = %d", tr->delta); 272 struct Event * e = getEvent(tr, tr->pos);
286 struct Event * e = getEvent(tr, tr->pos); 273
287 274 if(e->status != 0xFF)
288 if(e->status != 0xFF) 275 {
289 { 276 sendEvent(e);
290 sendEvent(e); 277 if(((e->status&0xF0) == MIDI_PRGM))
291 if(((e->status&0xF0) == MIDI_PRGM)) 278 {
292 { 279 printf("\nPatch Event, patch[%d] ==> %d", e->status&0xF, e->d1);
293 printf("\nPatch Event, patch[%d] ==> %d", e->status&0xF, e->d1); 280 }
294 } 281 }
295 } 282 else
296 else 283 {
297 { 284 if(e->d1 == 0x51)
298 if(e->d1 == 0x51) 285 {
299 { 286 tempo = (((short)e->evData[0])<<16)|(((short)e->evData[1])<<8)|(e->evData[2]);
300 tempo = (((short)e->evData[0])<<16)|(((short)e->evData[1])<<8)|(e->evData[2]); 287 printf("\nMeta-Event: Tempo Set = %d", tempo);
301 printf("\nMeta-Event: Tempo Set = %d", tempo); 288 bpm=mf->div*1000000/tempo;
302 bpm=mf->div*1000000/tempo; 289 numberOfSamples=SAMPLE_RATE/bpm;
303 numberOfSamples=SAMPLE_RATE/bpm; 290
304 291 }
305 } 292 }
306 } 293 tr->delta = 0;
307 tr->delta = 0; 294 tr->pos++;
308 tr->pos++; 295 if(tr->pos>=(tr->numEvents-1))
309 if(tr->pos>=(tr->numEvents-1)) 296 break;
310 break; 297 }
311 } 298 }
312 } 299 }
313 } 300
314 301 if(tracksAdv != 0)
315 if(tracksAdv != 0) 302 return 1;
316 return 1; 303 else
317 else 304 return 0;
318 return 0;
319} 305}
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;
20 20
21struct Event * getEvent(struct Track * tr, int evNum) 21struct Event * getEvent(struct Track * tr, int evNum)
22{ 22{
23 return tr->dataBlock + (evNum*sizeof(struct Event)); 23 return tr->dataBlock + (evNum*sizeof(struct Event));
24} 24}
25 25
26void readTextBlock(int file, char * buf) 26void readTextBlock(int file, char * buf)
27{ 27{
28 char c = 0; 28 char c = 0;
29 do 29 do
30 { 30 {
31 c = readChar(file); 31 c = readChar(file);
32 } while(c == '\n' || c == ' ' || c=='\t'); 32 } while(c == '\n' || c == ' ' || c=='\t');
33 33
34 rb->lseek(file, -1, SEEK_CUR); 34 rb->lseek(file, -1, SEEK_CUR);
35 int cp = 0; 35 int cp = 0;
36 do 36 do
37 { 37 {
38 c = readChar(file); 38 c = readChar(file);
39 buf[cp] = c; 39 buf[cp] = c;
40 cp++; 40 cp++;
41 } while (c != '\n' && c != ' ' && c != '\t' && !eof(file)); 41 } while (c != '\n' && c != ' ' && c != '\t' && !eof(file));
42 buf[cp-1]=0; 42 buf[cp-1]=0;
43 rb->lseek(file, -1, SEEK_CUR); 43 rb->lseek(file, -1, SEEK_CUR);
44} 44}
45 45
46 46
47 47
48//Filename is the name of the config file 48/* Filename is the name of the config file */
49//The MIDI file should have been loaded at this point 49/* The MIDI file should have been loaded at this point */
50int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig) 50int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig)
51{ 51{
52 char patchUsed[128]; 52 char patchUsed[128];
53 char drumUsed[128]; 53 char drumUsed[128];
54 int a=0; 54 int a=0;
55 for(a=0; a<MAX_VOICES; a++) 55 for(a=0; a<MAX_VOICES; a++)
56 { 56 {
57 voices[a].cp=0; 57 voices[a].cp=0;
58 voices[a].vol=0; 58 voices[a].vol=0;
59 voices[a].ch=0; 59 voices[a].ch=0;
60 voices[a].isUsed=0; 60 voices[a].isUsed=0;
61 voices[a].note=0; 61 voices[a].note=0;
62 } 62 }
63 63
64 for(a=0; a<16; a++) 64 for(a=0; a<16; a++)
65 { 65 {
66 chVol[a]=100; //Default, not quite full blast.. 66 chVol[a]=100; /* Default, not quite full blast.. */
67 chPanLeft[a]=64; //Center 67 chPanLeft[a]=64; /* Center */
68 chPanRight[a]=64; //Center 68 chPanRight[a]=64; /* Center */
69 chPat[a]=0; //Ac Gr Piano 69 chPat[a]=0; /* Ac Gr Piano */
70 chPW[a]=64; // .. not .. bent ? 70 chPW[a]=64; /* .. not .. bent ? */
71 } 71 }
72 for(a=0; a<128; a++) 72 for(a=0; a<128; a++)
73 { 73 {
74 patchSet[a]=NULL; 74 patchSet[a]=NULL;
75 drumSet[a]=NULL; 75 drumSet[a]=NULL;
76 patchUsed[a]=0; 76 patchUsed[a]=0;
77 drumUsed[a]=0; 77 drumUsed[a]=0;
78 } 78 }
79 79
80 //Always load the piano. 80 /*
81 //Some files will assume its loaded without specifically 81 * Always load the piano.
82 //issuing a Patch command... then we wonder why we can't hear anything 82 * Some files will assume its loaded without specifically
83 patchUsed[0]=1; 83 * issuing a Patch command... then we wonder why we can't hear anything
84 84 */
85 //Scan the file to see what needs to be loaded 85 patchUsed[0]=1;
86 for(a=0; a<mf->numTracks; a++) 86
87 { 87 /* Scan the file to see what needs to be loaded */
88 int ts=0; 88 for(a=0; a<mf->numTracks; a++)
89 89 {
90 if(mf->tracks[a] == NULL) 90 unsigned int ts=0;
91 { 91
92 printf("\nNULL TRACK !!!"); 92 if(mf->tracks[a] == NULL)
93 rb->splash(HZ*2, true, "Null Track in loader."); 93 {
94 return -1; 94 printf("\nNULL TRACK !!!");
95 } 95 rb->splash(HZ*2, true, "Null Track in loader.");
96 96 return -1;
97 for(ts=0; ts<mf->tracks[a]->numEvents; ts++) 97 }
98 { 98
99 99 for(ts=0; ts<mf->tracks[a]->numEvents; ts++)
100 if((getEvent(mf->tracks[a], ts)->status) == (MIDI_NOTE_ON+9)) 100 {
101 drumUsed[getEvent(mf->tracks[a], ts)->d1]=1; 101
102 102 if((getEvent(mf->tracks[a], ts)->status) == (MIDI_NOTE_ON+9))
103 if( (getEvent(mf->tracks[a], ts)->status & 0xF0) == MIDI_PRGM) 103 drumUsed[getEvent(mf->tracks[a], ts)->d1]=1;
104 { 104
105 if(patchUsed[getEvent(mf->tracks[a], ts)->d1]==0) 105 if( (getEvent(mf->tracks[a], ts)->status & 0xF0) == MIDI_PRGM)
106 printf("\nI need to load patch %d.", getEvent(mf->tracks[a], ts)->d1); 106 {
107 patchUsed[getEvent(mf->tracks[a], ts)->d1]=1; 107 if(patchUsed[getEvent(mf->tracks[a], ts)->d1]==0)
108 } 108 printf("\nI need to load patch %d.", getEvent(mf->tracks[a], ts)->d1);
109 } 109 patchUsed[getEvent(mf->tracks[a], ts)->d1]=1;
110 } 110 }
111 111 }
112 int file = rb->open(filename, O_RDONLY); 112 }
113 if(file == -1) 113
114 { 114 int file = rb->open(filename, O_RDONLY);
115 rb->splash(HZ*2, true, "Bad patch config.\nDid you install the patchset?"); 115 if(file == -1)
116 return -1; 116 {
117 } 117 rb->splash(HZ*2, true, "Bad patch config.\nDid you install the patchset?");
118 118 return -1;
119 char name[40]; 119 }
120 char fn[40]; 120
121 121 char name[40];
122 //Scan our config file and load the right patches as needed 122 char fn[40];
123 int c = 0; 123
124 rb->snprintf(name, 40, ""); 124 /* Scan our config file and load the right patches as needed */
125 for(a=0; a<128; a++) 125 int c = 0;
126 { 126 rb->snprintf(name, 40, "");
127 while(readChar(file)!=' ' && !eof(file)); 127 for(a=0; a<128; a++)
128 readTextBlock(file, name); 128 {
129 129 while(readChar(file)!=' ' && !eof(file));
130 rb->snprintf(fn, 40, "/.rockbox/patchset/%s.pat", name); 130 readTextBlock(file, name);
131 printf("\nLOADING: <%s> ", fn); 131
132 132 rb->snprintf(fn, 40, "/.rockbox/patchset/%s.pat", name);
133 if(patchUsed[a]==1) 133 printf("\nLOADING: <%s> ", fn);
134 patchSet[a]=gusload(fn); 134
135 135 if(patchUsed[a]==1)
136// if(patchSet[a] == NULL) 136 {
137// return -1; 137 patchSet[a]=gusload(fn);
138 138
139 while((c != '\n')) 139 if(patchSet[a] == NULL) /* There was an error loading it */
140 c = readChar(file); 140 return -1;
141 } 141 }
142 rb->close(file); 142
143 143 while((c != '\n'))
144 file = rb->open(drumConfig, O_RDONLY); 144 c = readChar(file);
145 if(file == -1) 145 }
146 { 146 rb->close(file);
147 rb->splash(HZ*2, true, "Bad drum config.\nDid you install the patchset?"); 147
148 return -1; 148 file = rb->open(drumConfig, O_RDONLY);
149 } 149 if(file == -1)
150 150 {
151 //Scan our config file and load the drum data 151 rb->splash(HZ*2, true, "Bad drum config.\nDid you install the patchset?");
152 int idx=0; 152 return -1;
153 char number[30]; 153 }
154 while(!eof(file)) 154
155 { 155 /* Scan our config file and load the drum data */
156 readTextBlock(file, number); 156 int idx=0;
157 readTextBlock(file, name); 157 char number[30];
158 rb->snprintf(fn, 40, "/.rockbox/patchset/%s.pat", name); 158 while(!eof(file))
159 159 {
160 idx = rb->atoi(number); 160 readTextBlock(file, number);
161 if(idx == 0) 161 readTextBlock(file, name);
162 break; 162 rb->snprintf(fn, 40, "/.rockbox/patchset/%s.pat", name);
163 163
164 if(drumUsed[idx]==1) 164 idx = rb->atoi(number);
165 drumSet[idx]=gusload(fn); 165 if(idx == 0)
166 166 break;
167// if(drumSet[idx] == NULL) 167
168// return -1; 168 if(drumUsed[idx]==1)
169 169 {
170 while((c != '\n') && (c != 255) && (!eof(file))) 170 drumSet[idx]=gusload(fn);
171 c = readChar(file); 171
172 } 172 if(drumSet[idx] == NULL) /* Error loading patch */
173 rb->close(file); 173 return -1;
174 return 0; 174 }
175
176 while((c != '\n') && (c != 255) && (!eof(file)))
177 c = readChar(file);
178 }
179 rb->close(file);
180 return 0;
175} 181}
176 182
177 183
@@ -182,7 +188,7 @@ struct GWaveform * wf IDATA_ATTR;
182int s IDATA_ATTR; 188int s IDATA_ATTR;
183short s1 IDATA_ATTR; 189short s1 IDATA_ATTR;
184short s2 IDATA_ATTR; 190short s2 IDATA_ATTR;
185short sample IDATA_ATTR; //For synthSample 191short sample IDATA_ATTR; /* For synthSample */
186unsigned int cpShifted IDATA_ATTR; 192unsigned int cpShifted IDATA_ATTR;
187 193
188unsigned char b1 IDATA_ATTR; 194unsigned char b1 IDATA_ATTR;
@@ -191,31 +197,9 @@ unsigned char b2 IDATA_ATTR;
191 197
192inline int getSample(int s) 198inline int getSample(int s)
193{ 199{
194 200 /* Sign conversion moved to guspat.c */
195 //16 bit samples 201 /* 8bit conversion NOT YET IMPLEMENTED in guspat.c */
196 if(wf->mode&1) 202 return ((short *) wf->data)[s];
197 {
198
199 if(s<<1 >= wf->wavSize)
200 {
201 printf("\n!!!!! %d \t %d", s<<1, wf->wavSize);
202 return 0;
203 }
204// signed short a = ((short *)wf->data)[s];
205
206 //Sign conversion moved into guspat.c
207 b1=wf->data[s<<1]+((wf->mode & 2) << 6);
208 b2=wf->data[(s<<1)|1]+((wf->mode & 2) << 6);
209 return (b1 | (b2<<8)) ;
210
211 //Get rid of this sometime
212 }
213 else
214 { //8-bit samples
215 //Do we even have anything 8-bit in our set?
216 int b1=wf->data[s]+((wf->mode & 2) << 6);
217 return b1<<8;
218 }
219} 203}
220 204
221 205
@@ -223,190 +207,194 @@ inline int getSample(int s)
223 207
224inline void setPoint(struct SynthObject * so, int pt) 208inline void setPoint(struct SynthObject * so, int pt)
225{ 209{
226 if(so->ch==9) //Drums, no ADSR 210 if(so->ch==9) /* Drums, no ADSR */
227 { 211 {
228 so->curOffset = 1<<27; 212 so->curOffset = 1<<27;
229 so->curRate = 1; 213 so->curRate = 1;
230 return; 214 return;
231 } 215 }
232 216
233 if(so->wf==NULL) 217 if(so->wf==NULL)
234 { 218 {
235 printf("\nCrap... null waveform..."); 219 printf("\nCrap... null waveform...");
236 exit(1); 220 exit(1);
237 } 221 }
238 if(so->wf->envRate==NULL) 222 if(so->wf->envRate==NULL)
239 { 223 {
240 printf("\nWaveform has no envelope set"); 224 printf("\nWaveform has no envelope set");
241 exit(1); 225 exit(1);
242 } 226 }
243 227
244 so->curPoint = pt; 228 so->curPoint = pt;
245 229
246 int r=0; 230 int r=0;
247 int rate = so->wf->envRate[pt]; 231 int rate = so->wf->envRate[pt];
248 232
249 r=3-((rate>>6) & 0x3); // Some blatant Timidity code for rate conversion... 233 r=3-((rate>>6) & 0x3); /* Some blatant Timidity code for rate conversion... */
250 r*=3; 234 r*=3;
251 r = (rate & 0x3f) << r; 235 r = (rate & 0x3f) << r;
252 236
253 /* 237 /*
254 Okay. This is the rate shift. Timidity defaults to 9, and sets 238 * Okay. This is the rate shift. Timidity defaults to 9, and sets
255 it to 10 if you use the fast decay option. Slow decay sounds better 239 * it to 10 if you use the fast decay option. Slow decay sounds better
256 on some files, except on some other files... you get chords that aren't 240 * on some files, except on some other files... you get chords that aren't
257 done decaying yet.. and they dont harmonize with the next chord and it 241 * done decaying yet.. and they dont harmonize with the next chord and it
258 sounds like utter crap. Yes, even Timitidy does that. So I'm going to 242 * sounds like utter crap. Yes, even Timitidy does that. So I'm going to
259 default this to 10, and maybe later have an option to set it to 9 243 * default this to 10, and maybe later have an option to set it to 9
260 for longer decays. 244 * for longer decays.
261 */ 245 */
262 so->curRate = r<<10; 246 so->curRate = r<<10;
263 247
264 //Do this here because the patches assume a 44100 sampling rate 248 /*
265 //We've halved our sampling rate, ergo the ADSR code will be 249 * Do this here because the patches assume a 44100 sampling rate
266 //called half the time. Ergo, double the rate to keep stuff 250 * We've halved our sampling rate, ergo the ADSR code will be
267 //sounding right. 251 * called half the time. Ergo, double the rate to keep stuff
268 so->curRate = so->curRate << 1; 252 * sounding right.
269 253 */
270 254 so->curRate = so->curRate << 1;
271 so->targetOffset = so->wf->envOffset[pt]<<(20); 255
272 if(pt==0) 256
273 so->curOffset = 0; 257 so->targetOffset = so->wf->envOffset[pt]<<(20);
258 if(pt==0)
259 so->curOffset = 0;
274} 260}
275 261
276 262
277inline void stopVoice(struct SynthObject * so) 263inline void stopVoice(struct SynthObject * so)
278{ 264{
279 if(so->state == STATE_RAMPDOWN) 265 if(so->state == STATE_RAMPDOWN)
280 return; 266 return;
281 so->state = STATE_RAMPDOWN; 267 so->state = STATE_RAMPDOWN;
282 so->decay = 255; 268 so->decay = 255;
283 269
284} 270}
285 271
286 272
287inline signed short int synthVoice() 273inline signed short int synthVoice()
288{ 274{
289 so = &voices[currentVoice]; 275 so = &voices[currentVoice];
290 wf = so->wf; 276 wf = so->wf;
291 277
292 278
293 if(so->state != STATE_RAMPDOWN) 279 if(so->state != STATE_RAMPDOWN)
294 { 280 {
295 so->cp += so->delta; 281 so->cp += so->delta;
296 } 282 }
297 283
298 cpShifted = so->cp >> 10; 284 cpShifted = so->cp >> 10;
299 285
300 if( (cpShifted >= (wf->wavSize>>1)) && (so->state != STATE_RAMPDOWN)) 286 if( (cpShifted > (wf->numSamples) && (so->state != STATE_RAMPDOWN)))
301 stopVoice(so); 287 {
288 stopVoice(so);
289 }
302 290
303 s2 = getSample((cpShifted)+1); 291 s2 = getSample((cpShifted)+1);
304 292
305 if((wf->mode & (LOOP_REVERSE|LOOP_PINGPONG)) && so->loopState == STATE_LOOPING && (cpShifted <= (wf->startLoop>>1))) 293 /* LOOP_REVERSE|LOOP_PINGPONG = 24 */
306 { 294 if((wf->mode & (24)) && so->loopState == STATE_LOOPING && (cpShifted <= (wf->startLoop)))
307 if(wf->mode & LOOP_REVERSE) 295 {
308 { 296 if(wf->mode & LOOP_REVERSE)
309 so->cp = (wf->endLoop)<<9; 297 {
310 cpShifted = so->cp >> 10; 298 so->cp = (wf->endLoop)<<10;
311 s2=getSample((cpShifted)); 299 cpShifted = wf->endLoop;
312 } else 300 s2=getSample((cpShifted));
313 { 301 } else
314 so->delta = -so->delta; 302 {
315 so->loopDir = LOOPDIR_FORWARD; 303 so->delta = -so->delta;
316 } 304 so->loopDir = LOOPDIR_FORWARD;
317 } 305 }
318 306 }
319 if((wf->mode & 28) && (so->cp>>10 >= wf->endLoop>>1)) 307
320 { 308 if((wf->mode & 28) && (cpShifted >= wf->endLoop))
321 so->loopState = STATE_LOOPING; 309 {
322 if((wf->mode & (24)) == 0) 310 so->loopState = STATE_LOOPING;
323 { 311 if((wf->mode & (24)) == 0)
324 so->cp = (wf->startLoop)<<9; 312 {
325 cpShifted = so->cp >> 10; 313 so->cp = (wf->startLoop)<<10;
326 s2=getSample((cpShifted)); 314 cpShifted = wf->startLoop;
327 } else 315 s2=getSample((cpShifted));
328 { 316 } else
329 so->delta = -so->delta; 317 {
330 so->loopDir = LOOPDIR_REVERSE; 318 so->delta = -so->delta;
331 } 319 so->loopDir = LOOPDIR_REVERSE;
332 } 320 }
333 321 }
334 //Better, working, linear interpolation 322
335 s1=getSample((cpShifted)); 323 /* Better, working, linear interpolation */
336 s = s1 + ((signed)((s2 - s1) * (so->cp & 1023))>>10); 324 s1=getSample((cpShifted));
337 325 s = s1 + ((signed)((s2 - s1) * (so->cp & 1023))>>10);
338 326
339//ADSR COMMENT WOULD GO FROM HERE......... 327
340 328/* ADSR COMMENT WOULD GO FROM HERE.........*/
341 if(so->curRate == 0) 329
342 stopVoice(so); 330 if(so->curRate == 0)
343 331 stopVoice(so);
344 332
345 if(so->ch != 9) //Stupid ADSR code... and don't do ADSR for drums 333
346 { 334 if(so->ch != 9) /* Stupid ADSR code... and don't do ADSR for drums */
347 if(so->curOffset < so->targetOffset) 335 {
348 { 336 if(so->curOffset < so->targetOffset)
349 so->curOffset += (so->curRate); 337 {
350 if(so -> curOffset > so->targetOffset && so->curPoint != 2) 338 so->curOffset += (so->curRate);
351 { 339 if(so -> curOffset > so->targetOffset && so->curPoint != 2)
352 if(so->curPoint != 5) 340 {
353 setPoint(so, so->curPoint+1); 341 if(so->curPoint != 5)
354 else 342 setPoint(so, so->curPoint+1);
355 stopVoice(so); 343 else
356 } 344 stopVoice(so);
357 } else 345 }
358 { 346 } else
359 so->curOffset -= (so->curRate); 347 {
360 if(so -> curOffset < so->targetOffset && so->curPoint != 2) 348 so->curOffset -= (so->curRate);
361 { 349 if(so -> curOffset < so->targetOffset && so->curPoint != 2)
362 350 {
363 if(so->curPoint != 5) 351
364 setPoint(so, so->curPoint+1); 352 if(so->curPoint != 5)
365 else 353 setPoint(so, so->curPoint+1);
366 stopVoice(so); 354 else
367 355 stopVoice(so);
368 } 356
369 } 357 }
370 } 358 }
371 359 }
372 if(so->curOffset < 0) 360
373 so->isUsed=0; //This is OK 361 if(so->curOffset < 0)
374 362 so->isUsed=0; /* This is OK because offset faded it out already */
375 363
376 s = (s * (so->curOffset >> 22) >> 6); 364
377 365 s = (s * (so->curOffset >> 22) >> 8);
378// ............. TO HERE 366
379 367/* ............. TO HERE */
380 368
381 if(so->state == STATE_RAMPDOWN) 369
382 { 370 if(so->state == STATE_RAMPDOWN)
383 so->decay--; 371 {
384 if(so->decay == 0) 372 so->decay--;
385 so->isUsed=0; 373 if(so->decay == 0)
386 } 374 so->isUsed=0;
387 375 s = (s * so->decay) >> 8;
388 s = s * so->decay; s = s >> 10; 376 }
389 377
390 return s*((signed short int)so->vol*(signed short int)chVol[so->ch])>>14; 378 return s*((signed short int)so->vol*(signed short int)chVol[so->ch])>>14;
391} 379}
392 380
393 381
394inline void synthSample(int * mixL, int * mixR) 382inline void synthSample(int * mixL, int * mixR)
395{ 383{
396// signed int leftMix=0, rightMix=0, 384 *mixL = 0;
397 *mixL = 0; 385 *mixR = 0;
398 *mixR = 0; 386 for(currentVoice=0; currentVoice<MAX_VOICES; currentVoice++)
399 for(currentVoice=0; currentVoice<MAX_VOICES; currentVoice++) 387 {
400 { 388 if(voices[currentVoice].isUsed==1)
401 if(voices[currentVoice].isUsed==1) 389 {
402 { 390 sample = synthVoice(currentVoice);
403 sample = synthVoice(currentVoice); 391 *mixL += (sample*chPanLeft[voices[currentVoice].ch])>>7;
404 *mixL += (sample*chPanLeft[voices[currentVoice].ch])>>7; 392 *mixR += (sample*chPanRight[voices[currentVoice].ch])>>7;
405 *mixR += (sample*chPanRight[voices[currentVoice].ch])>>7; 393 }
406 } 394 }
407 } 395
408 396 /* TODO: Automatic Gain Control, anyone? */
409 //TODO: Automatic Gain Control, anyone? 397 /* Or, should this be implemented on the DSP's output volume instead? */
410 //Or, should this be implemented on the DSP's output volume instead? 398
411 return; //No more ghetto lowpass filter.. linear intrpolation works well. 399 return; /* No more ghetto lowpass filter.. linear intrpolation works well. */
412} 400}
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 @@
20#define MAX_VOICES 100 20#define MAX_VOICES 100
21 21
22 22
23//Only define LOCAL_DSP on Simulator or else we're asking for trouble 23/* Only define LOCAL_DSP on Simulator or else we're asking for trouble */
24#if defined(SIMULATOR) 24#if defined(SIMULATOR)
25 //Enable this to write to the soundcard via a /dsv/dsp symlink in / 25 /*Enable this to write to the soundcard via a /dsv/dsp symlink in */
26// #define LOCAL_DSP 26// #define LOCAL_DSP
27#endif 27#endif
28 28
29 29
30#if defined(LOCAL_DSP) 30#if defined(LOCAL_DSP)
31// This is for writing to the DSP directly from the Simulator 31/* This is for writing to the DSP directly from the Simulator */
32#include <stdio.h> 32#include <stdio.h>
33#include <stdlib.h> 33#include <stdlib.h>
34#include <linux/soundcard.h> 34#include <linux/soundcard.h>
35#include <sys/ioctl.h> 35#include <sys/ioctl.h>
36#endif 36#endif
37 37
38#include "../../firmware/export/system.h"
38 39
39#include "../../plugin.h" 40#include "../../plugin.h"
40 41
@@ -53,9 +54,9 @@ long bpm;
53 54
54 55
55 56
56int fd=-1; //File descriptor where the output is written 57int fd=-1; /* File descriptor where the output is written */
57 58
58extern long tempo; //The sequencer keeps track of this 59extern long tempo; /* The sequencer keeps track of this */
59 60
60 61
61struct plugin_api * rb; 62struct plugin_api * rb;
@@ -66,27 +67,28 @@ struct plugin_api * rb;
66 67
67enum plugin_status plugin_start(struct plugin_api* api, void* parameter) 68enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
68{ 69{
69 TEST_PLUGIN_API(api); 70 TEST_PLUGIN_API(api);
70 rb = api; 71 rb = api;
71 TEST_PLUGIN_API(api); 72 TEST_PLUGIN_API(api);
72 (void)parameter; 73 (void)parameter;
73 rb = api; 74 rb = api;
74 75
75 if(parameter == NULL) 76 if(parameter == NULL)
76 { 77 {
77 rb->splash(HZ*2, true, " Play .MID file "); 78 rb->splash(HZ*2, true, " Play .MID file ");
78 return PLUGIN_OK; 79 return PLUGIN_OK;
79 } 80 }
80 rb->splash(HZ, true, parameter); 81
81 if(midimain(parameter) == -1) 82 rb->splash(HZ, true, parameter);
82 { 83 if(midimain(parameter) == -1)
83 return PLUGIN_ERROR; 84 {
84 } 85 return PLUGIN_ERROR;
85 rb->splash(HZ*3, true, "FINISHED PLAYING"); 86 }
86 return PLUGIN_OK; 87 rb->splash(HZ*3, true, "FINISHED PLAYING");
88 return PLUGIN_OK;
87} 89}
88 90
89signed char outputBuffer[3000] IDATA_ATTR; //signed char.. gonna run out of iram ... ! 91signed char outputBuffer[3000] IDATA_ATTR; /* signed char.. gonna run out of iram ... ! */
90 92
91 93
92int currentSample IDATA_ATTR; 94int currentSample IDATA_ATTR;
@@ -98,132 +100,133 @@ int outputSampleTwo IDATA_ATTR;
98int midimain(void * filename) 100int midimain(void * filename)
99{ 101{
100 102
101 printf("\nHello.\n"); 103 printf("\nHello.\n");
102 104
103 rb->splash(HZ/5, true, "LOADING MIDI"); 105 rb->splash(HZ/5, true, "LOADING MIDI");
104 106
105 struct MIDIfile * mf = loadFile(filename); 107 struct MIDIfile * mf = loadFile(filename);
106 108
107 rb->splash(HZ/5, true, "LOADING PATCHES"); 109 rb->splash(HZ/5, true, "LOADING PATCHES");
108 if (initSynth(mf, "/.rockbox/patchset/patchset.cfg", "/.rockbox/patchset/drums.cfg") == -1) 110 if (initSynth(mf, "/.rockbox/patchset/patchset.cfg", "/.rockbox/patchset/drums.cfg") == -1)
109 { 111 {
110 return -1; 112 return -1;
111 } 113 }
112 114
113//This lets you hear the music through the sound card if you are on Simulator 115/*
114//Make a symlink, archos/dsp.raw and make it point to /dev/dsp or whatever 116 * This lets you hear the music through the sound card if you are on Simulator
115//your sound device is. 117 * Make a symlink, archos/dsp.raw and make it point to /dev/dsp or whatever
118 * your sound device is.
119 */
116 120
117#if defined(LOCAL_DSP) 121#if defined(LOCAL_DSP)
118 fd=rb->open("/dsp.raw", O_WRONLY); 122 fd=rb->open("/dsp.raw", O_WRONLY);
119 int arg, status; 123 int arg, status;
120 int bit, samp, ch; 124 int bit, samp, ch;
121 125
122 arg = 16; // sample size 126 arg = 16; /* sample size */
123 status = ioctl(fd, SOUND_PCM_WRITE_BITS, &arg); 127 status = ioctl(fd, SOUND_PCM_WRITE_BITS, &arg);
124 status = ioctl(fd, SOUND_PCM_READ_BITS, &arg); 128 status = ioctl(fd, SOUND_PCM_READ_BITS, &arg);
125 bit=arg; 129 bit=arg;
126 130
127 131
128 arg = 2; //Number of channels, 1=mono 132 arg = 2; /* Number of channels, 1=mono */
129 status = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &arg); 133 status = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &arg);
130 status = ioctl(fd, SOUND_PCM_READ_CHANNELS, &arg); 134 status = ioctl(fd, SOUND_PCM_READ_CHANNELS, &arg);
131 ch=arg; 135 ch=arg;
132 136
133 arg = SAMPLE_RATE; //Yeah. sampling rate 137 arg = SAMPLE_RATE; /* Yeah. sampling rate */
134 status = ioctl(fd, SOUND_PCM_WRITE_RATE, &arg); 138 status = ioctl(fd, SOUND_PCM_WRITE_RATE, &arg);
135 status = ioctl(fd, SOUND_PCM_READ_RATE, &arg); 139 status = ioctl(fd, SOUND_PCM_READ_RATE, &arg);
136 samp=arg; 140 samp=arg;
137#else 141#else
138 file_info_struct file_info; 142 file_info_struct file_info;
139 file_info.samplerate = SAMPLE_RATE; 143 file_info.samplerate = SAMPLE_RATE;
140 file_info.infile = fd; 144 file_info.infile = fd;
141 file_info.channels = 2; 145 file_info.channels = 2;
142 file_info.bitspersample = 16; 146 file_info.bitspersample = 16;
143 local_init("/miditest.tmp", "/miditest.wav", &file_info, rb); 147 local_init("/miditest.tmp", "/miditest.wav", &file_info, rb);
144 fd = file_info.outfile; 148 fd = file_info.outfile;
145#endif 149#endif
146 150
147 151
148 rb->splash(HZ/5, true, " Starting Playback "); 152 rb->splash(HZ/5, true, " I hope this works... ");
149 153
150 154
151 155
152 156
157 /*
158 * tick() will do one MIDI clock tick. Then, there's a loop here that
159 * will generate the right number of samples per MIDI tick. The whole
160 * MIDI playback is timed in terms of this value.. there are no forced
161 * delays or anything. It just produces enough samples for each tick, and
162 * the playback of these samples is what makes the timings right.
163 *
164 * This seems to work quite well.
165 */
153 166
154 // tick() will do one MIDI clock tick. Then, there's a loop here that 167 printf("\nOkay, starting sequencing");
155 // will generate the right number of samples per MIDI tick. The whole
156 // MIDI playback is timed in terms of this value.. there are no forced
157 // delays or anything. It just produces enough samples for each tick, and
158 // the playback of these samples is what makes the timings right.
159 //
160 // This seems to work quite well.
161 168
162 169
163 printf("\nOkay, starting sequencing"); 170 currentSample=0; /* Sample counting variable */
171 outputBufferPosition = 0;
164 172
165 173
166 currentSample=0; //Sample counting variable 174 bpm=mf->div*1000000/tempo;
167 outputBufferPosition = 0; 175 numberOfSamples=SAMPLE_RATE/bpm;
168 176
169 177
170 bpm=mf->div*1000000/tempo;
171 numberOfSamples=SAMPLE_RATE/bpm;
172 178
179 /* Tick() will return 0 if there are no more events left to play */
180 while(tick(mf))
181 {
182 /*
183 * Tempo recalculation moved to sequencer.c to be done on a tempo event only
184 *
185 */
186 for(currentSample=0; currentSample<numberOfSamples; currentSample++)
187 {
173 188
189 synthSample(&outputSampleOne, &outputSampleTwo);
174 190
175 //Tick() will return 0 if there are no more events left to play
176 while(tick(mf))
177 {
178 191
179 //Some annoying math to compute the number of samples 192 /*
180 //to syntehsize per each MIDI tick. 193 * 16-bit audio because, well, it's better
194 * But really because ALSA's OSS emulation sounds extremely
195 * noisy and distorted when in 8-bit mode. I still do not know
196 * why this happens.
197 */
181 198
182 //Yes we need to do this math each time because the tempo 199 outputBuffer[outputBufferPosition]=outputSampleOne&0XFF; // Low byte first
183 //could have changed. 200 outputBufferPosition++;
201 outputBuffer[outputBufferPosition]=outputSampleOne>>8; //High byte second
202 outputBufferPosition++;
184 203
185 // On second thought, this can be moved to the event that 204 outputBuffer[outputBufferPosition]=outputSampleTwo&0XFF; // Low byte first
186 //recalculates the tempo, to save a little bit of CPU time. 205 outputBufferPosition++;
187 for(currentSample=0; currentSample<numberOfSamples; currentSample++) 206 outputBuffer[outputBufferPosition]=outputSampleTwo>>8; //High byte second
188 { 207 outputBufferPosition++;
189 208
190 synthSample(&outputSampleOne, &outputSampleTwo);
191 209
210 /*
211 * As soon as we produce 2000 bytes of sound,
212 * write it to the sound card. Why 2000? I have
213 * no idea. It's 1 AM and I am dead tired.
214 */
215 if(outputBufferPosition>=2000)
216 {
217 rb->write(fd, outputBuffer, 2000);
218 outputBufferPosition=0;
219 }
220 }
221 }
192 222
193 //16-bit audio because, well, it's better 223 printf("\n");
194 // But really because ALSA's OSS emulation sounds extremely
195 //noisy and distorted when in 8-bit mode. I still do not know
196 //why this happens.
197 outputBuffer[outputBufferPosition]=outputSampleOne&0XFF; // Low byte first
198 outputBufferPosition++;
199 outputBuffer[outputBufferPosition]=outputSampleOne>>8; //High byte second
200 outputBufferPosition++;
201
202 outputBuffer[outputBufferPosition]=outputSampleTwo&0XFF; // Low byte first
203 outputBufferPosition++;
204 outputBuffer[outputBufferPosition]=outputSampleTwo>>8; //High byte second
205 outputBufferPosition++;
206
207
208 //As soon as we produce 2000 bytes of sound,
209 //write it to the sound card. Why 2000? I have
210 //no idea. It's 1 AM and I am dead tired.
211 if(outputBufferPosition>=2000)
212 {
213 rb->write(fd, outputBuffer, 2000);
214 outputBufferPosition=0;
215 }
216 }
217 }
218
219// unloadFile(mf);
220 printf("\n");
221 224
222#if !defined(LOCAL_DSP) 225#if !defined(LOCAL_DSP)
223 226
224 close_wav(&file_info); 227 close_wav(&file_info);
225#else 228#else
226 rb->close(fd); 229 rb->close(fd);
227#endif 230#endif
228 return 0; 231 return 0;
229} 232}