cog/Plugins/MIDI/MIDI/MT32Player.cpp

173 lines
3.8 KiB
C++

#include "MT32Player.h"
#include <stdio.h>
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;
}