Permalink
Browse files

MT32: Update Munt to 2.0.1-pre

This update uses upstream commit
f88ef82.

This update switches to use the new Munt C++ interface, which
will allow ScummVM to link to an external Munt library instead
of requiring it to be built-in in the future. For the moment,
the emulator is still built-in, since it is not available from
most package repositories.

The Munt driver in ScummVM now uses writeSysex instead of the
(now-private) playSysexWithoutFraming, per recommendation from
the Munt team <munt/munt#30>.

This changeset also removes direct modifications that used to be
made to Munt code, to ease future updates. To update Munt code in
the future:

1. Replace all source files in the `softsynth/mt32` directory with
   new files from the upstream `mt32emu/src` directory;
2. Update `config.h` with the correct version number for the new
   version of Munt;
3. Update `module.mk` to add any new source files that need to be
   built.
  • Loading branch information...
1 parent ffea222 commit b8d70d26faea1ed71b0176326c97859b31afb8ef @csnover csnover committed Nov 24, 2016
Showing with 4,428 additions and 994 deletions.
  1. +28 −0 COPYING.BSD
  2. +1 −0 NEWS
  3. +86 −85 audio/softsynth/mt32.cpp
  4. +17 −31 audio/softsynth/mt32/Analog.cpp
  5. +9 −6 audio/softsynth/mt32/Analog.h
  6. +55 −52 audio/softsynth/mt32/BReverbModel.cpp
  7. +23 −19 audio/softsynth/mt32/BReverbModel.h
  8. +155 −0 audio/softsynth/mt32/Enumerations.h
  9. +73 −0 audio/softsynth/mt32/File.cpp
  10. +73 −0 audio/softsynth/mt32/File.h
  11. +83 −0 audio/softsynth/mt32/FileStream.cpp
  12. +46 −0 audio/softsynth/mt32/FileStream.h
  13. +21 −20 audio/softsynth/mt32/LA32FloatWaveGenerator.cpp
  14. +6 −16 audio/softsynth/mt32/LA32FloatWaveGenerator.h
  15. +5 −5 audio/softsynth/mt32/LA32Ramp.cpp
  16. +6 −3 audio/softsynth/mt32/LA32Ramp.h
  17. +18 −16 audio/softsynth/mt32/LA32WaveGenerator.cpp
  18. +14 −10 audio/softsynth/mt32/LA32WaveGenerator.h
  19. +13 −5 audio/softsynth/mt32/MemoryRegion.h
  20. +7 −3 audio/softsynth/mt32/MidiEventQueue.h
  21. +289 −0 audio/softsynth/mt32/MidiStreamParser.cpp
  22. +124 −0 audio/softsynth/mt32/MidiStreamParser.h
  23. +32 −30 audio/softsynth/mt32/Part.cpp
  24. +11 −5 audio/softsynth/mt32/Part.h
  25. +16 −11 audio/softsynth/mt32/Partial.cpp
  26. +18 −8 audio/softsynth/mt32/Partial.h
  27. +10 −5 audio/softsynth/mt32/PartialManager.cpp
  28. +11 −4 audio/softsynth/mt32/PartialManager.h
  29. +9 −3 audio/softsynth/mt32/Poly.cpp
  30. +8 −11 audio/softsynth/mt32/Poly.h
  31. +34 −56 audio/softsynth/mt32/ROMInfo.cpp
  32. +21 −31 audio/softsynth/mt32/ROMInfo.h
  33. +31 −10 audio/softsynth/mt32/Structures.h
  34. +525 −214 audio/softsynth/mt32/Synth.cpp
  35. +205 −183 audio/softsynth/mt32/Synth.h
  36. +24 −20 audio/softsynth/mt32/TVA.cpp
  37. +11 −5 audio/softsynth/mt32/TVA.h
  38. +13 −11 audio/softsynth/mt32/TVF.cpp
  39. +11 −4 audio/softsynth/mt32/TVF.h
  40. +24 −20 audio/softsynth/mt32/TVP.cpp
  41. +12 −5 audio/softsynth/mt32/TVP.h
  42. +15 −15 audio/softsynth/mt32/Tables.cpp
  43. +7 −4 audio/softsynth/mt32/Tables.h
  44. +1 −9 audio/softsynth/mt32/Types.h
  45. +624 −0 audio/softsynth/mt32/c_interface/c_interface.cpp
  46. +362 −0 audio/softsynth/mt32/c_interface/c_interface.h
  47. +298 −0 audio/softsynth/mt32/c_interface/c_types.h
  48. +436 −0 audio/softsynth/mt32/c_interface/cpp_interface.h
  49. +28 −0 audio/softsynth/mt32/config.h
  50. +119 −0 audio/softsynth/mt32/globals.h
  51. +56 −11 audio/softsynth/mt32/internals.h
  52. +5 −10 audio/softsynth/mt32/mmath.h
  53. +6 −1 audio/softsynth/mt32/module.mk
  54. +59 −37 audio/softsynth/mt32/mt32emu.h
  55. +185 −0 audio/softsynth/mt32/sha1/sha1.cpp
  56. +49 −0 audio/softsynth/mt32/sha1/sha1.h
