From e46b9889c2858680bc7e4d8f5cdb0d972fe515c6 Mon Sep 17 00:00:00 2001 From: Stepan Moskovchenko Date: Sun, 7 Aug 2005 22:32:20 +0000 Subject: 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 --- apps/plugins/midi2wav.c | 238 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 apps/plugins/midi2wav.c 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 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2005 Stepan Moskovchenko + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#define SAMPLE_RATE 22050 +#define MAX_VOICES 100 + + +/* Only define LOCAL_DSP on Simulator or else we're asking for trouble */ +#if defined(SIMULATOR) + /*Enable this to write to the soundcard via a /dsv/dsp symlink in */ + //#define LOCAL_DSP +#endif + + +#if defined(LOCAL_DSP) +/* This is for writing to the DSP directly from the Simulator */ +#include +#include +#include +#include +#endif + +#include "../../firmware/export/system.h" + +#include "../../plugin.h" + +//#include "../codecs/lib/xxx2wav.h" + +int numberOfSamples IDATA_ATTR; +long bpm; + +#include "midi/midiutil.c" +#include "midi/guspat.h" +#include "midi/guspat.c" +#include "midi/sequencer.c" +#include "midi/midifile.c" +#include "midi/synth.c" + + + + +int fd=-1; /* File descriptor where the output is written */ + +extern long tempo; /* The sequencer keeps track of this */ + + +struct plugin_api * rb; + + + + + +enum plugin_status plugin_start(struct plugin_api* api, void* parameter) +{ + TEST_PLUGIN_API(api); + rb = api; + TEST_PLUGIN_API(api); + (void)parameter; + rb = api; + + if(parameter == NULL) + { + rb->splash(HZ*2, true, " Play .MID file "); + return PLUGIN_OK; + } + + rb->splash(HZ, true, parameter); + if(midimain(parameter) == -1) + { + return PLUGIN_ERROR; + } + rb->splash(HZ*3, true, "FINISHED PLAYING"); + return PLUGIN_OK; +} + +signed char outputBuffer[3000] IDATA_ATTR; /* signed char.. gonna run out of iram ... ! */ + + +int currentSample IDATA_ATTR; +int outputBufferPosition IDATA_ATTR; +int outputSampleOne IDATA_ATTR; +int outputSampleTwo IDATA_ATTR; + + +int midimain(void * filename) +{ + + printf("\nHello.\n"); + + rb->splash(HZ/5, true, "LOADING MIDI"); + + struct MIDIfile * mf = loadFile(filename); + + rb->splash(HZ/5, true, "LOADING PATCHES"); + if (initSynth(mf, "/.rockbox/patchset/patchset.cfg", "/.rockbox/patchset/drums.cfg") == -1) + { + return -1; + } + +/* + * This lets you hear the music through the sound card if you are on Simulator + * Make a symlink, archos/dsp.raw and make it point to /dev/dsp or whatever + * your sound device is. + */ + +#if defined(LOCAL_DSP) + fd=rb->open("/dsp.raw", O_WRONLY); + int arg, status; + int bit, samp, ch; + + arg = 16; /* sample size */ + status = ioctl(fd, SOUND_PCM_WRITE_BITS, &arg); + status = ioctl(fd, SOUND_PCM_READ_BITS, &arg); + bit=arg; + + + arg = 2; /* Number of channels, 1=mono */ + status = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &arg); + status = ioctl(fd, SOUND_PCM_READ_CHANNELS, &arg); + ch=arg; + + arg = SAMPLE_RATE; /* Yeah. sampling rate */ + status = ioctl(fd, SOUND_PCM_WRITE_RATE, &arg); + status = ioctl(fd, SOUND_PCM_READ_RATE, &arg); + samp=arg; +#else + +/* xxx2wav stuff, removed for now, will move to the real way of outputting sound soon */ +/* + file_info_struct file_info; + file_info.samplerate = SAMPLE_RATE; + file_info.infile = fd; + file_info.channels = 2; + file_info.bitspersample = 16; + local_init("/miditest.tmp", "/miditest.wav", &file_info, rb); + fd = file_info.outfile; +*/ +#endif + + + rb->splash(HZ/5, true, " I hope this works... "); + + + + + /* + * tick() will do one MIDI clock tick. Then, there's a loop here that + * will generate the right number of samples per MIDI tick. The whole + * MIDI playback is timed in terms of this value.. there are no forced + * delays or anything. It just produces enough samples for each tick, and + * the playback of these samples is what makes the timings right. + * + * This seems to work quite well. + */ + + printf("\nOkay, starting sequencing"); + + + currentSample=0; /* Sample counting variable */ + outputBufferPosition = 0; + + + bpm=mf->div*1000000/tempo; + numberOfSamples=SAMPLE_RATE/bpm; + + + + /* Tick() will return 0 if there are no more events left to play */ + while(tick(mf)) + { + /* + * Tempo recalculation moved to sequencer.c to be done on a tempo event only + * + */ + for(currentSample=0; currentSample>8; //High byte second + outputBufferPosition++; + + outputBuffer[outputBufferPosition]=outputSampleTwo&0XFF; // Low byte first + outputBufferPosition++; + outputBuffer[outputBufferPosition]=outputSampleTwo>>8; //High byte second + outputBufferPosition++; + + + /* + * As soon as we produce 2000 bytes of sound, + * write it to the sound card. Why 2000? I have + * no idea. It's 1 AM and I am dead tired. + */ + if(outputBufferPosition>=2000) + { + rb->write(fd, outputBuffer, 2000); + outputBufferPosition=0; + } + } + } + + printf("\n"); + +#if !defined(LOCAL_DSP) + +/* again, xxx2wav stuff, removed for now */ + + /* close_wav(&file_info); */ +#else + rb->close(fd); +#endif + return 0; +} -- cgit v1.2.3