summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStepan Moskovchenko <stevenm@rockbox.org>2005-04-19 15:57:07 +0000
committerStepan Moskovchenko <stevenm@rockbox.org>2005-04-19 15:57:07 +0000
commit1f5fb998192f512ac32dfa012586fb78a9a6a72c (patch)
treef95b3ccdd5f077f1870aea934d4b7d8d2fc64843
parentc3d0a229ccd859853641d7ee01e7c5c30045159c (diff)
downloadrockbox-1f5fb998192f512ac32dfa012586fb78a9a6a72c.tar.gz
rockbox-1f5fb998192f512ac32dfa012586fb78a9a6a72c.zip
Some shifting optimizations. Working code. 50% realtime.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6323 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugins/midi/guspat.c52
-rw-r--r--apps/plugins/midi/guspat.h1
-rw-r--r--apps/plugins/midi/midiutil.c132
-rw-r--r--apps/plugins/midi/sequencer.c31
-rw-r--r--apps/plugins/midi/synth.c158
-rw-r--r--apps/plugins/midi2wav.c65
6 files changed, 238 insertions, 201 deletions
diff --git a/apps/plugins/midi/guspat.c b/apps/plugins/midi/guspat.c
index f674b64caa..2172072eb1 100644
--- a/apps/plugins/midi/guspat.c
+++ b/apps/plugins/midi/guspat.c
@@ -66,18 +66,64 @@ struct GWaveform * loadWaveform(int file)
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 int a=0; 70 int a=0;
70 71
72 return wav;
73 if(wav->mode & 1 == 0) //Whoops, 8 bit
74 {
75 wav->numSamples = wav->wavSize;
76
77 //Allocate a block for the rest of it
78 //It should end up right after the previous one.
79 wav->wavSize = wav->wavSize * 2;
80 void * foo = allocate(wav->wavSize);
81
82
83 for(a=0; a<1000; a++)
84 printf("\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
85
86
87 for(a=wav->wavSize-1; a>0; a-=2)
88 {
89
90 }
91 // int b1=wf->data[s]+((wf->mode & 2) << 6);
92 // return b1<<8;
93 }
94
95 /*
96//#if !defined(SIMULATOR)
97 for(a=0; a<wav->wavSize; a+=2)
98 {
99 unsigned char tmp;
100 tmp = wav->data[2*a];
101 wav->data[2*a] = wav->data[2*a+1];
102 wav->data[2*a+1] = tmp;
103 }
104//#endif
105
106 if(wav->mode & 2)
107 {
108 for(a=0; a<wav->wavSize/2; a++)
109 {
110 ((short *) wav->data)[a] = ((short *) wav->data)[a] - 32767;
111 }
112 }
113*/
114
115
116
71 //If we have a 16 bit waveform 117 //If we have a 16 bit waveform
72 if(wav->mode & 1 && (wav->mode & 2)) 118/* if(wav->mode & 1 && (wav->mode & 2))
73 { 119 {
74 for(a=0; a<wav->wavSize; a+=2) //Convert it to 120 for(a=0; a<wav->wavSize; a+=2) //Convert it to
75 { 121 {
76 //wav->data[a]=wav->data[a]; //+((wav->mode & 2) << 6); 122 wav->data[a]=wav->data[a]+(1 << 7);
77 wav->data[a|1]=wav->data[(a)|1]+(1 << 7); 123 wav->data[a|1]=wav->data[(a)|1]+(1 << 7);
78 } 124 }
79 } 125 }
80 126*/
81 return wav; 127 return wav;
82} 128}
83 129
diff --git a/apps/plugins/midi/guspat.h b/apps/plugins/midi/guspat.h
index 75bdb2ca01..6e41a85d23 100644
--- a/apps/plugins/midi/guspat.h
+++ b/apps/plugins/midi/guspat.h
@@ -36,6 +36,7 @@ struct GWaveform
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 startLoop; 40 unsigned int startLoop;
40 unsigned int endLoop; 41 unsigned int endLoop;
41 unsigned int sampRate; 42 unsigned int sampRate;
diff --git a/apps/plugins/midi/midiutil.c b/apps/plugins/midi/midiutil.c
index 41a02ae682..bf25d1d277 100644
--- a/apps/plugins/midi/midiutil.c
+++ b/apps/plugins/midi/midiutil.c
@@ -63,33 +63,26 @@
63extern struct plugin_api * rb; 63extern struct plugin_api * rb;
64 64
65 65
66int chVol[16] IDATA_ATTR; //Channel volume
67int chPanLeft[16] IDATA_ATTR; //Channel panning
68int chPanRight[16] IDATA_ATTR;
69int chPat[16]; //Channel patch
70int chPW[16]; //Channel pitch wheel, MSB only
71
72
73/*
66unsigned char chVol[16]; //Channel volume 74unsigned char chVol[16]; //Channel volume
67unsigned char chPanLeft[16]; //Channel panning 75unsigned char chPanLeft[16]; //Channel panning
68unsigned char chPanRight[16]; 76unsigned char chPanRight[16];
69unsigned char chPat[16]; //Channel patch 77unsigned char chPat[16]; //Channel patch
70unsigned char chPW[16]; //Channel pitch wheel, MSB only 78unsigned char chPW[16]; //Channel pitch wheel, MSB only
71 79*/
72
73struct GPatch * gusload(char *); 80struct GPatch * gusload(char *);
74struct GPatch * patchSet[128]; 81struct GPatch * patchSet[128];
75struct GPatch * drumSet[128]; 82struct GPatch * drumSet[128];
76struct SynthObject voices[MAX_VOICES];
77 83
78 84
79 85//char myarray[80] IDATA_ATTR;
80struct SynthObject
81{
82 int tmp;
83 struct GWaveform * wf;
84 unsigned int delta;
85 unsigned int decay;
86 unsigned int cp;
87 unsigned char state, pstate, loopState, loopDir;
88 unsigned char note, vol, ch, isUsed;
89 int curRate, curOffset, targetOffset;
90 int curPoint;
91};
92
93 86
94struct Event 87struct Event
95{ 88{
@@ -120,6 +113,34 @@ struct MIDIfile
120 unsigned char patches[128]; 113 unsigned char patches[128];
121 int numPatches; 114 int numPatches;
122}; 115};
116/*
117struct SynthObject
118{
119// int tmp;
120 struct GWaveform * wf;
121 unsigned int delta;
122 unsigned int decay;
123 unsigned int cp;
124 unsigned char state, loopState, loopDir;
125 unsigned char note, vol, ch, isUsed;
126 int curRate, curOffset, targetOffset;
127 unsigned int curPoint;
128};
129*/
130struct SynthObject
131{
132// int tmp;
133 struct GWaveform * wf;
134 int delta;
135 int decay;
136 int cp;
137 int state, loopState, loopDir;
138 int note, vol, ch, isUsed;
139 int curRate, curOffset, targetOffset;
140 int curPoint;
141};
142
143struct SynthObject voices[MAX_VOICES] IDATA_ATTR;
123 144
124 145
125 146
@@ -133,13 +154,16 @@ int readVarData(int file);
133int midimain(void * filename); 154int midimain(void * filename);
134 155
135 156
136//Rick's code
137void *alloc(int size) 157void *alloc(int size)
138{ 158{
139 static char *offset = NULL; 159 static char *offset = NULL;
140 static int totalSize = 0; 160 static int totalSize = 0;
141 char *ret; 161 char *ret;
142 162
163 int remainder = size % 4;
164
165 size = size + 4-remainder;
166
143 if (offset == NULL) 167 if (offset == NULL)
144 { 168 {
145 offset = rb->plugin_get_audio_buffer(&totalSize); 169 offset = rb->plugin_get_audio_buffer(&totalSize);
@@ -157,40 +181,34 @@ void *alloc(int size)
157 totalSize -= size + 4; 181 totalSize -= size + 4;
158 return ret; 182 return ret;
159} 183}
184
185
186//Rick's code
160/* 187/*
161void *ralloc(char *offset, int len) 188void *alloc(int size)
162{ 189{
163 int size; 190 static char *offset = NULL;
191 static int totalSize = 0;
164 char *ret; 192 char *ret;
165 193
194
166 if (offset == NULL) 195 if (offset == NULL)
167 { 196 {
168 return alloc(len); 197 offset = rb->plugin_get_audio_buffer(&totalSize);
169 } 198 }
170 199
171 size = *((unsigned int *)offset - 4); 200 if (size + 4 > totalSize)
172
173 if (size >= 0x02000000)
174 { 201 {
175 return NULL; 202 return NULL;
176 } 203 }
177 204
178 ret = alloc(len); 205 ret = offset + 4;
179 206 *((unsigned int *)offset) = size;
180 if (len < size)
181 {
182 rb->memcpy(ret, offset, len);
183 }
184 else
185 {
186 rb->memcpy(ret, offset, size);
187 rb->memset(ret, 0, len - size);
188 }
189 207
208 offset += size + 4;
209 totalSize -= size + 4;
190 return ret; 210 return ret;
191} 211}*/
192*/
193
194void * allocate(int size) 212void * allocate(int size)
195{ 213{
196 return alloc(size); 214 return alloc(size);
@@ -222,44 +240,6 @@ int eof(int fd)
222 240
223void printf(char *fmt, ...) {fmt=fmt; } 241void printf(char *fmt, ...) {fmt=fmt; }
224 242
225/*
226void *audio_bufferbase;
227void *audio_bufferpointer;
228unsigned int audio_buffer_free;
229
230
231
232
233void *my_malloc(int size)
234{
235
236 void *alloc;
237
238 if (!audio_bufferbase)
239 {
240 audio_bufferbase = audio_bufferpointer
241 = rb->plugin_get_audio_buffer(&audio_buffer_free);
242#if MEM <= 8 && !defined(SIMULATOR)
243
244 if ((unsigned)(ovl_start_addr - (unsigned char *)audio_bufferbase)
245 < audio_buffer_free)
246 audio_buffer_free = ovl_start_addr - (unsigned char *)audio_bufferbase;
247#endif
248 }
249 if (size + 4 > audio_buffer_free)
250 return 0;
251 alloc = audio_bufferpointer;
252 audio_bufferpointer += size + 4;
253 audio_buffer_free -= size + 4;
254 return alloc;
255}
256
257void setmallocpos(void *pointer)
258{
259 audio_bufferpointer = pointer;
260 audio_buffer_free = audio_bufferpointer - audio_bufferbase;
261}
262*/
263void exit(int code) 243void exit(int code)
264{ 244{
265 code = code; //Stub function, kill warning for now 245 code = code; //Stub function, kill warning for now
diff --git a/apps/plugins/midi/sequencer.c b/apps/plugins/midi/sequencer.c
index f7c6f30376..836866a5df 100644
--- a/apps/plugins/midi/sequencer.c
+++ b/apps/plugins/midi/sequencer.c
@@ -88,9 +88,30 @@ void setPW(int ch, int msb)
88 88
89void pressNote(int ch, int note, int vol) 89void pressNote(int ch, int note, int vol)
90{ 90{
91/*
92 if(ch == 0) return;
93// if(ch == 1) return;
94 if(ch == 2) return;
95 if(ch == 3) return;
96 if(ch == 4) return;
97 if(ch == 5) return;
98 if(ch == 6) return;
99 if(ch == 7) return;
100 if(ch == 8) return;
101 if(ch == 9) return;
102 if(ch == 10) return;
103 if(ch == 11) return;
104 if(ch == 12) return;
105 if(ch == 13) return;
106 if(ch == 14) return;
107 if(ch == 15) return;
108*/
91 int a=0; 109 int a=0;
92 for(a=0; a<MAX_VOICES; a++) 110 for(a=0; a<MAX_VOICES; a++)
93 { 111 {
112 if(voices[a].ch == ch && voices[a].note == note)
113 break;
114
94 if(voices[a].isUsed==0) 115 if(voices[a].isUsed==0)
95 break; 116 break;
96 } 117 }
@@ -107,7 +128,7 @@ void pressNote(int ch, int note, int vol)
107 voices[a].vol=vol; 128 voices[a].vol=vol;
108 voices[a].cp=0; 129 voices[a].cp=0;
109 voices[a].state=STATE_ATTACK; 130 voices[a].state=STATE_ATTACK;
110 voices[a].pstate=STATE_ATTACK; 131// voices[a].pstate=STATE_ATTACK;
111 voices[a].decay=255; 132 voices[a].decay=255;
112 133
113 134
@@ -170,15 +191,12 @@ void releaseNote(int ch, int note)
170 { 191 {
171 if(voices[a].ch == ch && voices[a].note == note) 192 if(voices[a].ch == ch && voices[a].note == note)
172 { 193 {
173 //voices[a].isUsed=0;
174 if((voices[a].wf->mode & 28)) 194 if((voices[a].wf->mode & 28))
175 { 195 {
176 voices[a].tmp=40; 196 // voices[a].tmp=40;
177// voices[a].state = STATE_RELEASE; //Ramp down 197// voices[a].state = STATE_RELEASE; //Ramp down
178 198
179// voices[a].state = STATE_RAMPDOWN; //Ramp down 199// voices[a].state = STATE_RAMPDOWN; //Ramp down
180
181// voices[a].isUsed = 0;
182 setPoint(&voices[a], 3); 200 setPoint(&voices[a], 3);
183 } 201 }
184 } 202 }
@@ -281,6 +299,9 @@ int tick(struct MIDIfile * mf)
281 { 299 {
282 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]);
283 printf("\nMeta-Event: Tempo Set = %d", tempo); 301 printf("\nMeta-Event: Tempo Set = %d", tempo);
302 bpm=mf->div*1000000/tempo;
303 numberOfSamples=SAMPLE_RATE/bpm;
304
284 } 305 }
285 } 306 }
286 tr->delta = 0; 307 tr->delta = 0;
diff --git a/apps/plugins/midi/synth.c b/apps/plugins/midi/synth.c
index 99864e557e..bafaf1c7ca 100644
--- a/apps/plugins/midi/synth.c
+++ b/apps/plugins/midi/synth.c
@@ -16,8 +16,6 @@
16 * 16 *
17 ****************************************************************************/ 17 ****************************************************************************/
18 18
19
20
21extern struct plugin_api * rb; 19extern struct plugin_api * rb;
22 20
23struct Event * getEvent(struct Track * tr, int evNum) 21struct Event * getEvent(struct Track * tr, int evNum)
@@ -178,7 +176,20 @@ int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig)
178 176
179 177
180 178
181inline signed short int getSample(struct GWaveform * wf, unsigned int s) 179int currentVoice IDATA_ATTR;
180struct SynthObject * so IDATA_ATTR;
181struct GWaveform * wf IDATA_ATTR;
182int s IDATA_ATTR;
183short s1 IDATA_ATTR;
184short s2 IDATA_ATTR;
185short sample IDATA_ATTR; //For synthSample
186unsigned int cpShifted IDATA_ATTR;
187
188unsigned char b1 IDATA_ATTR;
189unsigned char b2 IDATA_ATTR;
190
191
192inline int getSample(int s)
182{ 193{
183 194
184 //16 bit samples 195 //16 bit samples
@@ -186,24 +197,23 @@ inline signed short int getSample(struct GWaveform * wf, unsigned int s)
186 { 197 {
187 198
188 if(s<<1 >= wf->wavSize) 199 if(s<<1 >= wf->wavSize)
200 {
201 printf("\n!!!!! %d \t %d", s<<1, wf->wavSize);
189 return 0; 202 return 0;
190 203 }
191 204// signed short a = ((short *)wf->data)[s];
192 /*
193 * Probably put the signed/unsigned and and 8-16 bit conversion
194 * into the patch loader and have it run there, once.
195 */
196
197 205
198 //Sign conversion moved into guspat.c 206 //Sign conversion moved into guspat.c
199 unsigned char b1=wf->data[s<<1]; //+((wf->mode & 2) << 6); 207 b1=wf->data[s<<1]+((wf->mode & 2) << 6);
200 unsigned char b2=wf->data[(s<<1)|1]; //+((wf->mode & 2) << 6); 208 b2=wf->data[(s<<1)|1]+((wf->mode & 2) << 6);
201 return (b1 | (b2<<8)) ; 209 return (b1 | (b2<<8)) ;
210
211 //Get rid of this sometime
202 } 212 }
203 else 213 else
204 { //8-bit samples 214 { //8-bit samples
205 //Do we even have anything 8-bit in our set? 215 //Do we even have anything 8-bit in our set?
206 unsigned char b1=wf->data[s]+((wf->mode & 2) << 6); 216 int b1=wf->data[s]+((wf->mode & 2) << 6);
207 return b1<<8; 217 return b1<<8;
208 } 218 }
209} 219}
@@ -251,6 +261,12 @@ inline void setPoint(struct SynthObject * so, int pt)
251 */ 261 */
252 so->curRate = r<<10; 262 so->curRate = r<<10;
253 263
264 //Do this here because the patches assume a 44100 sampling rate
265 //We've halved our sampling rate, ergo the ADSR code will be
266 //called half the time. Ergo, double the rate to keep stuff
267 //sounding right.
268 so->curRate = so->curRate << 1;
269
254 270
255 so->targetOffset = so->wf->envOffset[pt]<<(20); 271 so->targetOffset = so->wf->envOffset[pt]<<(20);
256 if(pt==0) 272 if(pt==0)
@@ -258,8 +274,6 @@ inline void setPoint(struct SynthObject * so, int pt)
258} 274}
259 275
260 276
261long msi=0;
262
263inline void stopVoice(struct SynthObject * so) 277inline void stopVoice(struct SynthObject * so)
264{ 278{
265 if(so->state == STATE_RAMPDOWN) 279 if(so->state == STATE_RAMPDOWN)
@@ -269,51 +283,37 @@ inline void stopVoice(struct SynthObject * so)
269 283
270} 284}
271 285
272int rampDown = 0;
273 286
274inline signed short int synthVoice(int v) 287inline signed short int synthVoice()
275{ 288{
276 //Probably can combine these 2 lines into one.. 289 so = &voices[currentVoice];
277 //But for now, this looks more readable 290 wf = so->wf;
278// struct GPatch * pat = patchSet[chPat[voices[v].ch]];
279// struct GWaveform * wf = pat->waveforms[pat->noteTable[voices[v].note]];
280 struct SynthObject * so = &voices[v];
281 struct GWaveform * wf = so->wf;
282 291
283 signed int s;
284 292
285 if(so->state != STATE_RAMPDOWN) 293 if(so->state != STATE_RAMPDOWN)
286 { 294 {
287 if(so->loopDir==LOOPDIR_FORWARD) 295 so->cp += so->delta;
288 {
289 so->cp += so->delta;
290 }
291 else
292 {
293 so->cp -= so->delta;
294 }
295 } 296 }
296 297
297 if( (so->cp>>9 >= (wf->wavSize)) && (so->state != STATE_RAMPDOWN)) 298 cpShifted = so->cp >> 10;
298 stopVoice(so);
299
300 /*
301 //Original, working, no interpolation
302 s=getSample(wf, (so->cp>>10));
303 */
304
305 299
300 if( (cpShifted >= (wf->wavSize>>1)) && (so->state != STATE_RAMPDOWN))
301 stopVoice(so);
306 302
307 int s2=getSample(wf, (so->cp>>10)+1); 303 s2 = getSample((cpShifted)+1);
308 304
309 if((wf->mode & (LOOP_REVERSE|LOOP_PINGPONG)) && so->loopState == STATE_LOOPING && (so->cp>>10 <= (wf->startLoop>>1))) 305 if((wf->mode & (LOOP_REVERSE|LOOP_PINGPONG)) && so->loopState == STATE_LOOPING && (cpShifted <= (wf->startLoop>>1)))
310 { 306 {
311 if(wf->mode & LOOP_REVERSE) 307 if(wf->mode & LOOP_REVERSE)
312 { 308 {
313 so->cp = (wf->endLoop)<<9; 309 so->cp = (wf->endLoop)<<9;
314 s2=getSample(wf, (so->cp>>10)); 310 cpShifted = so->cp >> 10;
311 s2=getSample((cpShifted));
315 } else 312 } else
313 {
314 so->delta = -so->delta;
316 so->loopDir = LOOPDIR_FORWARD; 315 so->loopDir = LOOPDIR_FORWARD;
316 }
317 } 317 }
318 318
319 if((wf->mode & 28) && (so->cp>>10 >= wf->endLoop>>1)) 319 if((wf->mode & 28) && (so->cp>>10 >= wf->endLoop>>1))
@@ -322,14 +322,21 @@ inline signed short int synthVoice(int v)
322 if((wf->mode & (24)) == 0) 322 if((wf->mode & (24)) == 0)
323 { 323 {
324 so->cp = (wf->startLoop)<<9; 324 so->cp = (wf->startLoop)<<9;
325 s2=getSample(wf, (so->cp>>10)); 325 cpShifted = so->cp >> 10;
326 s2=getSample((cpShifted));
326 } else 327 } else
328 {
329 so->delta = -so->delta;
327 so->loopDir = LOOPDIR_REVERSE; 330 so->loopDir = LOOPDIR_REVERSE;
331 }
328 } 332 }
329 333
330 //Better, working, linear interpolation 334 //Better, working, linear interpolation
331 int s1=getSample(wf, (so->cp>>10)); 335 s1=getSample((cpShifted));
332 s = s1 + ((long)((s2 - s1) * (so->cp & 1023))>>10); 336 s = s1 + ((signed)((s2 - s1) * (so->cp & 1023))>>10);
337
338
339//ADSR COMMENT WOULD GO FROM HERE.........
333 340
334 if(so->curRate == 0) 341 if(so->curRate == 0)
335 stopVoice(so); 342 stopVoice(so);
@@ -366,8 +373,9 @@ inline signed short int synthVoice(int v)
366 so->isUsed=0; //This is OK 373 so->isUsed=0; //This is OK
367 374
368 375
369 s = s * (so->curOffset >> 22); 376 s = (s * (so->curOffset >> 22) >> 6);
370 s = s>>6; 377
378// ............. TO HERE
371 379
372 380
373 if(so->state == STATE_RAMPDOWN) 381 if(so->state == STATE_RAMPDOWN)
@@ -377,64 +385,28 @@ inline signed short int synthVoice(int v)
377 so->isUsed=0; 385 so->isUsed=0;
378 } 386 }
379 387
380 s = s * so->decay; s = s >> 9; 388 s = s * so->decay; s = s >> 10;
381 389
382 return s*((signed short int)so->vol*(signed short int)chVol[so->ch])>>14; 390 return s*((signed short int)so->vol*(signed short int)chVol[so->ch])>>14;
383} 391}
384 392
385 393
386
387int mhL[16];
388int mhR[16];
389int mp=0; //Mix position, for circular array
390// Was stuff for Ghetto Lowpass Filter, now deprecated.
391
392
393inline void synthSample(int * mixL, int * mixR) 394inline void synthSample(int * mixL, int * mixR)
394{ 395{
395 int a=0; 396// signed int leftMix=0, rightMix=0,
396 signed long int leftMix=0, rightMix=0, sample=0; 397 *mixL = 0;
397 for(a=0; a<MAX_VOICES; a++) 398 *mixR = 0;
399 for(currentVoice=0; currentVoice<MAX_VOICES; currentVoice++)
398 { 400 {
399 if(voices[a].isUsed==1) 401 if(voices[currentVoice].isUsed==1)
400 { 402 {
401 sample = synthVoice(a); 403 sample = synthVoice(currentVoice);
402 404 *mixL += (sample*chPanLeft[voices[currentVoice].ch])>>7;
403 leftMix += (sample*chPanLeft[voices[a].ch])>>7; 405 *mixR += (sample*chPanRight[voices[currentVoice].ch])>>7;
404 rightMix += (sample*chPanRight[voices[a].ch])>>7;
405 } 406 }
406 } 407 }
407 408
408 //TODO: Automatic Gain Control, anyone? 409 //TODO: Automatic Gain Control, anyone?
409 //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?
410 *mixL = leftMix;
411 *mixR = rightMix;
412
413 return; //No more ghetto lowpass filter.. linear intrpolation works well. 411 return; //No more ghetto lowpass filter.. linear intrpolation works well.
414
415
416 // HACK HACK HACK
417 // This is the infamous Ghetto Lowpass Filter
418 // Now that I have linear interpolation, it should not be needed anymore.
419 /*
420 mp++;
421 if(mp==4)
422 mp=0;
423
424 mhL[mp]=leftMix;
425 mhR[mp]=rightMix;
426
427 *mixL = 0;
428 *mixR = 0;
429
430
431 for(a=0; a<4; a++)
432 {
433 *mixL += mhL[a];
434 *mixR += mhR[a];
435 }
436 *mixL = *mixL>>4;
437 *mixR = *mixR>>4;
438 */
439 // END HACK END HACK END HACK
440} 412}
diff --git a/apps/plugins/midi2wav.c b/apps/plugins/midi2wav.c
index 3cf2866a12..6dc7a626b5 100644
--- a/apps/plugins/midi2wav.c
+++ b/apps/plugins/midi2wav.c
@@ -16,7 +16,7 @@
16 * 16 *
17 ****************************************************************************/ 17 ****************************************************************************/
18 18
19#define SAMPLE_RATE 48000 19#define SAMPLE_RATE 22050
20#define MAX_VOICES 100 20#define MAX_VOICES 100
21 21
22 22
@@ -37,6 +37,12 @@
37 37
38 38
39#include "../../plugin.h" 39#include "../../plugin.h"
40
41#include "lib/xxx2wav.h"
42
43int numberOfSamples IDATA_ATTR;
44long bpm;
45
40#include "midi/midiutil.c" 46#include "midi/midiutil.c"
41#include "midi/guspat.h" 47#include "midi/guspat.h"
42#include "midi/guspat.c" 48#include "midi/guspat.c"
@@ -46,7 +52,6 @@
46 52
47 53
48 54
49#include "lib/xxx2wav.h"
50 55
51int fd=-1; //File descriptor where the output is written 56int fd=-1; //File descriptor where the output is written
52 57
@@ -58,6 +63,7 @@ struct plugin_api * rb;
58 63
59 64
60 65
66
61enum plugin_status plugin_start(struct plugin_api* api, void* parameter) 67enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
62{ 68{
63 TEST_PLUGIN_API(api); 69 TEST_PLUGIN_API(api);
@@ -80,6 +86,14 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
80 return PLUGIN_OK; 86 return PLUGIN_OK;
81} 87}
82 88
89signed char outputBuffer[3000] IDATA_ATTR; //signed char.. gonna run out of iram ... !
90
91
92int currentSample IDATA_ATTR;
93int outputBufferPosition IDATA_ATTR;
94int outputSampleOne IDATA_ATTR;
95int outputSampleTwo IDATA_ATTR;
96
83 97
84int midimain(void * filename) 98int midimain(void * filename)
85{ 99{
@@ -89,9 +103,6 @@ int midimain(void * filename)
89 rb->splash(HZ/5, true, "LOADING MIDI"); 103 rb->splash(HZ/5, true, "LOADING MIDI");
90 104
91 struct MIDIfile * mf = loadFile(filename); 105 struct MIDIfile * mf = loadFile(filename);
92 long bpm, nsmp, l;
93
94 int bp=0;
95 106
96 rb->splash(HZ/5, true, "LOADING PATCHES"); 107 rb->splash(HZ/5, true, "LOADING PATCHES");
97 if (initSynth(mf, "/.rockbox/patchset/patchset.cfg", "/.rockbox/patchset/drums.cfg") == -1) 108 if (initSynth(mf, "/.rockbox/patchset/patchset.cfg", "/.rockbox/patchset/drums.cfg") == -1)
@@ -125,7 +136,7 @@ int midimain(void * filename)
125 samp=arg; 136 samp=arg;
126#else 137#else
127 file_info_struct file_info; 138 file_info_struct file_info;
128 file_info.samplerate = 48000; 139 file_info.samplerate = SAMPLE_RATE;
129 file_info.infile = fd; 140 file_info.infile = fd;
130 file_info.channels = 2; 141 file_info.channels = 2;
131 file_info.bitspersample = 16; 142 file_info.bitspersample = 16;
@@ -134,12 +145,11 @@ int midimain(void * filename)
134#endif 145#endif
135 146
136 147
137 rb->splash(HZ/5, true, " START PLAYING "); 148 rb->splash(HZ/5, true, " Starting Playback ");
138 149
139 150
140 151
141 152
142 signed char buf[3000];
143 153
144 // tick() will do one MIDI clock tick. Then, there's a loop here that 154 // tick() will do one MIDI clock tick. Then, there's a loop here that
145 // will generate the right number of samples per MIDI tick. The whole 155 // will generate the right number of samples per MIDI tick. The whole
@@ -152,49 +162,56 @@ int midimain(void * filename)
152 162
153 printf("\nOkay, starting sequencing"); 163 printf("\nOkay, starting sequencing");
154 164
165
166 currentSample=0; //Sample counting variable
167 outputBufferPosition = 0;
168
169
170 bpm=mf->div*1000000/tempo;
171 numberOfSamples=SAMPLE_RATE/bpm;
172
173
174
155 //Tick() will return 0 if there are no more events left to play 175 //Tick() will return 0 if there are no more events left to play
156 while(tick(mf)) 176 while(tick(mf))
157 { 177 {
158 178
159 //Some annoying math to compute the number of samples 179 //Some annoying math to compute the number of samples
160 //to syntehsize per each MIDI tick. 180 //to syntehsize per each MIDI tick.
161 bpm=mf->div*1000000/tempo;
162 nsmp=SAMPLE_RATE/bpm;
163 181
164 //Yes we need to do this math each time because the tempo 182 //Yes we need to do this math each time because the tempo
165 //could have changed. 183 //could have changed.
166 184
167 // On second thought, this can be moved to the event that 185 // On second thought, this can be moved to the event that
168 //recalculates the tempo, to save a little bit of CPU time. 186 //recalculates the tempo, to save a little bit of CPU time.
169 for(l=0; l<nsmp; l++) 187 for(currentSample=0; currentSample<numberOfSamples; currentSample++)
170 { 188 {
171 int s1, s2;
172 189
173 synthSample(&s1, &s2); 190 synthSample(&outputSampleOne, &outputSampleTwo);
174 191
175 192
176 //16-bit audio because, well, it's better 193 //16-bit audio because, well, it's better
177 // But really because ALSA's OSS emulation sounds extremely 194 // But really because ALSA's OSS emulation sounds extremely
178 //noisy and distorted when in 8-bit mode. I still do not know 195 //noisy and distorted when in 8-bit mode. I still do not know
179 //why this happens. 196 //why this happens.
180 buf[bp]=s1&0XFF; // Low byte first 197 outputBuffer[outputBufferPosition]=outputSampleOne&0XFF; // Low byte first
181 bp++; 198 outputBufferPosition++;
182 buf[bp]=s1>>8; //High byte second 199 outputBuffer[outputBufferPosition]=outputSampleOne>>8; //High byte second
183 bp++; 200 outputBufferPosition++;
184 201
185 buf[bp]=s2&0XFF; // Low byte first 202 outputBuffer[outputBufferPosition]=outputSampleTwo&0XFF; // Low byte first
186 bp++; 203 outputBufferPosition++;
187 buf[bp]=s2>>8; //High byte second 204 outputBuffer[outputBufferPosition]=outputSampleTwo>>8; //High byte second
188 bp++; 205 outputBufferPosition++;
189 206
190 207
191 //As soon as we produce 2000 bytes of sound, 208 //As soon as we produce 2000 bytes of sound,
192 //write it to the sound card. Why 2000? I have 209 //write it to the sound card. Why 2000? I have
193 //no idea. It's 1 AM and I am dead tired. 210 //no idea. It's 1 AM and I am dead tired.
194 if(bp>=2000) 211 if(outputBufferPosition>=2000)
195 { 212 {
196 rb->write(fd, buf, 2000); 213 rb->write(fd, outputBuffer, 2000);
197 bp=0; 214 outputBufferPosition=0;
198 } 215 }
199 } 216 }
200 } 217 }