Cog/Plugins/MIDI/MIDI/MT32Player.cpp

200 lines
4.1 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 "mtgm.h"
#include "kq6mtgm.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;
}