View
@@ -91,3 +91,31 @@ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+
+
+Parts of the MT-32 emulator use the following license:
+
+ Copyright (c) 2011, Micael Hildenborg
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Micael Hildenborg nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY Micael Hildenborg ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL Micael Hildenborg BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
View
@@ -7,6 +7,7 @@ For a more comprehensive changelog of the latest experimental code, see:
the current or a specified directory.
- Many options in GUI could be applied without closing the dialog.
- On-the-fly language switching was implemented.
+ - Updated Munt MT-32 emulation code to version 2.0.0.
AGOS:
- Fixed subtitle speed setting in the Hebrew version of Simon the Sorcerer 1.
@@ -25,9 +25,6 @@
#ifdef USE_MT32EMU
-#include "audio/softsynth/mt32/mt32emu.h"
-#include "audio/softsynth/mt32/ROMInfo.h"
-
#include "audio/softsynth/emumidi.h"
#include "audio/musicplugin.h"
#include "audio/mpu401.h"
@@ -52,16 +49,12 @@
#include "gui/message.h"
-namespace MT32Emu {
+#include "audio/softsynth/mt32/c_interface/cpp_interface.h"
-class ReportHandlerScummVM : public ReportHandler {
-friend class Synth;
+namespace MT32Emu {
+class ScummVMReportHandler : public MT32Emu::IReportHandler {
public:
- virtual ~ReportHandlerScummVM() {}
-
-protected:
-
// Callback for debug messages, in vprintf() format
void printDebug(const char *fmt, va_list list) {
Common::String out = Common::String::vformat(fmt, list);
@@ -70,18 +63,30 @@ friend class Synth;
// Callbacks for reporting various errors and information
void onErrorControlROM() {
- GUI::MessageDialog dialog("MT32emu: Init Error - Missing or invalid Control ROM image", "OK");
+ 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");
+ 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) {
Common::OSDMessageQueue::instance().addMessage(message);
}
+
+ // Unused callbacks
+ virtual void onMIDIMessagePlayed() {}
+ virtual bool onMIDIQueueOverflow() { return false; }
+ virtual void onMIDISystemRealtime(Bit8u /* system_realtime */) {}
+ virtual void onDeviceReset() {}
+ virtual void onDeviceReconfig() {}
+ virtual void onNewReverbMode(Bit8u /* mode */) {}
+ virtual void onNewReverbTime(Bit8u /* time */) {}
+ virtual void onNewReverbLevel(Bit8u /* level */) {}
+ virtual void onPolyStateChanged(Bit8u /* part_num */) {}
+ virtual void onProgramChanged(Bit8u /* part_num */, const char * /* sound_group_name */, const char * /* patch_name */) {}
};
} // end of namespace MT32Emu
@@ -95,10 +100,9 @@ class MidiDriver_MT32 : public MidiDriver_Emulated {
private:
MidiChannel_MT32 _midiChannels[16];
uint16 _channelMask;
- MT32Emu::Synth *_synth;
- MT32Emu::ReportHandlerScummVM *_reportHandler;
- const MT32Emu::ROMImage *_controlROM, *_pcmROM;
- Common::File *_controlFile, *_pcmFile;
+ MT32Emu::Service *_service;
+ MT32Emu::ScummVMReportHandler *_reportHandler;
+ byte *_controlData, *_pcmData;
void deleteMuntStructures();
int _outputRate;
@@ -107,15 +111,13 @@ class MidiDriver_MT32 : public MidiDriver_Emulated {
void generateSamples(int16 *buf, int len);
public:
- bool _initializing;
-
MidiDriver_MT32(Audio::Mixer *mixer);
virtual ~MidiDriver_MT32();
int open();
void close();
void send(uint32 b);
- void setPitchBendRange (byte channel, uint range);
+ void setPitchBendRange(byte channel, uint range);
void sysEx(const byte *msg, uint16 length);
uint32 property(int prop, uint32 param);
@@ -139,48 +141,32 @@ 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;
+ _service = nullptr;
+ _reportHandler = nullptr;
_outputRate = 0;
- _initializing = false;
-
- // Initialized in open()
- _controlROM = NULL;
- _pcmROM = NULL;
- _controlFile = NULL;
- _pcmFile = NULL;
+ _controlData = nullptr;
+ _pcmData = nullptr;
}
MidiDriver_MT32::~MidiDriver_MT32() {
deleteMuntStructures();
}
void MidiDriver_MT32::deleteMuntStructures() {
- delete _synth;
- _synth = NULL;
+ delete _service;
+ _service = nullptr;
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;
+ _reportHandler = nullptr;
+ delete _controlData;
+ _controlData = nullptr;
+ delete _pcmData;
+ _pcmData = nullptr;
}
int MidiDriver_MT32::open() {
if (_isOpen)
return MERR_ALREADY_OPEN;
- _reportHandler = new MT32Emu::ReportHandlerScummVM();
- _synth = new MT32Emu::Synth(_reportHandler);
-
Graphics::PixelFormat screenFormat = g_system->getScreenFormat();
if (screenFormat.bytesPerPixel == 1) {
@@ -193,75 +179,90 @@ int MidiDriver_MT32::open() {
g_system->getPaletteManager()->setPalette(dummy_palette, 0, 3);
}
- _initializing = true;
debug(4, _s("Initializing MT-32 Emulator"));
- _controlFile = new Common::File();
- if (!_controlFile->open("CM32L_CONTROL.ROM") && !_controlFile->open("MT32_CONTROL.ROM"))
- error("Error opening MT32_CONTROL.ROM / CM32L_CONTROL.ROM");
- _pcmFile = new Common::File();
- if (!_pcmFile->open("CM32L_PCM.ROM") && !_pcmFile->open("MT32_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))
+
+ Common::File controlFile;
+ if (!controlFile.open("CM32L_CONTROL.ROM") && !controlFile.open("MT32_CONTROL.ROM"))
+ error("Error opening MT32_CONTROL.ROM / CM32L_CONTROL.ROM. Check that your Extra Path in Paths settings is set to the correct directory");
+
+ Common::File pcmFile;
+ if (!pcmFile.open("CM32L_PCM.ROM") && !pcmFile.open("MT32_PCM.ROM"))
+ error("Error opening MT32_PCM.ROM / CM32L_PCM.ROM. Check that your Extra Path in Paths settings is set to the correct directory");
+
+ _controlData = new byte[controlFile.size()];
+ controlFile.read(_controlData, controlFile.size());
+ _pcmData = new byte[pcmFile.size()];
+ pcmFile.read(_pcmData, pcmFile.size());
+
+ _reportHandler = new MT32Emu::ScummVMReportHandler();
+ _service = new MT32Emu::Service();
+ _service->createContext(*_reportHandler);
+
+ if (_service->addROMData(_controlData, controlFile.size()) != MT32EMU_RC_ADDED_CONTROL_ROM) {
+ error("Adding control ROM failed. Check that your control ROM is valid");
+ }
+
+ controlFile.close();
+
+ if (_service->addROMData(_pcmData, pcmFile.size()) != MT32EMU_RC_ADDED_PCM_ROM) {
+ error("Adding PCM ROM failed. Check that your PCM ROM is valid");
+ }
+
+ pcmFile.close();
+
+ if (_service->openSynth() != MT32EMU_RC_OK)
return MERR_DEVICE_NOT_AVAILABLE;
double gain = (double)ConfMan.getInt("midi_gain") / 100.0;
- _synth->setOutputGain(1.0f * gain);
- _synth->setReverbOutputGain(0.68f * gain);
+ _service->setOutputGain(1.0f * gain);
+ _service->setReverbOutputGain(1.0f * gain);
// We let the synthesizer play MIDI messages immediately. Our MIDI
// handling is synchronous to sample generation. This makes delaying MIDI
// events result in odd sound output in some cases. For example, the
// shattering window in the Indiana Jones and the Fate of Atlantis intro
// will sound like a bell if we use any delay here.
// Bug #6242 "AUDIO: Built-In MT-32 MUNT Produces Wrong Sounds".
- _synth->setMIDIDelayMode(MT32Emu::MIDIDelayMode_IMMEDIATE);
+ _service->setMIDIDelayMode(MT32Emu::MIDIDelayMode_IMMEDIATE);
// We need to report the sample rate MUNT renders at as sample rate of our
// AudioStream.
- _outputRate = _synth->getStereoOutputSampleRate();
- MidiDriver_Emulated::open();
+ _outputRate = _service->getActualStereoOutputSamplerate();
- _initializing = false;
-
- if (screenFormat.bytesPerPixel > 1)
- g_system->fillScreen(screenFormat.RGBToColor(0, 0, 0));
- else
- g_system->fillScreen(0);
-
- g_system->updateScreen();
+ MidiDriver_Emulated::open();
_mixer->playStream(Audio::Mixer::kPlainSoundType, &_mixerSoundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
return 0;
}
void MidiDriver_MT32::send(uint32 b) {
- _synth->playMsg(b);
+ _service->playMsg(b);
}
+// Indiana Jones and the Fate of Atlantis (including the demo) uses
+// setPitchBendRange, if you need a game for testing purposes
void MidiDriver_MT32::setPitchBendRange(byte channel, uint range) {
if (range > 24) {
warning("setPitchBendRange() called with range > 24: %d", range);
}
- byte benderRangeSysex[9];
- benderRangeSysex[0] = 0x41; // Roland
- benderRangeSysex[1] = channel;
- benderRangeSysex[2] = 0x16; // MT-32
- benderRangeSysex[3] = 0x12; // Write
- benderRangeSysex[4] = 0x00;
- benderRangeSysex[5] = 0x00;
- benderRangeSysex[6] = 0x04;
- benderRangeSysex[7] = (byte)range;
- benderRangeSysex[8] = MT32Emu::Synth::calcSysexChecksum(&benderRangeSysex[4], 4, 0);
- sysEx(benderRangeSysex, 9);
+ byte benderRangeSysex[4] = { 0, 0, 4, (uint8)range };
+ _service->writeSysex(channel, benderRangeSysex, 4);
}
void MidiDriver_MT32::sysEx(const byte *msg, uint16 length) {
if (msg[0] == 0xf0) {
- _synth->playSysex(msg, length);
+ _service->playSysex(msg, length);
} else {
- _synth->playSysexWithoutFraming(msg, length);
+ enum {
+ SYSEX_CMD_DT1 = 0x12,
+ SYSEX_CMD_DAT = 0x42
+ };
+
+ if (msg[3] == SYSEX_CMD_DT1 || msg[3] == SYSEX_CMD_DAT) {
+ _service->writeSysex(msg[1], msg + 4, length - 5);
+ } else {
+ warning("Unused sysEx command %d", msg[3]);
+ }
}
}
@@ -275,12 +276,12 @@ void MidiDriver_MT32::close() {
// Detach the mixer callback handler
_mixer->stopHandle(_mixerSoundHandle);
- _synth->close();
+ _service->closeSynth();
deleteMuntStructures();
}
void MidiDriver_MT32::generateSamples(int16 *data, int len) {
- _synth->render(data, len);
+ _service->renderBit16s(data, len);
}
uint32 MidiDriver_MT32::property(int prop, uint32 param) {
Oops, something went wrong.

0 comments on commit b8d70d2

Please sign in to comment.