diff options
Diffstat (limited to 'apps/plugins/midi2wav.c')
-rw-r--r-- | apps/plugins/midi2wav.c | 65 |
1 files changed, 41 insertions, 24 deletions
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 | |||
43 | int numberOfSamples IDATA_ATTR; | ||
44 | long 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 | ||
51 | int fd=-1; //File descriptor where the output is written | 56 | int 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 | |||
61 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | 67 | enum 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 | ||
89 | signed char outputBuffer[3000] IDATA_ATTR; //signed char.. gonna run out of iram ... ! | ||
90 | |||
91 | |||
92 | int currentSample IDATA_ATTR; | ||
93 | int outputBufferPosition IDATA_ATTR; | ||
94 | int outputSampleOne IDATA_ATTR; | ||
95 | int outputSampleTwo IDATA_ATTR; | ||
96 | |||
83 | 97 | ||
84 | int midimain(void * filename) | 98 | int 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 | } |