#include "MT32Player.h" #include MT32Player::MT32Player(bool gm, unsigned gm_set) : bGM(gm), uGMSet(gm_set), MIDIPlayer() { _synth = NULL; controlRom = NULL; pcmRom = NULL; controlRomFile = NULL; pcmRomFile = NULL; } MT32Player::~MT32Player() { if(_synth) { _synth->close(); delete _synth; } if(controlRom) { MT32Emu::ROMImage::freeROMImage(controlRom); } if(pcmRom) { MT32Emu::ROMImage::freeROMImage(pcmRom); } delete controlRomFile; delete pcmRomFile; } void MT32Player::send_event(uint32_t b) { if(!(b & 0x80000000)) { _synth->playMsg(b); } else { uint32_t n = b & 0xffffff; const uint8_t *data; size_t size, port; mSysexMap.get_entry(n, data, size, port); _synth->playSysex(data, (MT32Emu::Bit32u)size); } } void MT32Player::render(float *out, unsigned long count) { _synth->render(out, (MT32Emu::Bit32u)count); } void MT32Player::setBasePath(const char *in) { sBasePath = in; shutdown(); } void MT32Player::shutdown() { if(_synth) { _synth->close(); delete _synth; } if(controlRom) { MT32Emu::ROMImage::freeROMImage(controlRom); } if(pcmRom) { MT32Emu::ROMImage::freeROMImage(pcmRom); } delete controlRomFile; delete pcmRomFile; _synth = 0; controlRom = 0; pcmRom = 0; controlRomFile = 0; pcmRomFile = 0; } static const char *control_rom_names[] = { "CM32L_CONTROL.ROM", "MT32_CONTROL.ROM" }; static const char *pcm_rom_names[] = { "CM32L_PCM.ROM", "MT32_PCM.ROM" }; bool MT32Player::startup() { if(_synth) return true; unsigned rom_set = 0; controlRomFile = openFile(control_rom_names[0]); if(!controlRomFile) { rom_set = 1; controlRomFile = openFile(control_rom_names[1]); } if(!controlRomFile) return false; pcmRomFile = openFile(pcm_rom_names[rom_set]); if(!pcmRomFile) return false; controlRom = MT32Emu::ROMImage::makeROMImage(controlRomFile); if(!controlRom) return false; pcmRom = MT32Emu::ROMImage::makeROMImage(pcmRomFile); if(!pcmRom) return false; _synth = new MT32Emu::Synth; if(!_synth->open(*controlRom, *pcmRom, bGM ? 256 : 32, MT32Emu::AnalogOutputMode_COARSE, bGM)) { delete _synth; _synth = 0; return false; } reset(); return true; } void MT32Player::reset() { static const uint8_t mt32_reset[10] = { 0xF0, MT32Emu::SYSEX_MANUFACTURER_ROLAND, 0x10, MT32Emu::SYSEX_MDL_MT32, MT32Emu::SYSEX_CMD_DT1, 0x7F, 0, 0, 0xF7 }; _synth->playSysex(mt32_reset, sizeof(mt32_reset)); if(bGM) { #include "kq6mtgm.h" #include "mtgm.h" #ifndef _countof #define _countof(a) ((sizeof((a))) / (sizeof((a[0])))) #endif const unsigned char *start, *end; if(uGMSet == 0) { start = mt32_gm_sysex; end = start + _countof(mt32_gm_sysex); } else { start = kq6_mt32_gm_sysex; end = start + _countof(kq6_mt32_gm_sysex); } while(start < end) { const unsigned char *sequence_end = start; while(sequence_end < end && *sequence_end != 0xF7) sequence_end++; _synth->playSysex(start, (MT32Emu::Bit32u)(sequence_end - start + 1)); start = sequence_end + 1; } } } class StdFile : public MT32Emu::File { public: StdFile() { data = NULL; } ~StdFile() { close(); } bool open(const char *filename) { FILE *f = fopen(filename, "rb"); if(f) { fseek(f, 0, SEEK_END); fileSize = ftell(f); fseek(f, 0, SEEK_SET); data = new unsigned char[fileSize]; fread(data, fileSize, 1, f); fclose(f); return true; } return false; } void close() { delete[] data; data = NULL; } size_t getSize() { return fileSize; } const unsigned char *getData() { return data; } }; MT32Emu::File *MT32Player::openFile(const char *filename) { StdFile *ret = new StdFile; std::string path = sBasePath; path += filename; if(!ret->open(path.c_str())) { delete ret; ret = 0; } return ret; }