diff options
Diffstat (limited to 'audio/softsynth/mt32.cpp')
-rw-r--r-- | audio/softsynth/mt32.cpp | 255 |
1 files changed, 88 insertions, 167 deletions
diff --git a/audio/softsynth/mt32.cpp b/audio/softsynth/mt32.cpp index 186118262f..00d0469356 100644 --- a/audio/softsynth/mt32.cpp +++ b/audio/softsynth/mt32.cpp @@ -25,6 +25,7 @@ #ifdef USE_MT32EMU #include "audio/softsynth/mt32/mt32emu.h" +#include "audio/softsynth/mt32/ROMInfo.h" #include "audio/softsynth/emumidi.h" #include "audio/musicplugin.h" @@ -47,6 +48,50 @@ #include "graphics/palette.h" #include "graphics/font.h" +#include "gui/message.h" + +namespace MT32Emu { + +class ReportHandlerScummVM : public ReportHandler { +friend class Synth; + +public: + virtual ~ReportHandlerScummVM() {} + +protected: + + // Callback for debug messages, in vprintf() format + void printDebug(const char *fmt, va_list list) { + debug(4, fmt, list); + } + + // Callbacks for reporting various errors and information + void onErrorControlROM() { + GUI::MessageDialog dialog("MT32emu: Init Error - Missing or invalid Control ROM image", "OK"); + dialog.runModal(); + error("MT32emu: Init Error - Missing or invalid Control ROM image"); + } + void onErrorPCMROM() { + GUI::MessageDialog dialog("MT32emu: Init Error - Missing PCM ROM image", "OK"); + dialog.runModal(); + error("MT32emu: Init Error - Missing PCM ROM image"); + } + void showLCDMessage(const char *message) { + g_system->displayMessageOnOSD(message); + } + void onDeviceReset() {} + void onDeviceReconfig() {} + void onNewReverbMode(Bit8u /* mode */) {} + void onNewReverbTime(Bit8u /* time */) {} + void onNewReverbLevel(Bit8u /* level */) {} + void onPartStateChanged(int /* partNum */, bool /* isActive */) {} + void onPolyStateChanged(int /* partNum */) {} + void onPartialStateChanged(int /* partialNum */, int /* oldPartialPhase */, int /* newPartialPhase */) {} + void onProgramChanged(int /* partNum */, char * /* patchName */) {} +}; + +} // end of namespace MT32Emu + class MidiChannel_MT32 : public MidiChannel_MPU401 { void effectLevel(byte value) { } void chorusLevel(byte value) { } @@ -57,6 +102,10 @@ private: MidiChannel_MT32 _midiChannels[16]; uint16 _channelMask; MT32Emu::Synth *_synth; + MT32Emu::ReportHandlerScummVM *_reportHandler; + const MT32Emu::ROMImage *_controlROM, *_pcmROM; + Common::File *_controlFile, *_pcmFile; + void deleteMuntStructures(); int _outputRate; @@ -84,149 +133,6 @@ public: int getRate() const { return _outputRate; } }; -static int eatSystemEvents() { - Common::Event event; - Common::EventManager *eventMan = g_system->getEventManager(); - while (eventMan->pollEvent(event)) { - switch (event.type) { - case Common::EVENT_QUIT: - return 1; - default: - break; - } - } - return 0; -} - -static void drawProgress(float progress) { - const Graphics::Font &font(*FontMan.getFontByUsage(Graphics::FontManager::kGUIFont)); - Graphics::Surface *screen = g_system->lockScreen(); - - assert(screen); - assert(screen->pixels); - - Graphics::PixelFormat screenFormat = g_system->getScreenFormat(); - - int16 w = g_system->getWidth() / 7 * 5; - int16 h = font.getFontHeight(); - int16 x = g_system->getWidth() / 7; - int16 y = g_system->getHeight() / 2 - h / 2; - - Common::Rect r(x, y, x + w, y + h); - - uint32 col; - - if (screenFormat.bytesPerPixel > 1) - col = screenFormat.RGBToColor(0, 171, 0); - else - col = 1; - - screen->frameRect(r, col); - - r.grow(-1); - r.setWidth(uint16(progress * w)); - - if (screenFormat.bytesPerPixel > 1) - col = screenFormat.RGBToColor(171, 0, 0); - else - col = 2; - - screen->fillRect(r, col); - - g_system->unlockScreen(); - g_system->updateScreen(); -} - -static void drawMessage(int offset, const Common::String &text) { - const Graphics::Font &font(*FontMan.getFontByUsage(Graphics::FontManager::kGUIFont)); - Graphics::Surface *screen = g_system->lockScreen(); - - assert(screen); - assert(screen->pixels); - - Graphics::PixelFormat screenFormat = g_system->getScreenFormat(); - - uint16 h = font.getFontHeight(); - uint16 y = g_system->getHeight() / 2 - h / 2 + offset * (h + 1); - - uint32 col; - - if (screenFormat.bytesPerPixel > 1) - col = screenFormat.RGBToColor(0, 0, 0); - else - col = 0; - - Common::Rect r(0, y, screen->w, y + h); - screen->fillRect(r, col); - - if (screenFormat.bytesPerPixel > 1) - col = screenFormat.RGBToColor(0, 171, 0); - else - col = 1; - - font.drawString(screen, text, 0, y, screen->w, col, Graphics::kTextAlignCenter); - - g_system->unlockScreen(); - g_system->updateScreen(); -} - -static Common::File *MT32_OpenFile(void *userData, const char *filename) { - Common::File *file = new Common::File(); - if (!file->open(filename)) { - delete file; - return NULL; - } - return file; -} - -static void MT32_PrintDebug(void *userData, const char *fmt, va_list list) { - if (((MidiDriver_MT32 *)userData)->_initializing) { - char buf[512]; - - vsnprintf(buf, 512, fmt, list); - buf[70] = 0; // Truncate to a reasonable length - - drawMessage(1, buf); - } - - //vdebug(0, fmt, list); // FIXME: Use a higher debug level -} - -static int MT32_Report(void *userData, MT32Emu::ReportType type, const void *reportData) { - switch (type) { - case MT32Emu::ReportType_lcdMessage: - g_system->displayMessageOnOSD((const char *)reportData); - break; - case MT32Emu::ReportType_errorControlROM: - error("Failed to load MT32_CONTROL.ROM"); - break; - case MT32Emu::ReportType_errorPCMROM: - error("Failed to load MT32_PCM.ROM"); - break; - case MT32Emu::ReportType_progressInit: - if (((MidiDriver_MT32 *)userData)->_initializing) { - drawProgress(*((const float *)reportData)); - return eatSystemEvents(); - } - break; - case MT32Emu::ReportType_availableSSE: - debug(1, "MT32emu: SSE is available"); - break; - case MT32Emu::ReportType_usingSSE: - debug(1, "MT32emu: using SSE"); - break; - case MT32Emu::ReportType_available3DNow: - debug(1, "MT32emu: 3DNow! is available"); - break; - case MT32Emu::ReportType_using3DNow: - debug(1, "MT32emu: using 3DNow!"); - break; - default: - break; - } - return 0; -} - //////////////////////////////////////// // // MidiDriver_MT32 @@ -239,43 +145,51 @@ MidiDriver_MT32::MidiDriver_MT32(Audio::Mixer *mixer) : MidiDriver_Emulated(mixe for (i = 0; i < ARRAYSIZE(_midiChannels); ++i) { _midiChannels[i].init(this, i); } + _reportHandler = NULL; _synth = NULL; - // A higher baseFreq reduces the length used in generateSamples(), - // and means that the timer callback will be called more often. - // That results in more accurate timing. - _baseFreq = 10000; // Unfortunately bugs in the emulator cause inaccurate tuning // at rates other than 32KHz, thus we produce data at 32KHz and // rely on Mixer to convert. _outputRate = 32000; //_mixer->getOutputRate(); _initializing = false; + + // Initialized in open() + _controlROM = NULL; + _pcmROM = NULL; + _controlFile = NULL; + _pcmFile = NULL; } MidiDriver_MT32::~MidiDriver_MT32() { + deleteMuntStructures(); +} + +void MidiDriver_MT32::deleteMuntStructures() { delete _synth; + _synth = NULL; + delete _reportHandler; + _reportHandler = NULL; + + if (_controlROM) + MT32Emu::ROMImage::freeROMImage(_controlROM); + _controlROM = NULL; + if (_pcmROM) + MT32Emu::ROMImage::freeROMImage(_pcmROM); + _pcmROM = NULL; + + delete _controlFile; + _controlFile = NULL; + delete _pcmFile; + _pcmFile = NULL; } int MidiDriver_MT32::open() { - MT32Emu::SynthProperties prop; - if (_isOpen) return MERR_ALREADY_OPEN; MidiDriver_Emulated::open(); - - memset(&prop, 0, sizeof(prop)); - prop.sampleRate = getRate(); - prop.useReverb = true; - prop.useDefaultReverb = false; - prop.reverbType = 0; - prop.reverbTime = 5; - prop.reverbLevel = 3; - prop.userData = this; - prop.printDebug = MT32_PrintDebug; - prop.report = MT32_Report; - prop.openFile = MT32_OpenFile; - - _synth = new MT32Emu::Synth(); + _reportHandler = new MT32Emu::ReportHandlerScummVM(); + _synth = new MT32Emu::Synth(_reportHandler); Graphics::PixelFormat screenFormat = g_system->getScreenFormat(); @@ -290,8 +204,16 @@ int MidiDriver_MT32::open() { } _initializing = true; - drawMessage(-1, _s("Initializing MT-32 Emulator")); - if (!_synth->open(prop)) + debug(4, _s("Initializing MT-32 Emulator")); + _controlFile = new Common::File(); + if (!_controlFile->open("MT32_CONTROL.ROM") && !_controlFile->open("CM32L_CONTROL.ROM")) + error("Error opening MT32_CONTROL.ROM / CM32L_CONTROL.ROM"); + _pcmFile = new Common::File(); + if (!_pcmFile->open("MT32_PCM.ROM") && !_pcmFile->open("CM32L_PCM.ROM")) + error("Error opening MT32_PCM.ROM / CM32L_PCM.ROM"); + _controlROM = MT32Emu::ROMImage::makeROMImage(_controlFile); + _pcmROM = MT32Emu::ROMImage::makeROMImage(_pcmFile); + if (!_synth->open(*_controlROM, *_pcmROM)) return MERR_DEVICE_NOT_AVAILABLE; double gain = (double)ConfMan.getInt("midi_gain") / 100.0; @@ -352,8 +274,7 @@ void MidiDriver_MT32::close() { _mixer->stopHandle(_mixerSoundHandle); _synth->close(); - delete _synth; - _synth = NULL; + deleteMuntStructures(); } void MidiDriver_MT32::generateSamples(int16 *data, int len) { |