diff options
Diffstat (limited to 'apps/plugins/midi2wav.c')
-rw-r--r-- | apps/plugins/midi2wav.c | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/apps/plugins/midi2wav.c b/apps/plugins/midi2wav.c new file mode 100644 index 0000000000..f8368535d1 --- /dev/null +++ b/apps/plugins/midi2wav.c @@ -0,0 +1,168 @@ +/*************************************************************************** + * __________ __ ___. + * 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 48000 +#define MAX_VOICES 100 + +/* This is for writing to the DSP directly from the Simulator +#include <stdio.h> +#include <stdlib.h> +#include <linux/soundcard.h> +#include <sys/ioctl.h> +*/ + +#include "../../plugin.h" +#include "midi/midiutil.c" +#include "midi/guspat.h" +#include "midi/guspat.c" +#include "midi/sequencer.c" +#include "midi/midifile.c" +#include "midi/synth.c" + + + +//#include "lib/xxx2wav.h" + +int fd=-1; //File descriptor, for opening /dev/dsp and writing to it + +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); + (void)parameter; + rb = api; + rb->splash(HZ*2, true, "MIDI"); + midimain(); + rb->splash(HZ*2, true, "FINISHED PLAYING"); + return PLUGIN_OK; +} + + +int midimain() +{ + rb->splash(HZ*2, true, "OPENED DSP"); + fd=rb->open("/dsp.raw", O_WRONLY|O_CREAT); +/* + 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; +*/ + + printf("\nHello.\n"); +// initSound(); //Open the computer's sound card + int a=0; + + rb->splash(HZ*2, true, "LOADING MIDI"); + + struct MIDIfile * mf = loadFile("/test.mid"); + + rb->splash(HZ*2, true, "LOADED MIDI"); + long bpm, nsmp, l; + + int bp=0; + + rb->splash(HZ*2, true, "LOADING PATCHES"); + initSynth(mf, "/iriver2.cfg", "/drums.cfg"); //Initialize the MIDI syntehsizer + rb->splash(HZ*2, true, "START PLAYING"); + + signed char buf[3000]; + + // 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"); + + //Tick() will return 0 if there are no more events left to play + while(tick(mf)) + { + + //Some annoying math to compute the number of samples + //to syntehsize per each MIDI tick. + bpm=mf->div*1000000/tempo; + nsmp=SAMPLE_RATE/bpm; + + //Yes we need to do this math each time because the tempo + //could have changed. + + // On second thought, this can be moved to the event that + //recalculates the tempo, to save a little bit of CPU time. + for(l=0; l<nsmp; l++) + { + int s1, s2; + + synthSample(&s1, &s2); + + + //16-bit audio because, well, it's better + // But really because ALSA's OSS emulation sounds extremely + //noisy and distorted when in 8-bit mode. I still do not know + //why this happens. + buf[bp]=s1&0XFF; // Low byte first + bp++; + buf[bp]=s1>>8; //High byte second + bp++; + + buf[bp]=s2&0XFF; // Low byte first + bp++; + buf[bp]=s2>>8; //High byte second + bp++; + + + //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(bp>=2000) + { + rb->write(fd, buf, 2000); + bp=0; + } + } + } + +// unloadFile(mf); + printf("\n"); + rb->close(fd); + return 0; +} |