summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStepan Moskovchenko <stevenm@rockbox.org>2005-08-07 22:32:20 +0000
committerStepan Moskovchenko <stevenm@rockbox.org>2005-08-07 22:32:20 +0000
commite46b9889c2858680bc7e4d8f5cdb0d972fe515c6 (patch)
tree9a72bfaa0e9b3ec47502d99a6faf06075d146995
parent2be160af315446f5c115223a094e23beace7507b (diff)
downloadrockbox-e46b9889c2858680bc7e4d8f5cdb0d972fe515c6.tar.gz
rockbox-e46b9889c2858680bc7e4d8f5cdb0d972fe515c6.zip
Add this back in, for now. Will turn into real codec later, when plugins support the codec api.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7290 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugins/midi2wav.c238
1 files changed, 238 insertions, 0 deletions
diff --git a/apps/plugins/midi2wav.c b/apps/plugins/midi2wav.c
new file mode 100644
index 0000000000..1a87fa8bfd
--- /dev/null
+++ b/apps/plugins/midi2wav.c
@@ -0,0 +1,238 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2005 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#define SAMPLE_RATE 22050
20#define MAX_VOICES 100
21
22
23/* Only define LOCAL_DSP on Simulator or else we're asking for trouble */
24#if defined(SIMULATOR)
25 /*Enable this to write to the soundcard via a /dsv/dsp symlink in */
26 //#define LOCAL_DSP
27#endif
28
29
30#if defined(LOCAL_DSP)
31/* This is for writing to the DSP directly from the Simulator */
32#include <stdio.h>
33#include <stdlib.h>
34#include <linux/soundcard.h>
35#include <sys/ioctl.h>
36#endif
37
38#include "../../firmware/export/system.h"
39
40#include "../../plugin.h"
41
42//#include "../codecs/lib/xxx2wav.h"
43
44int numberOfSamples IDATA_ATTR;
45long bpm;
46
47#include "midi/midiutil.c"
48#include "midi/guspat.h"
49#include "midi/guspat.c"
50#include "midi/sequencer.c"
51#include "midi/midifile.c"
52#include "midi/synth.c"
53
54
55
56
57int fd=-1; /* File descriptor where the output is written */
58
59extern long tempo; /* The sequencer keeps track of this */
60
61
62struct plugin_api * rb;
63
64
65
66
67
68enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
69{
70 TEST_PLUGIN_API(api);
71 rb = api;
72 TEST_PLUGIN_API(api);
73 (void)parameter;
74 rb = api;
75
76 if(parameter == NULL)
77 {
78 rb->splash(HZ*2, true, " Play .MID file ");
79 return PLUGIN_OK;
80 }
81
82 rb->splash(HZ, true, parameter);
83 if(midimain(parameter) == -1)
84 {
85 return PLUGIN_ERROR;
86 }
87 rb->splash(HZ*3, true, "FINISHED PLAYING");
88 return PLUGIN_OK;
89}
90
91signed char outputBuffer[3000] IDATA_ATTR; /* signed char.. gonna run out of iram ... ! */
92
93
94int currentSample IDATA_ATTR;
95int outputBufferPosition IDATA_ATTR;
96int outputSampleOne IDATA_ATTR;
97int outputSampleTwo IDATA_ATTR;
98
99
100int midimain(void * filename)
101{
102
103 printf("\nHello.\n");
104
105 rb->splash(HZ/5, true, "LOADING MIDI");
106
107 struct MIDIfile * mf = loadFile(filename);
108
109 rb->splash(HZ/5, true, "LOADING PATCHES");
110 if (initSynth(mf, "/.rockbox/patchset/patchset.cfg", "/.rockbox/patchset/drums.cfg") == -1)
111 {
112 return -1;
113 }
114
115/*
116 * This lets you hear the music through the sound card if you are on Simulator
117 * Make a symlink, archos/dsp.raw and make it point to /dev/dsp or whatever
118 * your sound device is.
119 */
120
121#if defined(LOCAL_DSP)
122 fd=rb->open("/dsp.raw", O_WRONLY);
123 int arg, status;
124 int bit, samp, ch;
125
126 arg = 16; /* sample size */
127 status = ioctl(fd, SOUND_PCM_WRITE_BITS, &arg);
128 status = ioctl(fd, SOUND_PCM_READ_BITS, &arg);
129 bit=arg;
130
131
132 arg = 2; /* Number of channels, 1=mono */
133 status = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &arg);
134 status = ioctl(fd, SOUND_PCM_READ_CHANNELS, &arg);
135 ch=arg;
136
137 arg = SAMPLE_RATE; /* Yeah. sampling rate */
138 status = ioctl(fd, SOUND_PCM_WRITE_RATE, &arg);
139 status = ioctl(fd, SOUND_PCM_READ_RATE, &arg);
140 samp=arg;
141#else
142
143/* xxx2wav stuff, removed for now, will move to the real way of outputting sound soon */
144/*
145 file_info_struct file_info;
146 file_info.samplerate = SAMPLE_RATE;
147 file_info.infile = fd;
148 file_info.channels = 2;
149 file_info.bitspersample = 16;
150 local_init("/miditest.tmp", "/miditest.wav", &file_info, rb);
151 fd = file_info.outfile;
152*/
153#endif
154
155
156 rb->splash(HZ/5, true, " I hope this works... ");
157
158
159
160
161 /*
162 * tick() will do one MIDI clock tick. Then, there's a loop here that
163 * will generate the right number of samples per MIDI tick. The whole
164 * MIDI playback is timed in terms of this value.. there are no forced
165 * delays or anything. It just produces enough samples for each tick, and
166 * the playback of these samples is what makes the timings right.
167 *
168 * This seems to work quite well.
169 */
170
171 printf("\nOkay, starting sequencing");
172
173
174 currentSample=0; /* Sample counting variable */
175 outputBufferPosition = 0;
176
177
178 bpm=mf->div*1000000/tempo;
179 numberOfSamples=SAMPLE_RATE/bpm;
180
181
182
183 /* Tick() will return 0 if there are no more events left to play */
184 while(tick(mf))
185 {
186 /*
187 * Tempo recalculation moved to sequencer.c to be done on a tempo event only
188 *
189 */
190 for(currentSample=0; currentSample<numberOfSamples; currentSample++)
191 {
192
193 synthSample(&outputSampleOne, &outputSampleTwo);
194
195
196 /*
197 * 16-bit audio because, well, it's better
198 * But really because ALSA's OSS emulation sounds extremely
199 * noisy and distorted when in 8-bit mode. I still do not know
200 * why this happens.
201 */
202
203 outputBuffer[outputBufferPosition]=outputSampleOne&0XFF; // Low byte first
204 outputBufferPosition++;
205 outputBuffer[outputBufferPosition]=outputSampleOne>>8; //High byte second
206 outputBufferPosition++;
207
208 outputBuffer[outputBufferPosition]=outputSampleTwo&0XFF; // Low byte first
209 outputBufferPosition++;
210 outputBuffer[outputBufferPosition]=outputSampleTwo>>8; //High byte second
211 outputBufferPosition++;
212
213
214 /*
215 * As soon as we produce 2000 bytes of sound,
216 * write it to the sound card. Why 2000? I have
217 * no idea. It's 1 AM and I am dead tired.
218 */
219 if(outputBufferPosition>=2000)
220 {
221 rb->write(fd, outputBuffer, 2000);
222 outputBufferPosition=0;
223 }
224 }
225 }
226
227 printf("\n");
228
229#if !defined(LOCAL_DSP)
230
231/* again, xxx2wav stuff, removed for now */
232
233 /* close_wav(&file_info); */
234#else
235 rb->close(fd);
236#endif
237 return 0;
238}