diff options
-rw-r--r-- | apps/plugins/SOURCES | 2 | ||||
-rw-r--r-- | apps/plugins/midi/guspat.c | 14 | ||||
-rw-r--r-- | apps/plugins/midi/midifile.c | 40 | ||||
-rw-r--r-- | apps/plugins/midi/midiutil.c | 48 | ||||
-rw-r--r-- | apps/plugins/midi/sequencer.c | 109 | ||||
-rw-r--r-- | apps/plugins/midi/synth.c | 83 | ||||
-rw-r--r-- | apps/plugins/midiplay.c | 217 | ||||
-rw-r--r-- | apps/plugins/viewers.config | 2 |
8 files changed, 400 insertions, 115 deletions
diff --git a/apps/plugins/SOURCES b/apps/plugins/SOURCES index 1f64e9140b..edcbe3e53b 100644 --- a/apps/plugins/SOURCES +++ b/apps/plugins/SOURCES | |||
@@ -99,7 +99,7 @@ nim.c | |||
99 | 99 | ||
100 | #if CONFIG_CODEC == SWCODEC /* software codec platforms */ | 100 | #if CONFIG_CODEC == SWCODEC /* software codec platforms */ |
101 | mp3_encoder.c | 101 | mp3_encoder.c |
102 | midi2wav.c | 102 | midiplay.c |
103 | wav2wv.c | 103 | wav2wv.c |
104 | #else /* hardware codec platforms */ | 104 | #else /* hardware codec platforms */ |
105 | #ifndef HAVE_MMC /* not for Ondio, has no remote control pin */ | 105 | #ifndef HAVE_MMC /* not for Ondio, has no remote control pin */ |
diff --git a/apps/plugins/midi/guspat.c b/apps/plugins/midi/guspat.c index 6f1866cd58..4b5e7a6a28 100644 --- a/apps/plugins/midi/guspat.c +++ b/apps/plugins/midi/guspat.c | |||
@@ -31,11 +31,11 @@ unsigned int readDWord(int file) | |||
31 | 31 | ||
32 | struct GWaveform * loadWaveform(int file) | 32 | struct GWaveform * loadWaveform(int file) |
33 | { | 33 | { |
34 | struct GWaveform * wav = (struct GWaveform *)allocate(sizeof(struct GWaveform)); | 34 | struct GWaveform * wav = (struct GWaveform *)malloc(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); |
@@ -62,7 +62,7 @@ struct GWaveform * loadWaveform(int 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 | ||
@@ -137,7 +137,7 @@ int selectWaveform(struct GPatch * pat, int midiNote) | |||
137 | 137 | ||
138 | struct GPatch * gusload(char * filename) | 138 | struct GPatch * gusload(char * filename) |
139 | { | 139 | { |
140 | struct GPatch * gp = (struct GPatch *)allocate(sizeof(struct GPatch)); | 140 | struct GPatch * gp = (struct GPatch *)malloc(sizeof(struct GPatch)); |
141 | rb->memset(gp, 0, sizeof(struct GPatch)); | 141 | rb->memset(gp, 0, sizeof(struct GPatch)); |
142 | 142 | ||
143 | int file = rb->open(filename, O_RDONLY); | 143 | int file = rb->open(filename, O_RDONLY); |
@@ -175,15 +175,15 @@ struct GPatch * gusload(char * filename) | |||
175 | gp->layerRes=readData(file,40); | 175 | gp->layerRes=readData(file,40); |
176 | 176 | ||
177 | 177 | ||
178 | printf("\nFILE: %s", filename); | 178 | /* printf("\nFILE: %s", filename); */ |
179 | printf("\nlayerSamples=%d", gp->numWaves); | 179 | /* printf("\nlayerSamples=%d", gp->numWaves); */ |
180 | 180 | ||
181 | int a=0; | 181 | int a=0; |
182 | for(a=0; a<gp->numWaves; a++) | 182 | for(a=0; a<gp->numWaves; a++) |
183 | gp->waveforms[a] = loadWaveform(file); | 183 | gp->waveforms[a] = loadWaveform(file); |
184 | 184 | ||
185 | 185 | ||
186 | printf("\nPrecomputing note table"); | 186 | /* printf("\nPrecomputing note table"); */ |
187 | 187 | ||
188 | for(a=0; a<128; a++) | 188 | for(a=0; a<128; a++) |
189 | { | 189 | { |
diff --git a/apps/plugins/midi/midifile.c b/apps/plugins/midi/midifile.c index 412cc6104d..61168f9d39 100644 --- a/apps/plugins/midi/midifile.c +++ b/apps/plugins/midi/midifile.c | |||
@@ -26,7 +26,7 @@ void bail(const char *); | |||
26 | 26 | ||
27 | struct MIDIfile * loadFile(char * filename) | 27 | struct MIDIfile * loadFile(char * filename) |
28 | { | 28 | { |
29 | struct MIDIfile * mf; | 29 | struct MIDIfile * mfload; |
30 | int file = rb->open (filename, O_RDONLY); | 30 | int file = rb->open (filename, O_RDONLY); |
31 | 31 | ||
32 | if(file==-1) | 32 | if(file==-1) |
@@ -34,15 +34,15 @@ struct MIDIfile * loadFile(char * filename) | |||
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 | mfload = (struct MIDIfile*)malloc(sizeof(struct MIDIfile)); |
38 | 38 | ||
39 | if(mf==NULL) | 39 | if(mfload==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(mfload, 0, sizeof(struct MIDIfile)); |
46 | 46 | ||
47 | if(readID(file) != ID_MTHD) | 47 | if(readID(file) != ID_MTHD) |
48 | { | 48 | { |
@@ -62,32 +62,32 @@ struct MIDIfile * loadFile(char * filename) | |||
62 | bail("MIDI file type not supported"); | 62 | bail("MIDI file type not supported"); |
63 | } | 63 | } |
64 | 64 | ||
65 | mf->numTracks = readTwoBytes(file); | 65 | mfload->numTracks = readTwoBytes(file); |
66 | mf->div = readTwoBytes(file); | 66 | mfload->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", mfload->numTracks, mfload->div); |
71 | 71 | ||
72 | 72 | ||
73 | while(! eof(file) && track < mf->numTracks) | 73 | while(! eof(file) && track < mfload->numTracks) |
74 | { | 74 | { |
75 | unsigned char id = readID(file); | 75 | unsigned char id = readID(file); |
76 | 76 | ||
77 | 77 | ||
78 | if(id == ID_EOF) | 78 | if(id == ID_EOF) |
79 | { | 79 | { |
80 | if(mf->numTracks != track) | 80 | if(mfload->numTracks != track) |
81 | { | 81 | { |
82 | printf("\nError: file claims to have %d tracks.\n I only see %d here.\n", mf->numTracks, track); | 82 | printf("\nError: file claims to have %d tracks.\n I only see %d here.\n", mfload->numTracks, track); |
83 | mf->numTracks = track; | 83 | mfload->numTracks = track; |
84 | } | 84 | } |
85 | return mf; | 85 | return mfload; |
86 | } | 86 | } |
87 | 87 | ||
88 | if(id == ID_MTRK) | 88 | if(id == ID_MTRK) |
89 | { | 89 | { |
90 | mf->tracks[track] = readTrack(file); | 90 | mfload->tracks[track] = readTrack(file); |
91 | //exit(0); | 91 | //exit(0); |
92 | track++; | 92 | track++; |
93 | } else | 93 | } else |
@@ -98,16 +98,16 @@ struct MIDIfile * loadFile(char * filename) | |||
98 | readChar(file); | 98 | readChar(file); |
99 | } | 99 | } |
100 | } | 100 | } |
101 | return mf; | 101 | return mfload; |
102 | 102 | ||
103 | } | 103 | } |
104 | 104 | ||
105 | 105 | ||
106 | int rStatus = 0; | ||
107 | |||
108 | /* Returns 0 if done, 1 if keep going */ | 106 | /* Returns 0 if done, 1 if keep going */ |
109 | int readEvent(int file, void * dest) | 107 | int readEvent(int file, void * dest) |
110 | { | 108 | { |
109 | |||
110 | static int rStatus = 0; | ||
111 | struct Event dummy; | 111 | struct Event dummy; |
112 | struct Event * ev = (struct Event *) dest; | 112 | struct Event * ev = (struct Event *) dest; |
113 | 113 | ||
@@ -131,7 +131,7 @@ int readEvent(int file, void * dest) | |||
131 | if(dest != NULL) | 131 | if(dest != NULL) |
132 | { | 132 | { |
133 | ev->evData = readData(file, ev->len); | 133 | ev->evData = readData(file, ev->len); |
134 | printf("\nDATA: <%s>", ev->evData); | 134 | /* printf("\nDATA: <%s>", ev->evData); */ |
135 | } | 135 | } |
136 | else | 136 | else |
137 | { | 137 | { |
@@ -173,11 +173,9 @@ int readEvent(int file, void * dest) | |||
173 | return 1; | 173 | return 1; |
174 | } | 174 | } |
175 | 175 | ||
176 | |||
177 | |||
178 | struct Track * readTrack(int file) | 176 | struct Track * readTrack(int file) |
179 | { | 177 | { |
180 | struct Track * trk = (struct Track *)allocate(sizeof(struct Track)); | 178 | struct Track * trk = (struct Track *)malloc(sizeof(struct Track)); |
181 | rb->memset(trk, 0, sizeof(struct Track)); | 179 | rb->memset(trk, 0, sizeof(struct Track)); |
182 | 180 | ||
183 | trk->size = readFourBytes(file); | 181 | trk->size = readFourBytes(file); |
@@ -194,7 +192,7 @@ struct Track * readTrack(int file) | |||
194 | rb->lseek(file, pos, SEEK_SET); | 192 | rb->lseek(file, pos, SEEK_SET); |
195 | 193 | ||
196 | int trackSize = (numEvents+1) * sizeof(struct Event); | 194 | int trackSize = (numEvents+1) * sizeof(struct Event); |
197 | void * dataPtr = allocate(trackSize); | 195 | void * dataPtr = malloc(trackSize); |
198 | trk->dataBlock = dataPtr; | 196 | trk->dataBlock = dataPtr; |
199 | 197 | ||
200 | numEvents=0; | 198 | numEvents=0; |
diff --git a/apps/plugins/midi/midiutil.c b/apps/plugins/midi/midiutil.c index d0b968e52c..8e27e739e7 100644 --- a/apps/plugins/midi/midiutil.c +++ b/apps/plugins/midi/midiutil.c | |||
@@ -63,11 +63,11 @@ | |||
63 | extern struct plugin_api * rb; | 63 | extern struct plugin_api * rb; |
64 | 64 | ||
65 | 65 | ||
66 | int chVol[16] IDATA_ATTR; /* Channel volume */ | 66 | int chVol[16] IBSS_ATTR; /* Channel volume */ |
67 | int chPanLeft[16] IDATA_ATTR; /* Channel panning */ | 67 | int chPanLeft[16] IBSS_ATTR; /* Channel panning */ |
68 | int chPanRight[16] IDATA_ATTR; | 68 | int chPanRight[16] IBSS_ATTR; |
69 | int chPat[16]; /* Channel patch */ | 69 | int chPat[16] IBSS_ATTR; /* Channel patch */ |
70 | int chPW[16]; /* Channel pitch wheel, MSB only */ | 70 | int chPW[16] IBSS_ATTR; /* Channel pitch wheel, MSB only */ |
71 | 71 | ||
72 | 72 | ||
73 | struct GPatch * gusload(char *); | 73 | struct GPatch * gusload(char *); |
@@ -128,12 +128,9 @@ struct SynthObject | |||
128 | int curPoint; | 128 | int curPoint; |
129 | }; | 129 | }; |
130 | 130 | ||
131 | struct SynthObject voices[MAX_VOICES] IDATA_ATTR; | 131 | struct SynthObject voices[MAX_VOICES] IBSS_ATTR; |
132 | |||
133 | |||
134 | 132 | ||
135 | void sendEvent(struct Event * ev); | 133 | void sendEvent(struct Event * ev); |
136 | int tick(struct MIDIfile * mf); | ||
137 | inline void setPoint(struct SynthObject * so, int pt); | 134 | inline void setPoint(struct SynthObject * so, int pt); |
138 | struct Event * getEvent(struct Track * tr, int evNum); | 135 | struct Event * getEvent(struct Track * tr, int evNum); |
139 | int readTwoBytes(int file); | 136 | int readTwoBytes(int file); |
@@ -196,8 +193,11 @@ void *alloc(int size) | |||
196 | offset += size + 4; | 193 | offset += size + 4; |
197 | totalSize -= size + 4; | 194 | totalSize -= size + 4; |
198 | return ret; | 195 | return ret; |
199 | }*/ | 196 | } |
200 | void * allocate(int size) | 197 | */ |
198 | |||
199 | #define malloc(n) my_malloc(n) | ||
200 | void * my_malloc(int size) | ||
201 | { | 201 | { |
202 | return alloc(size); | 202 | return alloc(size); |
203 | } | 203 | } |
@@ -211,7 +211,7 @@ unsigned char readChar(int file) | |||
211 | 211 | ||
212 | unsigned char * readData(int file, int len) | 212 | unsigned char * readData(int file, int len) |
213 | { | 213 | { |
214 | unsigned char * dat = allocate(len); | 214 | unsigned char * dat = malloc(len); |
215 | rb->read(file, dat, len); | 215 | rb->read(file, dat, len); |
216 | return dat; | 216 | return dat; |
217 | } | 217 | } |
@@ -226,7 +226,29 @@ int eof(int fd) | |||
226 | return size+1 == rb->lseek(fd, 0, SEEK_CUR); | 226 | return size+1 == rb->lseek(fd, 0, SEEK_CUR); |
227 | } | 227 | } |
228 | 228 | ||
229 | void printf(char *fmt, ...) {fmt=fmt; } | 229 | // Here is a hacked up printf command to get the output from the game. |
230 | int printf(const char *fmt, ...) | ||
231 | { | ||
232 | static int p_xtpt; | ||
233 | char p_buf[50]; | ||
234 | bool ok; | ||
235 | va_list ap; | ||
236 | |||
237 | va_start(ap, fmt); | ||
238 | ok = rb->vsnprintf(p_buf,sizeof(p_buf), fmt, ap); | ||
239 | va_end(ap); | ||
240 | |||
241 | rb->lcd_putsxy(1,p_xtpt, (unsigned char *)p_buf); | ||
242 | rb->lcd_update(); | ||
243 | |||
244 | p_xtpt+=8; | ||
245 | if(p_xtpt>LCD_HEIGHT-8) | ||
246 | { | ||
247 | p_xtpt=0; | ||
248 | rb->lcd_clear_display(); | ||
249 | } | ||
250 | return 1; | ||
251 | } | ||
230 | 252 | ||
231 | void exit(int code) | 253 | void exit(int code) |
232 | { | 254 | { |
diff --git a/apps/plugins/midi/sequencer.c b/apps/plugins/midi/sequencer.c index 4ae5a9f5fe..3c026276c2 100644 --- a/apps/plugins/midi/sequencer.c +++ b/apps/plugins/midi/sequencer.c | |||
@@ -22,22 +22,22 @@ extern struct plugin_api * rb; | |||
22 | long tempo=375000; | 22 | long tempo=375000; |
23 | 23 | ||
24 | 24 | ||
25 | void setVol(int ch, int vol) | 25 | inline void 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 | ||
31 | void setPan(int ch, int pan) | 31 | inline void 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 | ||
40 | void setPatch(int ch, int pat) | 40 | inline void setPatch(int ch, int pat) |
41 | { | 41 | { |
42 | chPat[ch]=pat; | 42 | chPat[ch]=pat; |
43 | } | 43 | } |
@@ -52,18 +52,64 @@ void setPatch(int ch, int pat) | |||
52 | /* | 52 | /* |
53 | long pitchTbl[]= | 53 | long pitchTbl[]= |
54 | { | 54 | { |
55 | 58386,58491,58597,58703,58809,58915,59022,59128,59235,59342,59449,59557,59664,59772,59880,59988,60097,60205, | 55 | 58386,58491,58597,58703,58809,58915,59022,59128,59235,59342,59449,59557, |
56 | 60314,60423,60532,60642,60751,60861,60971,61081,61191,61302,61413,61524,61635,61746,61858,61970,62081,62194, | 56 | 59664,59772,59880,59988,60097,60205,60314,60423,60532,60642,60751,60861, |
57 | 62306,62419,62531,62644,62757,62871,62984,63098,63212,63326,63441,63555,63670,63785,63901,64016,64132,64248, | 57 | 60971,61081,61191,61302,61413,61524,61635,61746,61858,61970,62081,62194, |
58 | 64364,64480,64596,64713,64830,64947,65065,65182,65300,65418,65536,65654,65773,65892,66011,66130,66250,66369, | 58 | 62306,62419,62531,62644,62757,62871,62984,63098,63212,63326,63441,63555, |
59 | 66489,66609,66730,66850,66971,67092,67213,67335,67456,67578,67700,67823,67945,68068,68191,68314,68438,68561, | 59 | 63670,63785,63901,64016,64132,64248,64364,64480,64596,64713,64830,64947, |
60 | 68685,68809,68933,69058,69183,69308,69433,69558,69684,69810,69936,70062,70189,70316,70443,70570,70698,70825, | 60 | 65065,65182,65300,65418,65536,65654,65773,65892,66011,66130,66250,66369, |
61 | 70953,71082,71210,71339,71468,71597,71726,71856,71985,72115,72246,72376,72507,72638,72769,72901,73032,73164, | 61 | 66489,66609,66730,66850,66971,67092,67213,67335,67456,67578,67700,67823, |
62 | 73297,73429 | 62 | 67945,68068,68191,68314,68438,68561,68685,68809,68933,69058,69183,69308, |
63 | 69433,69558,69684,69810,69936,70062,70189,70316,70443,70570,70698,70825, | ||
64 | 70953,71082,71210,71339,71468,71597,71726,71856,71985,72115,72246,72376, | ||
65 | 72507,72638,72769,72901,73032,73164,73297,73429 | ||
63 | }; | 66 | }; |
64 | */ | 67 | */ |
65 | long pitchTbl[]={ | 68 | |
66 | 58386,58412,58439,58465,58491,58518,58544,58571,58597,58624,58650,58676,58703,58729,58756,58782,58809,58836,58862,58889,58915,58942,58968,58995,59022,59048,59075,59102,59128,59155,59182,59208,59235,59262,59289,59315,59342,59369,59396,59423,59449,59476,59503,59530,59557,59584,59611,59638,59664,59691,59718,59745,59772,59799,59826,59853,59880,59907,59934,59961,59988,60015,60043,60070,60097,60124,60151,60178,60205,60233,60260,60287,60314,60341,60369,60396,60423,60450,60478,60505,60532,60560,60587,60614,60642,60669,60696,60724,60751,60779,60806,60833,60861,60888,60916,60943,60971,60998,61026,61054,61081,61109,61136,61164,61191,61219,61247,61274,61302,61330,61357,61385,61413,61440,61468,61496,61524,61551,61579,61607,61635,61663,61690,61718,61746,61774,61802,61830,61858,61886,61914,61942,61970,61997,62025,62053,62081,62109,62138,62166,62194,62222,62250,62278,62306,62334,62362,62390,62419,62447,62475,62503,62531,62560,62588,62616,62644,62673,62701,62729,62757,62786,62814,62843,62871,62899,62928,62956,62984,63013,63041,63070,63098,63127,63155,63184,63212,63241,63269,63298,63326,63355,63384,63412,63441,63470,63498,63527,63555,63584,63613,63642,63670,63699,63728,63757,63785,63814,63843,63872,63901,63929,63958,63987,64016,64045,64074,64103,64132,64161,64190,64219,64248,64277,64306,64335,64364,64393,64422,64451,64480,64509,64538,64567,64596,64626,64655,64684,64713,64742,64772,64801,64830,64859,64889,64918,64947,64976,65006,65035,65065,65094,65123,65153,65182,65211,65241,65270,65300,65329,65359,65388,65418,65447,65477,65506,65536,65566,65595,65625,65654,65684,65714,65743,65773,65803,65832,65862,65892,65922,65951,65981,66011,66041,66071,66100,66130,66160,66190,66220,66250,66280,66309,66339,66369,66399,66429,66459,66489,66519,66549,66579,66609,66639,66670,66700,66730,66760,66790,66820,66850,66880,66911,66941,66971,67001,67032,67062,67092,67122,67153,67183,67213,67244,67274,67304,67335,67365,67395,67426,67456,67487,67517,67548,67578,67609,67639,67670,67700,67731,67761,67792,67823,67853,67884,67915,67945,67976,68007,68037,68068,68099,68129,68160,68191,68222,68252,68283,68314,68345,68376,68407,68438,68468,68499,68530,68561,68592,68623,68654,68685,68716,68747,68778,68809,68840,68871,68902,68933,68965,68996,69027,69058,69089,69120,69152,69183,69214,69245,69276,69308,69339,69370,69402,69433,69464,69496,69527,69558,69590,69621,69653,69684,69716,69747,69778,69810,69841,69873,69905,69936,69968,69999,70031,70062,70094,70126,70157,70189,70221,70252,70284,70316,70348,70379,70411,70443,70475,70507,70538,70570,70602,70634,70666,70698,70730,70762,70793,70825,70857,70889,70921,70953,70985,71017,71049,71082,71114,71146,71178,71210,71242,71274,71306,71339,71371,71403,71435,71468,71500,71532,71564,71597,71629,71661,71694,71726,71758,71791,71823,71856,71888,71920,71953,71985,72018,72050,72083,72115,72148,72181,72213,72246,72278,72311,72344,72376,72409,72442,72474,72507,72540,72573,72605,72638,72671,72704,72736,72769,72802,72835,72868,72901,72934,72967,72999,73032,73065,73098,73131,73164,73197,73230,73264,73297,73330,73363,73396,73429,73462,73495,73528 | 69 | long pitchTbl[] ICONST_ATTR={ |
70 | 58386,58412,58439,58465,58491,58518,58544,58571,58597,58624,58650,58676, | ||
71 | 58703,58729,58756,58782,58809,58836,58862,58889,58915,58942,58968,58995, | ||
72 | 59022,59048,59075,59102,59128,59155,59182,59208,59235,59262,59289,59315, | ||
73 | 59342,59369,59396,59423,59449,59476,59503,59530,59557,59584,59611,59638, | ||
74 | 59664,59691,59718,59745,59772,59799,59826,59853,59880,59907,59934,59961, | ||
75 | 59988,60015,60043,60070,60097,60124,60151,60178,60205,60233,60260,60287, | ||
76 | 60314,60341,60369,60396,60423,60450,60478,60505,60532,60560,60587,60614, | ||
77 | 60642,60669,60696,60724,60751,60779,60806,60833,60861,60888,60916,60943, | ||
78 | 60971,60998,61026,61054,61081,61109,61136,61164,61191,61219,61247,61274, | ||
79 | 61302,61330,61357,61385,61413,61440,61468,61496,61524,61551,61579,61607, | ||
80 | 61635,61663,61690,61718,61746,61774,61802,61830,61858,61886,61914,61942, | ||
81 | 61970,61997,62025,62053,62081,62109,62138,62166,62194,62222,62250,62278, | ||
82 | 62306,62334,62362,62390,62419,62447,62475,62503,62531,62560,62588,62616, | ||
83 | 62644,62673,62701,62729,62757,62786,62814,62843,62871,62899,62928,62956, | ||
84 | 62984,63013,63041,63070,63098,63127,63155,63184,63212,63241,63269,63298, | ||
85 | 63326,63355,63384,63412,63441,63470,63498,63527,63555,63584,63613,63642, | ||
86 | 63670,63699,63728,63757,63785,63814,63843,63872,63901,63929,63958,63987, | ||
87 | 64016,64045,64074,64103,64132,64161,64190,64219,64248,64277,64306,64335, | ||
88 | 64364,64393,64422,64451,64480,64509,64538,64567,64596,64626,64655,64684, | ||
89 | 64713,64742,64772,64801,64830,64859,64889,64918,64947,64976,65006,65035, | ||
90 | 65065,65094,65123,65153,65182,65211,65241,65270,65300,65329,65359,65388, | ||
91 | 65418,65447,65477,65506,65536,65566,65595,65625,65654,65684,65714,65743, | ||
92 | 65773,65803,65832,65862,65892,65922,65951,65981,66011,66041,66071,66100, | ||
93 | 66130,66160,66190,66220,66250,66280,66309,66339,66369,66399,66429,66459, | ||
94 | 66489,66519,66549,66579,66609,66639,66670,66700,66730,66760,66790,66820, | ||
95 | 66850,66880,66911,66941,66971,67001,67032,67062,67092,67122,67153,67183, | ||
96 | 67213,67244,67274,67304,67335,67365,67395,67426,67456,67487,67517,67548, | ||
97 | 67578,67609,67639,67670,67700,67731,67761,67792,67823,67853,67884,67915, | ||
98 | 67945,67976,68007,68037,68068,68099,68129,68160,68191,68222,68252,68283, | ||
99 | 68314,68345,68376,68407,68438,68468,68499,68530,68561,68592,68623,68654, | ||
100 | 68685,68716,68747,68778,68809,68840,68871,68902,68933,68965,68996,69027, | ||
101 | 69058,69089,69120,69152,69183,69214,69245,69276,69308,69339,69370,69402, | ||
102 | 69433,69464,69496,69527,69558,69590,69621,69653,69684,69716,69747,69778, | ||
103 | 69810,69841,69873,69905,69936,69968,69999,70031,70062,70094,70126,70157, | ||
104 | 70189,70221,70252,70284,70316,70348,70379,70411,70443,70475,70507,70538, | ||
105 | 70570,70602,70634,70666,70698,70730,70762,70793,70825,70857,70889,70921, | ||
106 | 70953,70985,71017,71049,71082,71114,71146,71178,71210,71242,71274,71306, | ||
107 | 71339,71371,71403,71435,71468,71500,71532,71564,71597,71629,71661,71694, | ||
108 | 71726,71758,71791,71823,71856,71888,71920,71953,71985,72018,72050,72083, | ||
109 | 72115,72148,72181,72213,72246,72278,72311,72344,72376,72409,72442,72474, | ||
110 | 72507,72540,72573,72605,72638,72671,72704,72736,72769,72802,72835,72868, | ||
111 | 72901,72934,72967,72999,73032,73065,73098,73131,73164,73197,73230,73264, | ||
112 | 73297,73330,73363,73396,73429,73462,73495,73528 | ||
67 | }; | 113 | }; |
68 | 114 | ||
69 | void findDelta(struct SynthObject * so, int ch, int note) | 115 | void findDelta(struct SynthObject * so, int ch, int note) |
@@ -75,9 +121,9 @@ void findDelta(struct SynthObject * so, int ch, int note) | |||
75 | so->delta = (so->delta * pitchTbl[chPW[ch]])>> 16; | 121 | so->delta = (so->delta * pitchTbl[chPW[ch]])>> 16; |
76 | } | 122 | } |
77 | 123 | ||
78 | void setPW(int ch, int msb, int lsb) | 124 | inline void setPW(int ch, int msb, int lsb) |
79 | { | 125 | { |
80 | printf("\npitchw[%d] %d ==> %d", ch, chPW[ch], msb); | 126 | // printf("\npitchw[%d] %d ==> %d", ch, chPW[ch], msb); |
81 | chPW[ch] = msb<<2|lsb>>5; | 127 | chPW[ch] = msb<<2|lsb>>5; |
82 | 128 | ||
83 | int a=0; | 129 | int a=0; |
@@ -92,7 +138,7 @@ void setPW(int ch, int msb, int lsb) | |||
92 | 138 | ||
93 | void pressNote(int ch, int note, int vol) | 139 | void pressNote(int ch, int note, int vol) |
94 | { | 140 | { |
95 | 141 | static int lastKill = 0; | |
96 | //Silences all channels but one, for easy debugging, for me. | 142 | //Silences all channels but one, for easy debugging, for me. |
97 | /* | 143 | /* |
98 | if(ch == 0) return; | 144 | if(ch == 0) return; |
@@ -123,11 +169,16 @@ void pressNote(int ch, int note, int vol) | |||
123 | } | 169 | } |
124 | if(a==MAX_VOICES-1) | 170 | if(a==MAX_VOICES-1) |
125 | { | 171 | { |
126 | printf("\nOVERFLOW: Too many voices playing at once. No more left"); | 172 | // printf("\nVoice kill"); |
127 | printf("\nVOICE DUMP: "); | 173 | // printf("\nToo many voices playing at once. No more left"); |
128 | for(a=0; a<48; a++) | 174 | // printf("\nVOICE DUMP: "); |
129 | 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); | 175 | // for(a=0; a<48; a++) |
130 | return; /* None available */ | 176 | // 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); |
177 | lastKill++; | ||
178 | if(lastKill == MAX_VOICES) | ||
179 | lastKill = 0; | ||
180 | a = lastKill; | ||
181 | // return; /* None available */ | ||
131 | } | 182 | } |
132 | voices[a].ch=ch; | 183 | voices[a].ch=ch; |
133 | voices[a].note=note; | 184 | voices[a].note=note; |
@@ -163,7 +214,7 @@ void pressNote(int ch, int note, int vol) | |||
163 | voices[a].wf=wf; | 214 | voices[a].wf=wf; |
164 | voices[a].delta = (((gustable[note]<<10) / wf->rootFreq) * wf->sampRate / SAMPLE_RATE); | 215 | voices[a].delta = (((gustable[note]<<10) / wf->rootFreq) * wf->sampRate / SAMPLE_RATE); |
165 | if(wf->mode & 28) | 216 | if(wf->mode & 28) |
166 | printf("\nWoah, a drum patch has a loop. Stripping the loop..."); | 217 | // printf("\nWoah, a drum patch has a loop. Stripping the loop..."); |
167 | wf->mode = wf->mode & (255-28); | 218 | wf->mode = wf->mode & (255-28); |
168 | 219 | ||
169 | /* Turn it on */ | 220 | /* Turn it on */ |
@@ -172,7 +223,7 @@ void pressNote(int ch, int note, int vol) | |||
172 | 223 | ||
173 | } else | 224 | } else |
174 | { | 225 | { |
175 | printf("\nWarning: drum %d does not have a patch defined... Ignoring it", note); | 226 | /* printf("\nWarning: drum %d does not have a patch defined... Ignoring it", note); */ |
176 | } | 227 | } |
177 | } | 228 | } |
178 | } | 229 | } |
@@ -244,11 +295,7 @@ void sendEvent(struct Event * ev) | |||
244 | } | 295 | } |
245 | } | 296 | } |
246 | 297 | ||
247 | 298 | int tick(void) | |
248 | |||
249 | |||
250 | |||
251 | int tick(struct MIDIfile * mf) | ||
252 | { | 299 | { |
253 | if(mf==NULL) | 300 | if(mf==NULL) |
254 | return 0; | 301 | return 0; |
@@ -280,7 +327,7 @@ int tick(struct MIDIfile * mf) | |||
280 | sendEvent(e); | 327 | sendEvent(e); |
281 | if(((e->status&0xF0) == MIDI_PRGM)) | 328 | if(((e->status&0xF0) == MIDI_PRGM)) |
282 | { | 329 | { |
283 | printf("\nPatch Event, patch[%d] ==> %d", e->status&0xF, e->d1); | 330 | /* printf("\nPatch Event, patch[%d] ==> %d", e->status&0xF, e->d1); */ |
284 | } | 331 | } |
285 | } | 332 | } |
286 | else | 333 | else |
diff --git a/apps/plugins/midi/synth.c b/apps/plugins/midi/synth.c index 42ca9ddaf6..44417b2583 100644 --- a/apps/plugins/midi/synth.c +++ b/apps/plugins/midi/synth.c | |||
@@ -104,8 +104,9 @@ int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig) | |||
104 | 104 | ||
105 | if( (getEvent(mf->tracks[a], ts)->status & 0xF0) == MIDI_PRGM) | 105 | if( (getEvent(mf->tracks[a], ts)->status & 0xF0) == MIDI_PRGM) |
106 | { | 106 | { |
107 | if(patchUsed[getEvent(mf->tracks[a], ts)->d1]==0) | 107 | /* if(patchUsed[getEvent(mf->tracks[a], ts)->d1]==0) |
108 | printf("\nI need to load patch %d.", getEvent(mf->tracks[a], ts)->d1); | 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 | patchUsed[getEvent(mf->tracks[a], ts)->d1]=1; |
110 | } | 111 | } |
111 | } | 112 | } |
@@ -124,13 +125,14 @@ int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig) | |||
124 | /* Scan our config file and load the right patches as needed */ | 125 | /* Scan our config file and load the right patches as needed */ |
125 | int c = 0; | 126 | int c = 0; |
126 | rb->snprintf(name, 40, ""); | 127 | rb->snprintf(name, 40, ""); |
128 | printf("\nLoading instruments"); | ||
127 | for(a=0; a<128; a++) | 129 | for(a=0; a<128; a++) |
128 | { | 130 | { |
129 | while(readChar(file)!=' ' && !eof(file)); | 131 | while(readChar(file)!=' ' && !eof(file)); |
130 | readTextBlock(file, name); | 132 | readTextBlock(file, name); |
131 | 133 | ||
132 | rb->snprintf(fn, 40, "/.rockbox/patchset/%s.pat", name); | 134 | rb->snprintf(fn, 40, "/.rockbox/patchset/%s.pat", name); |
133 | printf("\nLOADING: <%s> ", fn); | 135 | /* printf("\nLOADING: <%s> ", fn); */ |
134 | 136 | ||
135 | if(patchUsed[a]==1) | 137 | if(patchUsed[a]==1) |
136 | { | 138 | { |
@@ -155,6 +157,7 @@ int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig) | |||
155 | /* Scan our config file and load the drum data */ | 157 | /* Scan our config file and load the drum data */ |
156 | int idx=0; | 158 | int idx=0; |
157 | char number[30]; | 159 | char number[30]; |
160 | printf("\nLoading drums"); | ||
158 | while(!eof(file)) | 161 | while(!eof(file)) |
159 | { | 162 | { |
160 | readTextBlock(file, number); | 163 | readTextBlock(file, number); |
@@ -168,7 +171,6 @@ int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig) | |||
168 | if(drumUsed[idx]==1) | 171 | if(drumUsed[idx]==1) |
169 | { | 172 | { |
170 | drumSet[idx]=gusload(fn); | 173 | drumSet[idx]=gusload(fn); |
171 | |||
172 | if(drumSet[idx] == NULL) /* Error loading patch */ | 174 | if(drumSet[idx] == NULL) /* Error loading patch */ |
173 | return -1; | 175 | return -1; |
174 | } | 176 | } |
@@ -180,32 +182,14 @@ int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig) | |||
180 | return 0; | 182 | return 0; |
181 | } | 183 | } |
182 | 184 | ||
183 | 185 | inline short getSample(int s,struct GWaveform * wf ) | |
184 | |||
185 | int currentVoice IDATA_ATTR; | ||
186 | struct SynthObject * so IDATA_ATTR; | ||
187 | struct GWaveform * wf IDATA_ATTR; | ||
188 | int s IDATA_ATTR; | ||
189 | short s1 IDATA_ATTR; | ||
190 | short s2 IDATA_ATTR; | ||
191 | short sample IDATA_ATTR; /* For synthSample */ | ||
192 | unsigned int cpShifted IDATA_ATTR; | ||
193 | |||
194 | unsigned char b1 IDATA_ATTR; | ||
195 | unsigned char b2 IDATA_ATTR; | ||
196 | |||
197 | |||
198 | inline int getSample(int s) | ||
199 | { | 186 | { |
200 | /* Sign conversion moved to guspat.c */ | 187 | /* Sign conversion moved to guspat.c */ |
201 | /* 8bit conversion NOT YET IMPLEMENTED in guspat.c */ | 188 | /* 8bit conversion NOT YET IMPLEMENTED in guspat.c */ |
202 | return ((short *) wf->data)[s]; | 189 | return ((short *) wf->data)[s]; |
203 | } | 190 | } |
204 | 191 | ||
205 | 192 | void setPoint(struct SynthObject * so, int pt) | |
206 | |||
207 | |||
208 | inline void setPoint(struct SynthObject * so, int pt) | ||
209 | { | 193 | { |
210 | if(so->ch==9) /* Drums, no ADSR */ | 194 | if(so->ch==9) /* Drums, no ADSR */ |
211 | { | 195 | { |
@@ -227,7 +211,7 @@ inline void setPoint(struct SynthObject * so, int pt) | |||
227 | 211 | ||
228 | so->curPoint = pt; | 212 | so->curPoint = pt; |
229 | 213 | ||
230 | int r=0; | 214 | int r; |
231 | int rate = so->wf->envRate[pt]; | 215 | int rate = so->wf->envRate[pt]; |
232 | 216 | ||
233 | r=3-((rate>>6) & 0x3); /* Some blatant Timidity code for rate conversion... */ | 217 | r=3-((rate>>6) & 0x3); /* Some blatant Timidity code for rate conversion... */ |
@@ -243,15 +227,17 @@ inline void setPoint(struct SynthObject * so, int pt) | |||
243 | * default this to 10, and maybe later have an option to set it to 9 | 227 | * default this to 10, and maybe later have an option to set it to 9 |
244 | * for longer decays. | 228 | * for longer decays. |
245 | */ | 229 | */ |
246 | so->curRate = r<<10; | 230 | so->curRate = r<<11; |
247 | 231 | ||
248 | /* | 232 | /* |
249 | * Do this here because the patches assume a 44100 sampling rate | 233 | * Do this here because the patches assume a 44100 sampling rate |
250 | * We've halved our sampling rate, ergo the ADSR code will be | 234 | * We've halved our sampling rate, ergo the ADSR code will be |
251 | * called half the time. Ergo, double the rate to keep stuff | 235 | * called half the time. Ergo, double the rate to keep stuff |
252 | * sounding right. | 236 | * sounding right. |
237 | * | ||
238 | * Or just move the 1 up one line to optimize a tiny bit. | ||
253 | */ | 239 | */ |
254 | so->curRate = so->curRate << 1; | 240 | /* so->curRate = so->curRate << 1;*/ |
255 | 241 | ||
256 | 242 | ||
257 | so->targetOffset = so->wf->envOffset[pt]<<(20); | 243 | so->targetOffset = so->wf->envOffset[pt]<<(20); |
@@ -270,9 +256,14 @@ inline void stopVoice(struct SynthObject * so) | |||
270 | } | 256 | } |
271 | 257 | ||
272 | 258 | ||
273 | inline signed short int synthVoice(void) | 259 | signed short int synthVoice(struct SynthObject * so) |
274 | { | 260 | { |
275 | so = &voices[currentVoice]; | 261 | struct GWaveform * wf; |
262 | register int s; | ||
263 | register unsigned int cpShifted; | ||
264 | register short s1; | ||
265 | register short s2; | ||
266 | |||
276 | wf = so->wf; | 267 | wf = so->wf; |
277 | 268 | ||
278 | 269 | ||
@@ -288,7 +279,7 @@ inline signed short int synthVoice(void) | |||
288 | stopVoice(so); | 279 | stopVoice(so); |
289 | } | 280 | } |
290 | 281 | ||
291 | s2 = getSample((cpShifted)+1); | 282 | s2 = getSample((cpShifted)+1, wf); |
292 | 283 | ||
293 | /* LOOP_REVERSE|LOOP_PINGPONG = 24 */ | 284 | /* LOOP_REVERSE|LOOP_PINGPONG = 24 */ |
294 | if((wf->mode & (24)) && so->loopState == STATE_LOOPING && (cpShifted <= (wf->startLoop))) | 285 | if((wf->mode & (24)) && so->loopState == STATE_LOOPING && (cpShifted <= (wf->startLoop))) |
@@ -297,8 +288,9 @@ inline signed short int synthVoice(void) | |||
297 | { | 288 | { |
298 | so->cp = (wf->endLoop)<<10; //Was 10 | 289 | so->cp = (wf->endLoop)<<10; //Was 10 |
299 | cpShifted = wf->endLoop; | 290 | cpShifted = wf->endLoop; |
300 | s2=getSample((cpShifted)); | 291 | s2=getSample((cpShifted), wf); |
301 | } else | 292 | } |
293 | else | ||
302 | { | 294 | { |
303 | so->delta = -so->delta; | 295 | so->delta = -so->delta; |
304 | so->loopDir = LOOPDIR_FORWARD; | 296 | so->loopDir = LOOPDIR_FORWARD; |
@@ -312,8 +304,9 @@ inline signed short int synthVoice(void) | |||
312 | { | 304 | { |
313 | so->cp = (wf->startLoop)<<10; //Was 10 | 305 | so->cp = (wf->startLoop)<<10; //Was 10 |
314 | cpShifted = wf->startLoop; | 306 | cpShifted = wf->startLoop; |
315 | s2=getSample((cpShifted)); | 307 | s2=getSample((cpShifted), wf); |
316 | } else | 308 | } |
309 | else | ||
317 | { | 310 | { |
318 | so->delta = -so->delta; | 311 | so->delta = -so->delta; |
319 | so->loopDir = LOOPDIR_REVERSE; | 312 | so->loopDir = LOOPDIR_REVERSE; |
@@ -321,7 +314,7 @@ inline signed short int synthVoice(void) | |||
321 | } | 314 | } |
322 | 315 | ||
323 | /* Better, working, linear interpolation */ | 316 | /* Better, working, linear interpolation */ |
324 | s1=getSample((cpShifted)); //\|/ Was 1023)) >> 10 | 317 | s1=getSample((cpShifted), wf); //\|/ Was 1023)) >> 10 |
325 | s = s1 + ((signed)((s2 - s1) * (so->cp & 1023))>>10); //Was 10 | 318 | s = s1 + ((signed)((s2 - s1) * (so->cp & 1023))>>10); //Was 10 |
326 | 319 | ||
327 | 320 | ||
@@ -381,18 +374,26 @@ inline signed short int synthVoice(void) | |||
381 | 374 | ||
382 | inline void synthSample(int * mixL, int * mixR) | 375 | inline void synthSample(int * mixL, int * mixR) |
383 | { | 376 | { |
384 | *mixL = 0; | 377 | register int dL=0; |
385 | *mixR = 0; | 378 | register int dR=0; |
386 | for(currentVoice=0; currentVoice<MAX_VOICES; currentVoice++) | 379 | register short sample=0; |
380 | register struct SynthObject *voicept=voices; | ||
381 | struct SynthObject *lastvoice=&voices[MAX_VOICES]; | ||
382 | |||
383 | while(voicept!=lastvoice) | ||
387 | { | 384 | { |
388 | if(voices[currentVoice].isUsed==1) | 385 | if(voicept->isUsed==1) |
389 | { | 386 | { |
390 | sample = synthVoice(); | 387 | sample = synthVoice(voicept); |
391 | *mixL += (sample*chPanLeft[voices[currentVoice].ch])>>7; | 388 | dL += (sample*chPanLeft[voicept->ch])>>7; |
392 | *mixR += (sample*chPanRight[voices[currentVoice].ch])>>7; | 389 | dR += (sample*chPanRight[voicept->ch])>>7; |
393 | } | 390 | } |
391 | voicept++; | ||
394 | } | 392 | } |
395 | 393 | ||
394 | *mixL=dL; | ||
395 | *mixR=dR; | ||
396 | |||
396 | /* TODO: Automatic Gain Control, anyone? */ | 397 | /* TODO: Automatic Gain Control, anyone? */ |
397 | /* Or, should this be implemented on the DSP's output volume instead? */ | 398 | /* Or, should this be implemented on the DSP's output volume instead? */ |
398 | 399 | ||
diff --git a/apps/plugins/midiplay.c b/apps/plugins/midiplay.c new file mode 100644 index 0000000000..f279e72e4e --- /dev/null +++ b/apps/plugins/midiplay.c | |||
@@ -0,0 +1,217 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * | ||
9 | * Copyright (C) 2005 Karl Kurbjun based on midi2wav by Stepan Moskovchenko | ||
10 | * | ||
11 | * All files in this archive are subject to the GNU General Public License. | ||
12 | * See the file COPYING in the source tree root for full license agreement. | ||
13 | * | ||
14 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
15 | * KIND, either express or implied. | ||
16 | * | ||
17 | ****************************************************************************/ | ||
18 | |||
19 | #include "../../plugin.h" | ||
20 | |||
21 | PLUGIN_HEADER | ||
22 | |||
23 | #define SAMPLE_RATE 22050 // 44100 22050 11025 | ||
24 | #define MAX_VOICES 12 // Note: 24 midi channels is the minimum general midi | ||
25 | // spec implementation | ||
26 | #define BUF_SIZE 512 | ||
27 | #define NBUF 2 | ||
28 | |||
29 | #undef SYNC | ||
30 | struct MIDIfile * mf IBSS_ATTR; | ||
31 | |||
32 | int numberOfSamples IBSS_ATTR; | ||
33 | long bpm IBSS_ATTR; | ||
34 | |||
35 | #include "midi/midiutil.c" | ||
36 | #include "midi/guspat.h" | ||
37 | #include "midi/guspat.c" | ||
38 | #include "midi/sequencer.c" | ||
39 | #include "midi/midifile.c" | ||
40 | #include "midi/synth.c" | ||
41 | |||
42 | short gmbuf[BUF_SIZE*NBUF] IBSS_ATTR; | ||
43 | |||
44 | int quit=0; | ||
45 | struct plugin_api * rb; | ||
46 | |||
47 | #ifdef USE_IRAM | ||
48 | extern char iramcopy[]; | ||
49 | extern char iramstart[]; | ||
50 | extern char iramend[]; | ||
51 | extern char iedata[]; | ||
52 | extern char iend[]; | ||
53 | #endif | ||
54 | |||
55 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | ||
56 | { | ||
57 | rb = api; | ||
58 | |||
59 | if(parameter == NULL) | ||
60 | { | ||
61 | rb->splash(HZ*2, true, " Play .MID file "); | ||
62 | return PLUGIN_OK; | ||
63 | } | ||
64 | rb->lcd_setfont(0); | ||
65 | |||
66 | #ifdef USE_IRAM | ||
67 | rb->memcpy(iramstart, iramcopy, iramend-iramstart); | ||
68 | rb->memset(iedata, 0, iend - iedata); | ||
69 | #endif | ||
70 | |||
71 | #if !defined(SIMULATOR) && defined(HAVE_ADJUSTABLE_CPU_FREQ) | ||
72 | rb->cpu_boost(true); | ||
73 | #endif | ||
74 | |||
75 | printf("\n%s", parameter); | ||
76 | /* rb->splash(HZ, true, parameter); */ | ||
77 | |||
78 | #ifdef RB_PROFILE | ||
79 | rb->profile_thread(); | ||
80 | #endif | ||
81 | |||
82 | if(midimain(parameter) == -1) | ||
83 | return PLUGIN_ERROR; | ||
84 | |||
85 | #ifdef RB_PROFILE | ||
86 | rb->profstop(); | ||
87 | #endif | ||
88 | |||
89 | #ifndef SIMULATOR | ||
90 | rb->pcm_play_stop(); | ||
91 | rb->pcm_set_frequency(44100); // 44100 | ||
92 | #endif | ||
93 | |||
94 | #if !defined(SIMULATOR) && defined(HAVE_ADJUSTABLE_CPU_FREQ) | ||
95 | rb->cpu_boost(false); | ||
96 | #endif | ||
97 | |||
98 | rb->splash(HZ, true, "FINISHED PLAYING"); | ||
99 | |||
100 | return PLUGIN_OK; | ||
101 | } | ||
102 | |||
103 | bool swap=0; | ||
104 | bool lastswap=1; | ||
105 | |||
106 | inline void synthbuf(void) | ||
107 | { | ||
108 | short *outptr; | ||
109 | register int i; | ||
110 | static int currentSample=0; | ||
111 | int synthtemp[2]; | ||
112 | |||
113 | #ifndef SYNC | ||
114 | if(lastswap==swap) return; | ||
115 | lastswap=swap; | ||
116 | |||
117 | outptr=(swap ? gmbuf : gmbuf+BUF_SIZE); | ||
118 | #else | ||
119 | outptr=gmbuf; | ||
120 | #endif | ||
121 | |||
122 | for(i=0; i<BUF_SIZE/2; i++) | ||
123 | { | ||
124 | synthSample(&synthtemp[0], &synthtemp[1]); | ||
125 | currentSample++; | ||
126 | *outptr=synthtemp[0]&0xFFFF; | ||
127 | outptr++; | ||
128 | *outptr=synthtemp[1]&0xFFFF; | ||
129 | outptr++; | ||
130 | if(currentSample==numberOfSamples) | ||
131 | { | ||
132 | if( tick() == 0 ) quit=1; | ||
133 | currentSample=0; | ||
134 | } | ||
135 | } | ||
136 | } | ||
137 | |||
138 | void get_more(unsigned char** start, size_t* size) | ||
139 | { | ||
140 | #ifndef SYNC | ||
141 | if(lastswap!=swap) | ||
142 | { | ||
143 | printf("Buffer miss!"); // Comment out the printf to make missses less noticable. | ||
144 | /* | ||
145 | int a=0; | ||
146 | for(a=0; a<MAX_VOICES; a++) | ||
147 | { | ||
148 | voices[a].isUsed=0; | ||
149 | } | ||
150 | */ | ||
151 | } | ||
152 | |||
153 | #else | ||
154 | synthbuf(); // For some reason midiplayer crashes when an update is forced | ||
155 | #endif | ||
156 | |||
157 | *size = BUF_SIZE*sizeof(short); | ||
158 | #ifndef SYNC | ||
159 | *start = (unsigned char*)((swap ? gmbuf : gmbuf + BUF_SIZE)); | ||
160 | swap=!swap; | ||
161 | #else | ||
162 | *start = (unsigned char*)(gmbuf); | ||
163 | #endif | ||
164 | } | ||
165 | |||
166 | int midimain(void * filename) | ||
167 | { | ||
168 | int button; | ||
169 | |||
170 | /* rb->splash(HZ/5, true, "LOADING MIDI"); */ | ||
171 | printf("\nLoading file"); | ||
172 | mf= loadFile(filename); | ||
173 | |||
174 | /* rb->splash(HZ/5, true, "LOADING PATCHES"); */ | ||
175 | if (initSynth(mf, "/.rockbox/patchset/patchset.cfg", "/.rockbox/patchset/drums.cfg") == -1) | ||
176 | return -1; | ||
177 | |||
178 | #ifndef SIMULATOR | ||
179 | rb->pcm_play_stop(); | ||
180 | rb->pcm_set_frequency(SAMPLE_RATE); // 44100 22050 11025 | ||
181 | #endif | ||
182 | |||
183 | /* | ||
184 | * tick() will do one MIDI clock tick. Then, there's a loop here that | ||
185 | * will generate the right number of samples per MIDI tick. The whole | ||
186 | * MIDI playback is timed in terms of this value.. there are no forced | ||
187 | * delays or anything. It just produces enough samples for each tick, and | ||
188 | * the playback of these samples is what makes the timings right. | ||
189 | * | ||
190 | * This seems to work quite well. | ||
191 | */ | ||
192 | |||
193 | printf("\nOkay, starting sequencing"); | ||
194 | |||
195 | bpm=mf->div*1000000/tempo; | ||
196 | numberOfSamples=SAMPLE_RATE/bpm; | ||
197 | |||
198 | tick(); | ||
199 | |||
200 | synthbuf(); | ||
201 | #ifndef SIMULATOR | ||
202 | rb->pcm_play_data(&get_more, NULL, 0); | ||
203 | #endif | ||
204 | |||
205 | button=rb->button_status(); | ||
206 | |||
207 | while(!quit) | ||
208 | { | ||
209 | #ifndef SYNC | ||
210 | synthbuf(); | ||
211 | #endif | ||
212 | rb->yield(); | ||
213 | if(rb->button_status()!=button) quit=1; | ||
214 | } | ||
215 | |||
216 | return 0; | ||
217 | } | ||
diff --git a/apps/plugins/viewers.config b/apps/plugins/viewers.config index 6de2bd883a..afab02278b 100644 --- a/apps/plugins/viewers.config +++ b/apps/plugins/viewers.config | |||
@@ -11,7 +11,7 @@ txt,viewers/sort, 00 00 00 00 00 00 | |||
11 | gb,viewers/rockboy, 0C 2A 59 7A 2E 0C | 11 | gb,viewers/rockboy, 0C 2A 59 7A 2E 0C |
12 | gbc,viewers/rockboy, 0C 2A 59 7A 2E 0C | 12 | gbc,viewers/rockboy, 0C 2A 59 7A 2E 0C |
13 | m3u,viewers/iriverify,00 00 00 00 00 00 | 13 | m3u,viewers/iriverify,00 00 00 00 00 00 |
14 | mid,viewers/midi2wav, 20 70 70 3F 00 00 | 14 | mid,viewers/midiplay, 20 70 70 3F 00 00 |
15 | rsp,viewers/searchengine, 0e 11 11 31 7e 60 | 15 | rsp,viewers/searchengine, 0e 11 11 31 7e 60 |
16 | ss,rocks/sudoku, 55 55 55 55 55 55 | 16 | ss,rocks/sudoku, 55 55 55 55 55 55 |
17 | wav,viewers/wav2wv, 00 00 00 00 00 00 | 17 | wav,viewers/wav2wv, 00 00 00 00 00 00 |