[Scummvm-git-logs] scummvm master -> b0b0e573fb4f82ebfc740d95565c2822682c2248

sev- sev at scummvm.org
Sat Jun 6 22:55:50 UTC 2020


This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
cc5299961e MT32: Update to libmt32emu 2.4.0
d831c5984e MT32: Fix MSVC warning
b0b0e573fb MT32: Add missing default switch cases


Commit: cc5299961ec1aaf18fbeecbe8c931269c12d31c2
    https://github.com/scummvm/scummvm/commit/cc5299961ec1aaf18fbeecbe8c931269c12d31c2
Author: Lothar Serra Mari (mail at serra.me)
Date: 2020-06-07T00:55:45+02:00

Commit Message:
MT32: Update to libmt32emu 2.4.0

Changed paths:
    audio/softsynth/mt32/Analog.cpp
    audio/softsynth/mt32/Analog.h
    audio/softsynth/mt32/BReverbModel.cpp
    audio/softsynth/mt32/BReverbModel.h
    audio/softsynth/mt32/Enumerations.h
    audio/softsynth/mt32/File.cpp
    audio/softsynth/mt32/File.h
    audio/softsynth/mt32/FileStream.cpp
    audio/softsynth/mt32/FileStream.h
    audio/softsynth/mt32/LA32FloatWaveGenerator.cpp
    audio/softsynth/mt32/LA32FloatWaveGenerator.h
    audio/softsynth/mt32/LA32Ramp.cpp
    audio/softsynth/mt32/LA32Ramp.h
    audio/softsynth/mt32/LA32WaveGenerator.cpp
    audio/softsynth/mt32/LA32WaveGenerator.h
    audio/softsynth/mt32/MemoryRegion.h
    audio/softsynth/mt32/MidiEventQueue.h
    audio/softsynth/mt32/MidiStreamParser.cpp
    audio/softsynth/mt32/MidiStreamParser.h
    audio/softsynth/mt32/Part.cpp
    audio/softsynth/mt32/Part.h
    audio/softsynth/mt32/Partial.cpp
    audio/softsynth/mt32/Partial.h
    audio/softsynth/mt32/PartialManager.cpp
    audio/softsynth/mt32/PartialManager.h
    audio/softsynth/mt32/Poly.cpp
    audio/softsynth/mt32/Poly.h
    audio/softsynth/mt32/ROMInfo.cpp
    audio/softsynth/mt32/ROMInfo.h
    audio/softsynth/mt32/SampleRateConverter.cpp
    audio/softsynth/mt32/SampleRateConverter.h
    audio/softsynth/mt32/Structures.h
    audio/softsynth/mt32/Synth.cpp
    audio/softsynth/mt32/Synth.h
    audio/softsynth/mt32/TVA.cpp
    audio/softsynth/mt32/TVA.h
    audio/softsynth/mt32/TVF.cpp
    audio/softsynth/mt32/TVF.h
    audio/softsynth/mt32/TVP.cpp
    audio/softsynth/mt32/TVP.h
    audio/softsynth/mt32/Tables.cpp
    audio/softsynth/mt32/Tables.h
    audio/softsynth/mt32/Types.h
    audio/softsynth/mt32/c_interface/c_interface.cpp
    audio/softsynth/mt32/c_interface/c_interface.h
    audio/softsynth/mt32/c_interface/c_types.h
    audio/softsynth/mt32/c_interface/cpp_interface.h
    audio/softsynth/mt32/config.h
    audio/softsynth/mt32/globals.h
    audio/softsynth/mt32/internals.h
    audio/softsynth/mt32/mmath.h
    audio/softsynth/mt32/mt32emu.h
    audio/softsynth/mt32/srchelper/InternalResampler.cpp
    audio/softsynth/mt32/srchelper/InternalResampler.h
    audio/softsynth/mt32/srchelper/SamplerateAdapter.cpp
    audio/softsynth/mt32/srchelper/SamplerateAdapter.h
    audio/softsynth/mt32/srchelper/SoxrAdapter.cpp
    audio/softsynth/mt32/srchelper/SoxrAdapter.h
    audio/softsynth/mt32/srchelper/srctools/include/FIRResampler.h
    audio/softsynth/mt32/srchelper/srctools/include/FloatSampleProvider.h
    audio/softsynth/mt32/srchelper/srctools/include/IIR2xResampler.h
    audio/softsynth/mt32/srchelper/srctools/include/LinearResampler.h
    audio/softsynth/mt32/srchelper/srctools/include/ResamplerModel.h
    audio/softsynth/mt32/srchelper/srctools/include/ResamplerStage.h
    audio/softsynth/mt32/srchelper/srctools/include/SincResampler.h
    audio/softsynth/mt32/srchelper/srctools/src/FIRResampler.cpp
    audio/softsynth/mt32/srchelper/srctools/src/IIR2xResampler.cpp
    audio/softsynth/mt32/srchelper/srctools/src/LinearResampler.cpp
    audio/softsynth/mt32/srchelper/srctools/src/ResamplerModel.cpp
    audio/softsynth/mt32/srchelper/srctools/src/SincResampler.cpp


diff --git a/audio/softsynth/mt32/Analog.cpp b/audio/softsynth/mt32/Analog.cpp
index 6073357041..b14d824dda 100644
--- a/audio/softsynth/mt32/Analog.cpp
+++ b/audio/softsynth/mt32/Analog.cpp
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
@@ -273,8 +273,6 @@ Analog *Analog::createAnalog(const AnalogOutputMode mode, const bool oldMT32Anal
 		return new AnalogImpl<IntSampleEx>(mode, oldMT32AnalogLPF);
 	case RendererType_FLOAT:
 		return new AnalogImpl<FloatSample>(mode, oldMT32AnalogLPF);
-	default:
-		break;
 	}
 	return NULL;
 }
diff --git a/audio/softsynth/mt32/Analog.h b/audio/softsynth/mt32/Analog.h
index 3b6dcabfa3..244e4118f3 100644
--- a/audio/softsynth/mt32/Analog.h
+++ b/audio/softsynth/mt32/Analog.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/BReverbModel.cpp b/audio/softsynth/mt32/BReverbModel.cpp
index 5835bf0a6e..1eb6f7e568 100644
--- a/audio/softsynth/mt32/BReverbModel.cpp
+++ b/audio/softsynth/mt32/BReverbModel.cpp
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
@@ -633,8 +633,6 @@ BReverbModel *BReverbModel::createBReverbModel(const ReverbMode mode, const bool
 		return new BReverbModelImpl<IntSample>(mode, mt32CompatibleModel);
 	case RendererType_FLOAT:
 		return new BReverbModelImpl<FloatSample>(mode, mt32CompatibleModel);
-	default:
-		break;
 	}
 	return NULL;
 }
diff --git a/audio/softsynth/mt32/BReverbModel.h b/audio/softsynth/mt32/BReverbModel.h
index 5b1d411988..ee2f838b2e 100644
--- a/audio/softsynth/mt32/BReverbModel.h
+++ b/audio/softsynth/mt32/BReverbModel.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/Enumerations.h b/audio/softsynth/mt32/Enumerations.h
index bb580ca5b1..05a2b6f6db 100644
--- a/audio/softsynth/mt32/Enumerations.h
+++ b/audio/softsynth/mt32/Enumerations.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/File.cpp b/audio/softsynth/mt32/File.cpp
index a5967b4f34..dbe2266487 100644
--- a/audio/softsynth/mt32/File.cpp
+++ b/audio/softsynth/mt32/File.cpp
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/File.h b/audio/softsynth/mt32/File.h
index 91a0a7fe6c..a4b099fbb2 100644
--- a/audio/softsynth/mt32/File.h
+++ b/audio/softsynth/mt32/File.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/FileStream.cpp b/audio/softsynth/mt32/FileStream.cpp
index 9e477d4e9b..3fa1a31074 100644
--- a/audio/softsynth/mt32/FileStream.cpp
+++ b/audio/softsynth/mt32/FileStream.cpp
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
@@ -21,10 +21,6 @@
 
 #include "internals.h"
 
-// Disable MSVC STL exceptions
-#ifdef _MSC_VER
-#define _HAS_EXCEPTIONS 0
-#endif
 #include "FileStream.h"
 
 namespace MT32Emu {
diff --git a/audio/softsynth/mt32/FileStream.h b/audio/softsynth/mt32/FileStream.h
index ea5de69527..2279890b45 100644
--- a/audio/softsynth/mt32/FileStream.h
+++ b/audio/softsynth/mt32/FileStream.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/LA32FloatWaveGenerator.cpp b/audio/softsynth/mt32/LA32FloatWaveGenerator.cpp
index 6ff4aa37b4..34ea1fbf44 100644
--- a/audio/softsynth/mt32/LA32FloatWaveGenerator.cpp
+++ b/audio/softsynth/mt32/LA32FloatWaveGenerator.cpp
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/LA32FloatWaveGenerator.h b/audio/softsynth/mt32/LA32FloatWaveGenerator.h
index 7e92d0a67c..a21d68e2b3 100644
--- a/audio/softsynth/mt32/LA32FloatWaveGenerator.h
+++ b/audio/softsynth/mt32/LA32FloatWaveGenerator.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/LA32Ramp.cpp b/audio/softsynth/mt32/LA32Ramp.cpp
index 9dcf143fbf..122ee05ac8 100644
--- a/audio/softsynth/mt32/LA32Ramp.cpp
+++ b/audio/softsynth/mt32/LA32Ramp.cpp
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/LA32Ramp.h b/audio/softsynth/mt32/LA32Ramp.h
index 959a1ad372..802b34aa42 100644
--- a/audio/softsynth/mt32/LA32Ramp.h
+++ b/audio/softsynth/mt32/LA32Ramp.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/LA32WaveGenerator.cpp b/audio/softsynth/mt32/LA32WaveGenerator.cpp
index f6f6928801..f4f7eeccbc 100644
--- a/audio/softsynth/mt32/LA32WaveGenerator.cpp
+++ b/audio/softsynth/mt32/LA32WaveGenerator.cpp
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/LA32WaveGenerator.h b/audio/softsynth/mt32/LA32WaveGenerator.h
index c206daa63f..d2d74f48d2 100644
--- a/audio/softsynth/mt32/LA32WaveGenerator.h
+++ b/audio/softsynth/mt32/LA32WaveGenerator.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/MemoryRegion.h b/audio/softsynth/mt32/MemoryRegion.h
index 807f147820..c8e85c7fb6 100644
--- a/audio/softsynth/mt32/MemoryRegion.h
+++ b/audio/softsynth/mt32/MemoryRegion.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/MidiEventQueue.h b/audio/softsynth/mt32/MidiEventQueue.h
index 32a0bbe553..846f47c517 100644
--- a/audio/softsynth/mt32/MidiEventQueue.h
+++ b/audio/softsynth/mt32/MidiEventQueue.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
@@ -23,21 +23,6 @@
 
 namespace MT32Emu {
 
-/**
- * Used to safely store timestamped MIDI events in a local queue.
- */
-struct MidiEvent {
-	Bit32u shortMessageData;
-	const Bit8u *sysexData;
-	Bit32u sysexLength;
-	Bit32u timestamp;
-
-	MidiEvent();
-	~MidiEvent();
-	void setShortMessage(Bit32u shortMessageData, Bit32u timestamp);
-	void setSysex(const Bit8u *sysexData, Bit32u sysexLength, Bit32u timestamp);
-};
-
 /**
  * Simple queue implementation using a ring buffer to store incoming MIDI event before the synth actually processes it.
  * It is intended to:
@@ -49,22 +34,38 @@ struct MidiEvent {
  * and one performs only writing. More complicated usage requires external synchronisation.
  */
 class MidiEventQueue {
-private:
-	MidiEvent * const ringBuffer;
-	const Bit32u ringBufferMask;
-	volatile Bit32u startPosition;
-	volatile Bit32u endPosition;
-
 public:
-	MidiEventQueue(Bit32u ringBufferSize = DEFAULT_MIDI_EVENT_QUEUE_SIZE); // Must be a power of 2
+	class SysexDataStorage;
+
+	struct MidiEvent {
+		const Bit8u *sysexData;
+		union {
+			Bit32u sysexLength;
+			Bit32u shortMessageData;
+		};
+		Bit32u timestamp;
+	};
+
+	explicit MidiEventQueue(
+		// Must be a power of 2
+		Bit32u ringBufferSize,
+		Bit32u storageBufferSize
+	);
 	~MidiEventQueue();
 	void reset();
 	bool pushShortMessage(Bit32u shortMessageData, Bit32u timestamp);
 	bool pushSysex(const Bit8u *sysexData, Bit32u sysexLength, Bit32u timestamp);
-	const MidiEvent *peekMidiEvent();
+	const volatile MidiEvent *peekMidiEvent();
 	void dropMidiEvent();
-	bool isFull() const;
-	bool inline isEmpty() const;
+	inline bool isEmpty() const;
+
+private:
+	SysexDataStorage &sysexDataStorage;
+
+	MidiEvent * const ringBuffer;
+	const Bit32u ringBufferMask;
+	volatile Bit32u startPosition;
+	volatile Bit32u endPosition;
 };
 
 } // namespace MT32Emu
diff --git a/audio/softsynth/mt32/MidiStreamParser.cpp b/audio/softsynth/mt32/MidiStreamParser.cpp
index a426a20cc3..e9fbf76907 100644
--- a/audio/softsynth/mt32/MidiStreamParser.cpp
+++ b/audio/softsynth/mt32/MidiStreamParser.cpp
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/MidiStreamParser.h b/audio/softsynth/mt32/MidiStreamParser.h
index 881ec032f5..f26fe11b7b 100644
--- a/audio/softsynth/mt32/MidiStreamParser.h
+++ b/audio/softsynth/mt32/MidiStreamParser.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/Part.cpp b/audio/softsynth/mt32/Part.cpp
index 9c85ce5599..465903a726 100644
--- a/audio/softsynth/mt32/Part.cpp
+++ b/audio/softsynth/mt32/Part.cpp
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/Part.h b/audio/softsynth/mt32/Part.h
index a4de1060bc..bc2e11416a 100644
--- a/audio/softsynth/mt32/Part.h
+++ b/audio/softsynth/mt32/Part.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/Partial.cpp b/audio/softsynth/mt32/Partial.cpp
index 60c06b7be7..877d93b454 100644
--- a/audio/softsynth/mt32/Partial.cpp
+++ b/audio/softsynth/mt32/Partial.cpp
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
@@ -37,7 +37,7 @@ static const Bit8u PAN_NUMERATOR_SLAVE[]  = {0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7,
 // We assume the pan is applied using the same 13-bit multiplier circuit that is also used for ring modulation
 // because of the observed sample overflow, so the panSetting values are likely mapped in a similar way via a LUT.
 // FIXME: Sample analysis suggests that the use of panSetting is linear, but there are some quirks that still need to be resolved.
-static Bit32s getPANFactor(Bit32s panSetting) {
+static Bit32s getPanFactor(Bit32s panSetting) {
 	static const Bit32u PAN_FACTORS_COUNT = 15;
 	static Bit32s PAN_FACTORS[PAN_FACTORS_COUNT];
 	static bool firstRun = true;
@@ -118,7 +118,7 @@ void Partial::deactivate() {
 		poly->partialDeactivated(this);
 	}
 #if MT32EMU_MONITOR_PARTIALS > 2
-	synth->printDebug("[+%lu] [Partial %d] Deactivated", sampleNum, debugPartialNum);
+	synth->printDebug("[+%lu] [Partial %d] Deactivated", sampleNum, partialIndex);
 	synth->printPartialUsage(sampleNum);
 #endif
 	if (isRingModulatingSlave()) {
@@ -155,20 +155,18 @@ void Partial::startPartial(const Part *part, Poly *usePoly, const PatchCache *us
 		// Do a normal mix independent of any pair partial.
 		mixType = 0;
 		pairPartial = NULL;
-	} else {
+	} else if (!synth->isNicePanningEnabled()) {
 		// Mok wanted an option for smoother panning, and we love Mok.
-#ifndef INACCURATE_SMOOTH_PAN
-		// CONFIRMED by Mok: exactly bytes like this (right shifted?) are sent to the LA32.
+		// CONFIRMED by Mok: exactly bytes like this (right shifted) are sent to the LA32.
 		panSetting &= 0x0E;
-#endif
 	}
 
 	leftPanValue = synth->reversedStereoEnabled ? 14 - panSetting : panSetting;
 	rightPanValue = 14 - leftPanValue;
 
 	if (!floatMode) {
-		leftPanValue = getPANFactor(leftPanValue);
-		rightPanValue = getPANFactor(rightPanValue);
+		leftPanValue = getPanFactor(leftPanValue);
+		rightPanValue = getPanFactor(rightPanValue);
 	}
 
 	// SEMI-CONFIRMED: From sample analysis:
@@ -184,7 +182,7 @@ void Partial::startPartial(const Part *part, Poly *usePoly, const PatchCache *us
 	// whole-quarter assignment or after some partials got aborted, even 4-partial timbres can be found sounding differently.
 	// This behaviour is also confirmed with two more special timbres: one with identical sawtooth partials, and one with PCM wave 02.
 	// For my personal taste, this behaviour rather enriches the sounding and should be emulated.
-	if (partialIndex & 4) {
+	if (!synth->isNicePartialMixingEnabled() && (partialIndex & 4)) {
 		leftPanValue = -leftPanValue;
 		rightPanValue = -rightPanValue;
 	}
diff --git a/audio/softsynth/mt32/Partial.h b/audio/softsynth/mt32/Partial.h
index e297710f78..0c4355742a 100644
--- a/audio/softsynth/mt32/Partial.h
+++ b/audio/softsynth/mt32/Partial.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
@@ -45,8 +45,9 @@ private:
 	// This is only kept available for debugging purposes.
 	Bit32u sampleNum;
 
-	// Actually, this is a 4-bit register but we abuse this to emulate inverted mixing.
-	// Also we double the value to enable INACCURATE_SMOOTH_PAN, with respect to MoK.
+	// Actually, LA-32 receives only 3 bits as a pan setting, but we abuse these to emulate
+	// the inverted partial mixing as well. Also we double the values (making them correspond
+	// to the panpot range) to enable NicePanning mode, with respect to MoK.
 	Bit32s leftPanValue, rightPanValue;
 
 	int ownerPart; // -1 if unassigned
diff --git a/audio/softsynth/mt32/PartialManager.cpp b/audio/softsynth/mt32/PartialManager.cpp
index aeba5ce8e0..508d5fa6c7 100644
--- a/audio/softsynth/mt32/PartialManager.cpp
+++ b/audio/softsynth/mt32/PartialManager.cpp
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/PartialManager.h b/audio/softsynth/mt32/PartialManager.h
index deded8f150..6b59857cc2 100644
--- a/audio/softsynth/mt32/PartialManager.h
+++ b/audio/softsynth/mt32/PartialManager.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/Poly.cpp b/audio/softsynth/mt32/Poly.cpp
index 44b8d24460..f37e471d4f 100644
--- a/audio/softsynth/mt32/Poly.cpp
+++ b/audio/softsynth/mt32/Poly.cpp
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/Poly.h b/audio/softsynth/mt32/Poly.h
index b2d4eceaf9..5b7cc30e4d 100644
--- a/audio/softsynth/mt32/Poly.h
+++ b/audio/softsynth/mt32/Poly.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/ROMInfo.cpp b/audio/softsynth/mt32/ROMInfo.cpp
index 8c813a4e69..308d3eb1ec 100644
--- a/audio/softsynth/mt32/ROMInfo.cpp
+++ b/audio/softsynth/mt32/ROMInfo.cpp
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/ROMInfo.h b/audio/softsynth/mt32/ROMInfo.h
index cd4a1c5ac0..b695ba2a1e 100644
--- a/audio/softsynth/mt32/ROMInfo.h
+++ b/audio/softsynth/mt32/ROMInfo.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/SampleRateConverter.cpp b/audio/softsynth/mt32/SampleRateConverter.cpp
index 73f7963e21..9ae35e9621 100644
--- a/audio/softsynth/mt32/SampleRateConverter.cpp
+++ b/audio/softsynth/mt32/SampleRateConverter.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2017 Sergey V. Mikayev
+/* Copyright (C) 2015-2020 Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/SampleRateConverter.h b/audio/softsynth/mt32/SampleRateConverter.h
index e8950111f0..96f3925e35 100644
--- a/audio/softsynth/mt32/SampleRateConverter.h
+++ b/audio/softsynth/mt32/SampleRateConverter.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2017 Sergey V. Mikayev
+/* Copyright (C) 2015-2020 Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/Structures.h b/audio/softsynth/mt32/Structures.h
index d116aaeb46..de7281b165 100644
--- a/audio/softsynth/mt32/Structures.h
+++ b/audio/softsynth/mt32/Structures.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/Synth.cpp b/audio/softsynth/mt32/Synth.cpp
index 0486aa4eff..d61ad44a6c 100644
--- a/audio/softsynth/mt32/Synth.cpp
+++ b/audio/softsynth/mt32/Synth.cpp
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
@@ -195,6 +195,8 @@ public:
 	RendererType selectedRendererType;
 	Bit32s masterTunePitchDelta;
 	bool niceAmpRamp;
+	bool nicePanning;
+	bool nicePartialMixing;
 
 	// Here we keep the reverse mapping of assigned parts per MIDI channel.
 	// NOTE: value above 8 means that the channel is not assigned
@@ -202,6 +204,11 @@ public:
 
 	// This stores the index of Part in chantable that failed to play and required partial abortion.
 	Bit32u abortingPartIx;
+
+	bool preallocatedReverbMemory;
+
+	Bit32u midiEventQueueSize;
+	Bit32u midiEventQueueSysexStorageBufferSize;
 };
 
 Bit32u Synth::getLibraryVersionInt() {
@@ -245,7 +252,8 @@ Synth::Synth(ReportHandler *useReportHandler) :
 		isDefaultReportHandler = false;
 	}
 
-	for (int i = 0; i < 4; i++) {
+	extensions.preallocatedReverbMemory = false;
+	for (int i = REVERB_MODE_ROOM; i <= REVERB_MODE_TAP_DELAY; i++) {
 		reverbModels[i] = NULL;
 	}
 	reverbModel = NULL;
@@ -257,6 +265,8 @@ Synth::Synth(ReportHandler *useReportHandler) :
 	setReverbOutputGain(1.0f);
 	setReversedStereoEnabled(false);
 	setNiceAmpRampEnabled(true);
+	setNicePanningEnabled(false);
+	setNicePartialMixingEnabled(false);
 	selectRendererType(RendererType_BIT16S);
 
 	patchTempMemoryRegion = NULL;
@@ -274,6 +284,8 @@ Synth::Synth(ReportHandler *useReportHandler) :
 	pcmROMData = NULL;
 	soundGroupNames = NULL;
 	midiQueue = NULL;
+	extensions.midiEventQueueSize = DEFAULT_MIDI_EVENT_QUEUE_SIZE;
+	extensions.midiEventQueueSysexStorageBufferSize = 0;
 	lastReceivedMIDIEventTimestamp = 0;
 	memset(parts, 0, sizeof(parts));
 	renderedSampleCount = 0;
@@ -320,16 +332,27 @@ void Synth::newTimbreSet(Bit8u partNum, Bit8u timbreGroup, Bit8u timbreNumber, c
 	reportHandler->onProgramChanged(partNum, soundGroupName, patchName);
 }
 
+#define MT32EMU_PRINT_DEBUG \
+	va_list ap; \
+	va_start(ap, fmt); \
+	reportHandler->printDebug(fmt, ap); \
+	va_end(ap);
+
+#if MT32EMU_DEBUG_SAMPLESTAMPS > 0
+static inline void printSamplestamp(ReportHandler *reportHandler, const char *fmt, ...) {
+	MT32EMU_PRINT_DEBUG
+}
+#endif
+
 void Synth::printDebug(const char *fmt, ...) {
-	va_list ap;
-	va_start(ap, fmt);
 #if MT32EMU_DEBUG_SAMPLESTAMPS > 0
-	reportHandler->printDebug("[%u]", (va_list)&renderedSampleCount);
+	printSamplestamp(reportHandler, "[%u]", renderedSampleCount);
 #endif
-	reportHandler->printDebug(fmt, ap);
-	va_end(ap);
+	MT32EMU_PRINT_DEBUG
 }
 
+#undef MT32EMU_PRINT_DEBUG
+
 void Synth::setReverbEnabled(bool newReverbEnabled) {
 	if (!opened) return;
 	if (isReverbEnabled() == newReverbEnabled) return;
@@ -339,9 +362,9 @@ void Synth::setReverbEnabled(bool newReverbEnabled) {
 		refreshSystemReverbParameters();
 		reverbOverridden = oldReverbOverridden;
 	} else {
-#if MT32EMU_REDUCE_REVERB_MEMORY
-		reverbModel->close();
-#endif
+		if (!extensions.preallocatedReverbMemory) {
+			reverbModel->close();
+		}
 		reverbModel = NULL;
 	}
 }
@@ -362,7 +385,7 @@ void Synth::setReverbCompatibilityMode(bool mt32CompatibleMode) {
 	if (!opened || (isMT32ReverbCompatibilityMode() == mt32CompatibleMode)) return;
 	bool oldReverbEnabled = isReverbEnabled();
 	setReverbEnabled(false);
-	for (int i = 0; i < 4; i++) {
+	for (int i = REVERB_MODE_ROOM; i <= REVERB_MODE_TAP_DELAY; i++) {
 		delete reverbModels[i];
 	}
 	initReverbModels(mt32CompatibleMode);
@@ -378,6 +401,19 @@ bool Synth::isDefaultReverbMT32Compatible() const {
 	return opened && controlROMFeatures->defaultReverbMT32Compatible;
 }
 
+void Synth::preallocateReverbMemory(bool enabled) {
+	if (extensions.preallocatedReverbMemory == enabled) return;
+	extensions.preallocatedReverbMemory = enabled;
+	if (!opened) return;
+	for (int i = REVERB_MODE_ROOM; i <= REVERB_MODE_TAP_DELAY; i++) {
+		if (enabled) {
+			reverbModels[i]->open();
+		} else if (reverbModel != reverbModels[i]) {
+			reverbModels[i]->close();
+		}
+	}
+}
+
 void Synth::setDACInputMode(DACInputMode mode) {
 	dacInputMode = mode;
 }
@@ -430,6 +466,22 @@ bool Synth::isNiceAmpRampEnabled() const {
 	return extensions.niceAmpRamp;
 }
 
+void Synth::setNicePanningEnabled(bool enabled) {
+	extensions.nicePanning = enabled;
+}
+
+bool Synth::isNicePanningEnabled() const {
+	return extensions.nicePanning;
+}
+
+void Synth::setNicePartialMixingEnabled(bool enabled) {
+	extensions.nicePartialMixing = enabled;
+}
+
+bool Synth::isNicePartialMixingEnabled() const {
+	return extensions.nicePartialMixing;
+}
+
 bool Synth::loadControlROM(const ROMImage &controlROMImage) {
 	File *file = controlROMImage.getFile();
 	const ROMInfo *controlROMInfo = controlROMImage.getROMInfo();
@@ -572,15 +624,13 @@ bool Synth::initTimbres(Bit16u mapAddress, Bit16u offset, Bit16u count, Bit16u s
 }
 
 void Synth::initReverbModels(bool mt32CompatibleMode) {
-	reverbModels[REVERB_MODE_ROOM] = BReverbModel::createBReverbModel(REVERB_MODE_ROOM, mt32CompatibleMode, getSelectedRendererType());
-	reverbModels[REVERB_MODE_HALL] = BReverbModel::createBReverbModel(REVERB_MODE_HALL, mt32CompatibleMode, getSelectedRendererType());
-	reverbModels[REVERB_MODE_PLATE] = BReverbModel::createBReverbModel(REVERB_MODE_PLATE, mt32CompatibleMode, getSelectedRendererType());
-	reverbModels[REVERB_MODE_TAP_DELAY] = BReverbModel::createBReverbModel(REVERB_MODE_TAP_DELAY, mt32CompatibleMode, getSelectedRendererType());
-#if !MT32EMU_REDUCE_REVERB_MEMORY
-	for (int i = REVERB_MODE_ROOM; i <= REVERB_MODE_TAP_DELAY; i++) {
-		reverbModels[i]->open();
+	for (int mode = REVERB_MODE_ROOM; mode <= REVERB_MODE_TAP_DELAY; mode++) {
+		reverbModels[mode] = BReverbModel::createBReverbModel(ReverbMode(mode), mt32CompatibleMode, getSelectedRendererType());
+
+		if (extensions.preallocatedReverbMemory) {
+			reverbModels[mode]->open();
+		}
 	}
-#endif
 }
 
 void Synth::initSoundGroups(char newSoundGroupNames[][9]) {
@@ -759,7 +809,7 @@ bool Synth::open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, B
 	// For resetting mt32 mid-execution
 	mt32default = mt32ram;
 
-	midiQueue = new MidiEventQueue();
+	midiQueue = new MidiEventQueue(extensions.midiEventQueueSize, extensions.midiEventQueueSysexStorageBufferSize);
 
 	analog = Analog::createAnalog(analogOutputMode, controlROMFeatures->oldMT32AnalogLPF, getSelectedRendererType());
 #if MT32EMU_MONITOR_INIT
@@ -828,7 +878,7 @@ void Synth::dispose() {
 
 	deleteMemoryRegions();
 
-	for (int i = 0; i < 4; i++) {
+	for (int i = REVERB_MODE_ROOM; i <= REVERB_MODE_TAP_DELAY; i++) {
 		delete reverbModels[i];
 		reverbModels[i] = NULL;
 	}
@@ -848,26 +898,24 @@ bool Synth::isOpen() const {
 }
 
 void Synth::flushMIDIQueue() {
-	if (midiQueue != NULL) {
-		for (;;) {
-			const MidiEvent *midiEvent = midiQueue->peekMidiEvent();
-			if (midiEvent == NULL) break;
-			if (midiEvent->sysexData == NULL) {
-				playMsgNow(midiEvent->shortMessageData);
-			} else {
-				playSysexNow(midiEvent->sysexData, midiEvent->sysexLength);
-			}
-			midiQueue->dropMidiEvent();
+	if (midiQueue == NULL) return;
+	for (;;) {
+		const volatile MidiEventQueue::MidiEvent *midiEvent = midiQueue->peekMidiEvent();
+		if (midiEvent == NULL) break;
+		if (midiEvent->sysexData == NULL) {
+			playMsgNow(midiEvent->shortMessageData);
+		} else {
+			playSysexNow(midiEvent->sysexData, midiEvent->sysexLength);
 		}
-		lastReceivedMIDIEventTimestamp = renderedSampleCount;
+		midiQueue->dropMidiEvent();
 	}
+	lastReceivedMIDIEventTimestamp = renderedSampleCount;
 }
 
 Bit32u Synth::setMIDIEventQueueSize(Bit32u useSize) {
 	static const Bit32u MAX_QUEUE_SIZE = (1 << 24); // This results in about 256 Mb - much greater than any reasonable value
 
-	if (midiQueue == NULL) return 0;
-	flushMIDIQueue();
+	if (extensions.midiEventQueueSize == useSize) return useSize;
 
 	// Find a power of 2 that is >= useSize
 	Bit32u binarySize = 1;
@@ -877,11 +925,26 @@ Bit32u Synth::setMIDIEventQueueSize(Bit32u useSize) {
 	} else {
 		binarySize = MAX_QUEUE_SIZE;
 	}
-	delete midiQueue;
-	midiQueue = new MidiEventQueue(binarySize);
+	extensions.midiEventQueueSize = binarySize;
+	if (midiQueue != NULL) {
+		flushMIDIQueue();
+		delete midiQueue;
+		midiQueue = new MidiEventQueue(binarySize, extensions.midiEventQueueSysexStorageBufferSize);
+	}
 	return binarySize;
 }
 
+void Synth::configureMIDIEventQueueSysexStorage(Bit32u storageBufferSize) {
+	if (extensions.midiEventQueueSysexStorageBufferSize == storageBufferSize) return;
+
+	extensions.midiEventQueueSysexStorageBufferSize = storageBufferSize;
+	if (midiQueue != NULL) {
+		flushMIDIQueue();
+		delete midiQueue;
+		midiQueue = new MidiEventQueue(extensions.midiEventQueueSize, storageBufferSize);
+	}
+}
+
 Bit32u Synth::getShortMessageLength(Bit32u msg) {
 	if ((msg & 0xF0) == 0xF0) {
 		switch (msg & 0xFF) {
@@ -966,7 +1029,7 @@ void Synth::playMsgNow(Bit32u msg) {
 	Bit8u *chanParts = extensions.chantable[chan];
 	if (*chanParts > 8) {
 #if MT32EMU_MONITOR_MIDI > 0
-		printDebug("Play msg on unreg chan %d (%d): code=0x%01x, vel=%d", chan, part, code, velocity);
+		printDebug("Play msg on unreg chan %d (%d): code=0x%01x, vel=%d", chan, *chanParts, code, velocity);
 #endif
 		return;
 	}
@@ -1464,7 +1527,7 @@ void Synth::writeMemoryRegion(const MemoryRegion *region, Bit32u addr, Bit32u le
 			char instrumentName[11];
 			memcpy(instrumentName, mt32ram.timbres[patchAbsTimbreNum].timbre.common.name, 10);
 			instrumentName[10] = 0;
-			Bit8u *n = (Bit8u *)patch;
+			Bit8u *n = reinterpret_cast<Bit8u *>(patch);
 			printDebug("WRITE-PATCH (%d-%d@%d..%d): %d; timbre=%d (%s) %02X%02X%02X%02X%02X%02X%02X%02X", first, last, off, off + len, i, patchAbsTimbreNum, instrumentName, n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7]);
 		}
 #endif
@@ -1611,8 +1674,6 @@ void Synth::writeMemoryRegion(const MemoryRegion *region, Bit32u addr, Bit32u le
 	case MR_Reset:
 		reset();
 		break;
-	default:
-		break;
 	}
 }
 
@@ -1651,18 +1712,18 @@ void Synth::refreshSystemReverbParameters() {
 		reverbModel = reverbModels[mt32ram.system.reverbMode];
 	}
 	if (reverbModel != oldReverbModel) {
-#if MT32EMU_REDUCE_REVERB_MEMORY
-		if (oldReverbModel != NULL) {
-			oldReverbModel->close();
-		}
-		if (isReverbEnabled()) {
-			reverbModel->open();
-		}
-#else
-		if (isReverbEnabled()) {
-			reverbModel->mute();
+		if (extensions.preallocatedReverbMemory) {
+			if (isReverbEnabled()) {
+				reverbModel->mute();
+			}
+		} else {
+			if (oldReverbModel != NULL) {
+				oldReverbModel->close();
+			}
+			if (isReverbEnabled()) {
+				reverbModel->open();
+			}
 		}
-#endif
 	}
 	if (isReverbEnabled()) {
 		reverbModel->setParameters(mt32ram.system.reverbTime, mt32ram.system.reverbLevel);
@@ -1755,46 +1816,120 @@ Bit32s Synth::getMasterTunePitchDelta() const {
 	return extensions.masterTunePitchDelta;
 }
 
-MidiEvent::MidiEvent() {
-	shortMessageData = 0;
-	sysexData = NULL;
-	sysexLength = 0;
-	timestamp = 0;
-}
+/** Defines an interface of a class that maintains storage of variable-sized data of SysEx messages. */
+class MidiEventQueue::SysexDataStorage {
+public:
+	static MidiEventQueue::SysexDataStorage *create(Bit32u storageBufferSize);
 
-MidiEvent::~MidiEvent() {
-	if (sysexData != NULL) {
-		delete[] sysexData;
+	virtual ~SysexDataStorage() {}
+	virtual Bit8u *allocate(Bit32u sysexLength) = 0;
+	virtual void reclaimUnused(const Bit8u *sysexData, Bit32u sysexLength) = 0;
+	virtual void dispose(const Bit8u *sysexData, Bit32u sysexLength) = 0;
+};
+
+/** Storage space for SysEx data is allocated dynamically on demand and is disposed lazily. */
+class DynamicSysexDataStorage : public MidiEventQueue::SysexDataStorage {
+public:
+	Bit8u *allocate(Bit32u sysexLength) {
+		return new Bit8u[sysexLength];
 	}
-}
 
-void MidiEvent::setShortMessage(Bit32u useShortMessageData, Bit32u useTimestamp) {
-	if (sysexData != NULL) {
+	void reclaimUnused(const Bit8u *, Bit32u) {}
+
+	void dispose(const Bit8u *sysexData, Bit32u) {
 		delete[] sysexData;
 	}
-	shortMessageData = useShortMessageData;
-	timestamp = useTimestamp;
-	sysexData = NULL;
-	sysexLength = 0;
-}
+};
 
-void MidiEvent::setSysex(const Bit8u *useSysexData, Bit32u useSysexLength, Bit32u useTimestamp) {
-	if (sysexData != NULL) {
-		delete[] sysexData;
+/**
+ * SysEx data is stored in a preallocated buffer, that makes this kind of storage safe
+ * for use in a realtime thread. Additionally, the space retained by a SysEx event,
+ * that has been processed and thus is no longer necessary, is disposed instantly.
+ */
+class BufferedSysexDataStorage : public MidiEventQueue::SysexDataStorage {
+public:
+	explicit BufferedSysexDataStorage(Bit32u useStorageBufferSize) :
+		storageBuffer(new Bit8u[useStorageBufferSize]),
+		storageBufferSize(useStorageBufferSize),
+		startPosition(),
+		endPosition()
+	{}
+
+	~BufferedSysexDataStorage() {
+		delete[] storageBuffer;
+	}
+
+	Bit8u *allocate(Bit32u sysexLength) {
+		Bit32u myStartPosition = startPosition;
+		Bit32u myEndPosition = endPosition;
+
+		// When the free space isn't contiguous, the data is allocated either right after the end position
+		// or at the buffer beginning, wherever it fits.
+		if (myStartPosition > myEndPosition) {
+			if (myStartPosition - myEndPosition <= sysexLength) return NULL;
+		} else if (storageBufferSize - myEndPosition < sysexLength) {
+			// There's not enough free space at the end to place the data block.
+			if (myStartPosition == myEndPosition) {
+				// The buffer is empty -> reset positions to the buffer beginning.
+				if (storageBufferSize <= sysexLength) return NULL;
+				if (myStartPosition != 0) {
+					myStartPosition = 0;
+					// It's OK to write startPosition here non-atomically. We don't expect any
+					// concurrent reads, as there must be no SysEx messages in the queue.
+					startPosition = myStartPosition;
+				}
+			} else if (myStartPosition <= sysexLength) return NULL;
+			myEndPosition = 0;
+		}
+		endPosition = myEndPosition + sysexLength;
+		return storageBuffer + myEndPosition;
+	}
+
+	void reclaimUnused(const Bit8u *sysexData, Bit32u sysexLength) {
+		if (sysexData == NULL) return;
+		Bit32u allocatedPosition = startPosition;
+		if (storageBuffer + allocatedPosition == sysexData) {
+			startPosition = allocatedPosition + sysexLength;
+		} else if (storageBuffer == sysexData) {
+			// Buffer wrapped around.
+			startPosition = sysexLength;
+		}
+	}
+
+	void dispose(const Bit8u *, Bit32u) {}
+
+private:
+	Bit8u * const storageBuffer;
+	const Bit32u storageBufferSize;
+
+	volatile Bit32u startPosition;
+	volatile Bit32u endPosition;
+};
+
+MidiEventQueue::SysexDataStorage *MidiEventQueue::SysexDataStorage::create(Bit32u storageBufferSize) {
+	if (storageBufferSize > 0) {
+		return new BufferedSysexDataStorage(storageBufferSize);
+	} else {
+		return new DynamicSysexDataStorage;
 	}
-	shortMessageData = 0;
-	timestamp = useTimestamp;
-	sysexLength = useSysexLength;
-	Bit8u *dstSysexData = new Bit8u[sysexLength];
-	sysexData = dstSysexData;
-	memcpy(dstSysexData, useSysexData, sysexLength);
 }
 
-MidiEventQueue::MidiEventQueue(Bit32u useRingBufferSize) : ringBuffer(new MidiEvent[useRingBufferSize]), ringBufferMask(useRingBufferSize - 1) {
+MidiEventQueue::MidiEventQueue(Bit32u useRingBufferSize, Bit32u storageBufferSize) :
+	sysexDataStorage(*SysexDataStorage::create(storageBufferSize)),
+	ringBuffer(new MidiEvent[useRingBufferSize]), ringBufferMask(useRingBufferSize - 1)
+{
+	for (Bit32u i = 0; i <= ringBufferMask; i++) {
+		ringBuffer[i].sysexData = NULL;
+	}
 	reset();
 }
 
 MidiEventQueue::~MidiEventQueue() {
+	for (Bit32u i = 0; i <= ringBufferMask; i++) {
+		volatile MidiEvent &currentEvent = ringBuffer[i];
+		sysexDataStorage.dispose(currentEvent.sysexData, currentEvent.sysexLength);
+	}
+	delete &sysexDataStorage;
 	delete[] ringBuffer;
 }
 
@@ -1805,35 +1940,42 @@ void MidiEventQueue::reset() {
 
 bool MidiEventQueue::pushShortMessage(Bit32u shortMessageData, Bit32u timestamp) {
 	Bit32u newEndPosition = (endPosition + 1) & ringBufferMask;
-	// Is ring buffer full?
+	// If ring buffer is full, bail out.
 	if (startPosition == newEndPosition) return false;
-	ringBuffer[endPosition].setShortMessage(shortMessageData, timestamp);
+	volatile MidiEvent &newEvent = ringBuffer[endPosition];
+	sysexDataStorage.dispose(newEvent.sysexData, newEvent.sysexLength);
+	newEvent.sysexData = NULL;
+	newEvent.shortMessageData = shortMessageData;
+	newEvent.timestamp = timestamp;
 	endPosition = newEndPosition;
 	return true;
 }
 
 bool MidiEventQueue::pushSysex(const Bit8u *sysexData, Bit32u sysexLength, Bit32u timestamp) {
 	Bit32u newEndPosition = (endPosition + 1) & ringBufferMask;
-	// Is ring buffer full?
+	// If ring buffer is full, bail out.
 	if (startPosition == newEndPosition) return false;
-	ringBuffer[endPosition].setSysex(sysexData, sysexLength, timestamp);
+	volatile MidiEvent &newEvent = ringBuffer[endPosition];
+	sysexDataStorage.dispose(newEvent.sysexData, newEvent.sysexLength);
+	Bit8u *dstSysexData = sysexDataStorage.allocate(sysexLength);
+	if (dstSysexData == NULL) return false;
+	memcpy(dstSysexData, sysexData, sysexLength);
+	newEvent.sysexData = dstSysexData;
+	newEvent.sysexLength = sysexLength;
+	newEvent.timestamp = timestamp;
 	endPosition = newEndPosition;
 	return true;
 }
 
-const MidiEvent *MidiEventQueue::peekMidiEvent() {
+const volatile MidiEventQueue::MidiEvent *MidiEventQueue::peekMidiEvent() {
 	return isEmpty() ? NULL : &ringBuffer[startPosition];
 }
 
 void MidiEventQueue::dropMidiEvent() {
-	// Is ring buffer empty?
-	if (startPosition != endPosition) {
-		startPosition = (startPosition + 1) & ringBufferMask;
-	}
-}
-
-bool MidiEventQueue::isFull() const {
-	return startPosition == ((endPosition + 1) & ringBufferMask);
+	if (isEmpty()) return;
+	volatile MidiEvent &unusedEvent = ringBuffer[startPosition];
+	sysexDataStorage.reclaimUnused(unusedEvent.sysexData, unusedEvent.sysexLength);
+	startPosition = (startPosition + 1) & ringBufferMask;
 }
 
 bool MidiEventQueue::isEmpty() const {
@@ -1972,7 +2114,7 @@ void RendererImpl<Sample>::doRenderStreams(const DACOutputStreams<Sample> &strea
 		// We need to ensure zero-duration notes will play so add minimum 1-sample delay.
 		Bit32u thisLen = 1;
 		if (!isAbortingPoly()) {
-			const MidiEvent *nextEvent = getMidiQueue().peekMidiEvent();
+			const volatile MidiEventQueue::MidiEvent *nextEvent = getMidiQueue().peekMidiEvent();
 			Bit32s samplesToNextEvent = (nextEvent != NULL) ? Bit32s(nextEvent->timestamp - getRenderedSampleCount()) : MAX_SAMPLES_PER_RUN;
 			if (samplesToNextEvent > 0) {
 				thisLen = len > MAX_SAMPLES_PER_RUN ? MAX_SAMPLES_PER_RUN : len;
diff --git a/audio/softsynth/mt32/Synth.h b/audio/softsynth/mt32/Synth.h
index 54417d5b44..65f2656e62 100644
--- a/audio/softsynth/mt32/Synth.h
+++ b/audio/softsynth/mt32/Synth.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
@@ -115,6 +115,7 @@ public:
 
 class Synth {
 friend class DefaultMidiStreamParser;
+friend class MemoryRegion;
 friend class Part;
 friend class Partial;
 friend class PartialManager;
@@ -311,7 +312,18 @@ public:
 	// Sets size of the internal MIDI event queue. The queue size is set to the minimum power of 2 that is greater or equal to the size specified.
 	// The queue is flushed before reallocation.
 	// Returns the actual queue size being used.
-	MT32EMU_EXPORT Bit32u setMIDIEventQueueSize(Bit32u);
+	MT32EMU_EXPORT Bit32u setMIDIEventQueueSize(Bit32u requestedSize);
+
+	// Configures the SysEx storage of the internal MIDI event queue.
+	// Supplying 0 in the storageBufferSize argument makes the SysEx data stored
+	// in multiple dynamically allocated buffers per MIDI event. These buffers are only disposed
+	// when a new MIDI event replaces the SysEx event in the queue, thus never on the rendering thread.
+	// This is the default behaviour.
+	// In contrast, when a positive value is specified, SysEx data will be stored in a single preallocated buffer,
+	// which makes this kind of storage safe for use in a realtime thread. Additionally, the space retained
+	// by a SysEx event, that has been processed and thus is no longer necessary, is disposed instantly.
+	// Note, the queue is flushed and recreated in the process so that its size remains intact.
+	MT32EMU_EXPORT void configureMIDIEventQueueSysexStorage(Bit32u storageBufferSize);
 
 	// Returns current value of the global counter of samples rendered since the synth was created (at the native sample rate 32000 Hz).
 	// This method helps to compute accurate timestamp of a MIDI message to use with the methods below.
@@ -379,6 +391,10 @@ public:
 	MT32EMU_EXPORT bool isMT32ReverbCompatibilityMode() const;
 	// Returns whether default reverb compatibility mode is the old MT-32 compatibility mode.
 	MT32EMU_EXPORT bool isDefaultReverbMT32Compatible() const;
+	// If enabled, reverb buffers for all modes are keept around allocated all the time to avoid memory
+	// allocating/freeing in the rendering thread, which may be required for realtime operation.
+	// Otherwise, reverb buffers that are not in use are deleted to save memory (the default behaviour).
+	MT32EMU_EXPORT void preallocateReverbMemory(bool enabled);
 	// Sets new DAC input mode. See DACInputMode for details.
 	MT32EMU_EXPORT void setDACInputMode(DACInputMode mode);
 	// Returns current DAC input mode. See DACInputMode for details.
@@ -422,6 +438,29 @@ public:
 	// Returns whether NiceAmpRamp mode is enabled.
 	MT32EMU_EXPORT bool isNiceAmpRampEnabled() const;
 
+	// Allows to toggle the NicePanning mode.
+	// Despite the Roland's manual specifies allowed panpot values in range 0-14,
+	// the LA-32 only receives 3-bit pan setting in fact. In particular, this
+	// makes it impossible to set the "middle" panning for a single partial.
+	// In the NicePanning mode, we enlarge the pan setting accuracy to 4 bits
+	// making it smoother thus sacrificing the emulation accuracy.
+	// This mode is disabled by default.
+	MT32EMU_EXPORT void setNicePanningEnabled(bool enabled);
+	// Returns whether NicePanning mode is enabled.
+	MT32EMU_EXPORT bool isNicePanningEnabled() const;
+
+	// Allows to toggle the NicePartialMixing mode.
+	// LA-32 is known to mix partials either in-phase (so that they are added)
+	// or in counter-phase (so that they are subtracted instead).
+	// In some cases, this quirk isn't highly desired because a pair of closely
+	// sounding partials may occasionally cancel out.
+	// In the NicePartialMixing mode, the mixing is always performed in-phase,
+	// thus making the behaviour more predictable.
+	// This mode is disabled by default.
+	MT32EMU_EXPORT void setNicePartialMixingEnabled(bool enabled);
+	// Returns whether NicePartialMixing mode is enabled.
+	MT32EMU_EXPORT bool isNicePartialMixingEnabled() const;
+
 	// Selects new type of the wave generator and renderer to be used during subsequent calls to open().
 	// By default, RendererType_BIT16S is selected.
 	// See RendererType for details.
diff --git a/audio/softsynth/mt32/TVA.cpp b/audio/softsynth/mt32/TVA.cpp
index 3f7064f9a4..a49ad0193a 100644
--- a/audio/softsynth/mt32/TVA.cpp
+++ b/audio/softsynth/mt32/TVA.cpp
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/TVA.h b/audio/softsynth/mt32/TVA.h
index cf9296d481..de6e610170 100644
--- a/audio/softsynth/mt32/TVA.h
+++ b/audio/softsynth/mt32/TVA.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/TVF.cpp b/audio/softsynth/mt32/TVF.cpp
index d0c21c8169..3d5f26049a 100644
--- a/audio/softsynth/mt32/TVF.cpp
+++ b/audio/softsynth/mt32/TVF.cpp
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
@@ -206,8 +206,6 @@ void TVF::nextPhase() {
 		}
 		startRamp((levelMult * partialParam->tvf.envLevel[3]) >> 8, 0, newPhase);
 		return;
-	default:
-		break;
 	}
 
 	int envPointIndex = phase;
diff --git a/audio/softsynth/mt32/TVF.h b/audio/softsynth/mt32/TVF.h
index e637aa5b48..149b1d09b2 100644
--- a/audio/softsynth/mt32/TVF.h
+++ b/audio/softsynth/mt32/TVF.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/TVP.cpp b/audio/softsynth/mt32/TVP.cpp
index a3b364048a..3d5f492fda 100644
--- a/audio/softsynth/mt32/TVP.cpp
+++ b/audio/softsynth/mt32/TVP.cpp
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
@@ -104,12 +104,12 @@ static Bit32u calcBasePitch(const Partial *partial, const TimbreParam::PartialPa
 
 	// MT-32 GEN0 does 16-bit calculations here, allowing an integer overflow.
 	// This quirk is observable playing the patch defined for timbre "HIT BOTTOM" in Larry 3.
+	// Note, the upper bound isn't checked either.
 	if (controlROMFeatures->quirkBasePitchOverflow) {
 		basePitch = basePitch & 0xffff;
 	} else if (basePitch < 0) {
 		basePitch = 0;
-	}
-	if (basePitch > 59392) {
+	} else if (basePitch > 59392) {
 		basePitch = 59392;
 	}
 	return Bit32u(basePitch);
@@ -151,6 +151,7 @@ void TVP::reset(const Part *usePart, const TimbreParam::PartialParam *usePartial
 
 	// FIXME: We're using a per-TVP timer instead of a system-wide one for convenience.
 	timeElapsed = 0;
+	processTimerIncrement = 0;
 
 	basePitch = calcBasePitch(partial, partialParam, patchTemp, key, partial->getSynth()->controlROMFeatures);
 	currentPitchOffset = calcTargetPitchOffsetWithoutLFO(partialParam, 0, velocity);
@@ -194,6 +195,7 @@ void TVP::updatePitch() {
 	} else if (newPitch < 0) {
 		newPitch = 0;
 	}
+	// This check is present in every unit.
 	if (newPitch > 59392) {
 		newPitch = 59392;
 	}
diff --git a/audio/softsynth/mt32/TVP.h b/audio/softsynth/mt32/TVP.h
index 896e8c11ab..c3dc314b4a 100644
--- a/audio/softsynth/mt32/TVP.h
+++ b/audio/softsynth/mt32/TVP.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/Tables.cpp b/audio/softsynth/mt32/Tables.cpp
index f12caa6b61..7fee467e84 100644
--- a/audio/softsynth/mt32/Tables.cpp
+++ b/audio/softsynth/mt32/Tables.cpp
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/Tables.h b/audio/softsynth/mt32/Tables.h
index 47465097e2..790ee17b9a 100644
--- a/audio/softsynth/mt32/Tables.h
+++ b/audio/softsynth/mt32/Tables.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/Types.h b/audio/softsynth/mt32/Types.h
index f70e4795cd..17c33e5684 100644
--- a/audio/softsynth/mt32/Types.h
+++ b/audio/softsynth/mt32/Types.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/c_interface/c_interface.cpp b/audio/softsynth/mt32/c_interface/c_interface.cpp
index adb1cb6b26..48eb2824ae 100644
--- a/audio/softsynth/mt32/c_interface/c_interface.cpp
+++ b/audio/softsynth/mt32/c_interface/c_interface.cpp
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
@@ -41,7 +41,7 @@ static mt32emu_service_version getSynthVersionID(mt32emu_service_i) {
 	return MT32EMU_SERVICE_VERSION_CURRENT;
 }
 
-static const mt32emu_service_i_v2 SERVICE_VTABLE = {
+static const mt32emu_service_i_v3 SERVICE_VTABLE = {
 	getSynthVersionID,
 	mt32emu_get_supported_report_handler_version,
 	mt32emu_get_supported_midi_receiver_version,
@@ -112,7 +112,13 @@ static const mt32emu_service_i_v2 SERVICE_VTABLE = {
 	mt32emu_convert_synth_to_output_timestamp,
 	mt32emu_get_internal_rendered_sample_count,
 	mt32emu_set_nice_amp_ramp_enabled,
-	mt32emu_is_nice_amp_ramp_enabled
+	mt32emu_is_nice_amp_ramp_enabled,
+	mt32emu_set_nice_panning_enabled,
+	mt32emu_is_nice_panning_enabled,
+	mt32emu_set_nice_partial_mixing_enabled,
+	mt32emu_is_nice_partial_mixing_enabled,
+	mt32emu_preallocate_reverb_memory,
+	mt32emu_configure_midi_event_queue_sysex_storage
 };
 
 } // namespace MT32Emu
@@ -323,7 +329,7 @@ extern "C" {
 
 mt32emu_service_i mt32emu_get_service_i() {
 	mt32emu_service_i i;
-	i.v2 = &SERVICE_VTABLE;
+	i.v3 = &SERVICE_VTABLE;
 	return i;
 }
 
@@ -517,6 +523,10 @@ mt32emu_bit32u mt32emu_set_midi_event_queue_size(mt32emu_const_context context,
 	return context->synth->setMIDIEventQueueSize(queue_size);
 }
 
+void mt32emu_configure_midi_event_queue_sysex_storage(mt32emu_const_context context, const mt32emu_bit32u storage_buffer_size) {
+	return context->synth->configureMIDIEventQueueSysexStorage(storage_buffer_size);
+}
+
 void mt32emu_set_midi_receiver(mt32emu_context context, mt32emu_midi_receiver_i midi_receiver, void *instance_data) {
 	delete context->midiParser;
 	context->midiParser = (midi_receiver.v0 != NULL) ? new DelegatingMidiStreamParser(context, midi_receiver, instance_data) : new DefaultMidiStreamParser(*context->synth);
@@ -610,6 +620,10 @@ mt32emu_boolean mt32emu_is_default_reverb_mt32_compatible(mt32emu_const_context
 	return context->synth->isDefaultReverbMT32Compatible() ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE;
 }
 
+void mt32emu_preallocate_reverb_memory(mt32emu_const_context context, const mt32emu_boolean enabled) {
+	return context->synth->preallocateReverbMemory(enabled != MT32EMU_BOOL_FALSE);
+}
+
 void mt32emu_set_dac_input_mode(mt32emu_const_context context, const mt32emu_dac_input_mode mode) {
 	context->synth->setDACInputMode(static_cast<DACInputMode>(mode));
 }
@@ -658,6 +672,22 @@ mt32emu_boolean mt32emu_is_nice_amp_ramp_enabled(mt32emu_const_context context)
 	return context->synth->isNiceAmpRampEnabled() ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE;
 }
 
+MT32EMU_EXPORT void mt32emu_set_nice_panning_enabled(mt32emu_const_context context, const mt32emu_boolean enabled) {
+	context->synth->setNicePanningEnabled(enabled != MT32EMU_BOOL_FALSE);
+}
+
+MT32EMU_EXPORT mt32emu_boolean mt32emu_is_nice_panning_enabled(mt32emu_const_context context) {
+	return context->synth->isNicePanningEnabled() ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE;
+}
+
+MT32EMU_EXPORT void mt32emu_set_nice_partial_mixing_enabled(mt32emu_const_context context, const mt32emu_boolean enabled) {
+	context->synth->setNicePartialMixingEnabled(enabled != MT32EMU_BOOL_FALSE);
+}
+
+MT32EMU_EXPORT mt32emu_boolean mt32emu_is_nice_partial_mixing_enabled(mt32emu_const_context context) {
+	return context->synth->isNicePartialMixingEnabled() ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE;
+}
+
 void mt32emu_render_bit16s(mt32emu_const_context context, mt32emu_bit16s *stream, mt32emu_bit32u len) {
 	if (context->srcState->src != NULL) {
 		context->srcState->src->getOutputSamples(stream, len);
diff --git a/audio/softsynth/mt32/c_interface/c_interface.h b/audio/softsynth/mt32/c_interface/c_interface.h
index f736400370..0924dcce53 100644
--- a/audio/softsynth/mt32/c_interface/c_interface.h
+++ b/audio/softsynth/mt32/c_interface/c_interface.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
@@ -201,6 +201,19 @@ MT32EMU_EXPORT void mt32emu_flush_midi_queue(mt32emu_const_context context);
  */
 MT32EMU_EXPORT mt32emu_bit32u mt32emu_set_midi_event_queue_size(mt32emu_const_context context, const mt32emu_bit32u queue_size);
 
+/**
+ * Configures the SysEx storage of the internal MIDI event queue.
+ * Supplying 0 in the storage_buffer_size argument makes the SysEx data stored
+ * in multiple dynamically allocated buffers per MIDI event. These buffers are only disposed
+ * when a new MIDI event replaces the SysEx event in the queue, thus never on the rendering thread.
+ * This is the default behaviour.
+ * In contrast, when a positive value is specified, SysEx data will be stored in a single preallocated buffer,
+ * which makes this kind of storage safe for use in a realtime thread. Additionally, the space retained
+ * by a SysEx event, that has been processed and thus is no longer necessary, is disposed instantly.
+ * Note, the queue is flushed and recreated in the process so that its size remains intact.
+ */
+void mt32emu_configure_midi_event_queue_sysex_storage(mt32emu_const_context context, const mt32emu_bit32u storage_buffer_size);
+
 /**
  * Installs custom MIDI receiver object intended for receiving MIDI messages generated by MIDI stream parser.
  * MIDI stream parser is involved when functions mt32emu_parse_stream() and mt32emu_play_short_message() or the likes are called.
@@ -316,6 +329,13 @@ MT32EMU_EXPORT mt32emu_boolean mt32emu_is_mt32_reverb_compatibility_mode(mt32emu
 /** Returns whether default reverb compatibility mode is the old MT-32 compatibility mode. */
 MT32EMU_EXPORT mt32emu_boolean mt32emu_is_default_reverb_mt32_compatible(mt32emu_const_context context);
 
+/**
+ * If enabled, reverb buffers for all modes are keept around allocated all the time to avoid memory
+ * allocating/freeing in the rendering thread, which may be required for realtime operation.
+ * Otherwise, reverb buffers that are not in use are deleted to save memory (the default behaviour).
+ */
+MT32EMU_EXPORT void mt32emu_preallocate_reverb_memory(mt32emu_const_context context, const mt32emu_boolean enabled);
+
 /** Sets new DAC input mode. See mt32emu_dac_input_mode for details. */
 MT32EMU_EXPORT void mt32emu_set_dac_input_mode(mt32emu_const_context context, const mt32emu_dac_input_mode mode);
 /** Returns current DAC input mode. See mt32emu_dac_input_mode for details. */
@@ -366,6 +386,33 @@ MT32EMU_EXPORT void mt32emu_set_nice_amp_ramp_enabled(mt32emu_const_context cont
 /** Returns whether NiceAmpRamp mode is enabled. */
 MT32EMU_EXPORT mt32emu_boolean mt32emu_is_nice_amp_ramp_enabled(mt32emu_const_context context);
 
+/**
+ * Allows to toggle the NicePanning mode.
+ * Despite the Roland's manual specifies allowed panpot values in range 0-14,
+ * the LA-32 only receives 3-bit pan setting in fact. In particular, this
+ * makes it impossible to set the "middle" panning for a single partial.
+ * In the NicePanning mode, we enlarge the pan setting accuracy to 4 bits
+ * making it smoother thus sacrificing the emulation accuracy.
+ * This mode is disabled by default.
+ */
+MT32EMU_EXPORT void mt32emu_set_nice_panning_enabled(mt32emu_const_context context, const mt32emu_boolean enabled);
+/** Returns whether NicePanning mode is enabled. */
+MT32EMU_EXPORT mt32emu_boolean mt32emu_is_nice_panning_enabled(mt32emu_const_context context);
+
+/**
+ * Allows to toggle the NicePartialMixing mode.
+ * LA-32 is known to mix partials either in-phase (so that they are added)
+ * or in counter-phase (so that they are subtracted instead).
+ * In some cases, this quirk isn't highly desired because a pair of closely
+ * sounding partials may occasionally cancel out.
+ * In the NicePartialMixing mode, the mixing is always performed in-phase,
+ * thus making the behaviour more predictable.
+ * This mode is disabled by default.
+ */
+MT32EMU_EXPORT void mt32emu_set_nice_partial_mixing_enabled(mt32emu_const_context context, const mt32emu_boolean enabled);
+/** Returns whether NicePartialMixing mode is enabled. */
+MT32EMU_EXPORT mt32emu_boolean mt32emu_is_nice_partial_mixing_enabled(mt32emu_const_context context);
+
 /**
  * Renders samples to the specified output stream as if they were sampled at the analog stereo output at the desired sample rate.
  * If the output sample rate is not specified explicitly, the default output sample rate is used which depends on the current
diff --git a/audio/softsynth/mt32/c_interface/c_types.h b/audio/softsynth/mt32/c_interface/c_types.h
index dada610bd4..74bae8df48 100644
--- a/audio/softsynth/mt32/c_interface/c_types.h
+++ b/audio/softsynth/mt32/c_interface/c_types.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
@@ -121,7 +121,8 @@ typedef enum {
 	MT32EMU_SERVICE_VERSION_0 = 0,
 	MT32EMU_SERVICE_VERSION_1 = 1,
 	MT32EMU_SERVICE_VERSION_2 = 2,
-	MT32EMU_SERVICE_VERSION_CURRENT = MT32EMU_SERVICE_VERSION_2
+	MT32EMU_SERVICE_VERSION_3 = 3,
+	MT32EMU_SERVICE_VERSION_CURRENT = MT32EMU_SERVICE_VERSION_3
 } mt32emu_service_version;
 
 /* === Report Handler Interface === */
@@ -303,6 +304,14 @@ typedef union mt32emu_service_i mt32emu_service_i;
 	void (*setNiceAmpRampEnabled)(mt32emu_const_context context, const mt32emu_boolean enabled); \
 	mt32emu_boolean (*isNiceAmpRampEnabled)(mt32emu_const_context context);
 
+#define MT32EMU_SERVICE_I_V3 \
+	void (*setNicePanningEnabled)(mt32emu_const_context context, const mt32emu_boolean enabled); \
+	mt32emu_boolean (*isNicePanningEnabled)(mt32emu_const_context context); \
+	void (*setNicePartialMixingEnabled)(mt32emu_const_context context, const mt32emu_boolean enabled); \
+	mt32emu_boolean (*isNicePartialMixingEnabled)(mt32emu_const_context context); \
+	void (*preallocateReverbMemory)(mt32emu_const_context context, const mt32emu_boolean enabled); \
+	void (*configureMIDIEventQueueSysexStorage)(mt32emu_const_context context, const mt32emu_bit32u storage_buffer_size);
+
 typedef struct {
 	MT32EMU_SERVICE_I_V0
 } mt32emu_service_i_v0;
@@ -318,6 +327,13 @@ typedef struct {
 	MT32EMU_SERVICE_I_V2
 } mt32emu_service_i_v2;
 
+typedef struct {
+	MT32EMU_SERVICE_I_V0
+	MT32EMU_SERVICE_I_V1
+	MT32EMU_SERVICE_I_V2
+	MT32EMU_SERVICE_I_V3
+} mt32emu_service_i_v3;
+
 /**
  * Extensible interface for all the library services.
  * Union intended to view an interface of any subsequent version as any parent interface not requiring a cast.
@@ -327,10 +343,12 @@ union mt32emu_service_i {
 	const mt32emu_service_i_v0 *v0;
 	const mt32emu_service_i_v1 *v1;
 	const mt32emu_service_i_v2 *v2;
+	const mt32emu_service_i_v3 *v3;
 };
 
 #undef MT32EMU_SERVICE_I_V0
 #undef MT32EMU_SERVICE_I_V1
 #undef MT32EMU_SERVICE_I_V2
+#undef MT32EMU_SERVICE_I_V3
 
 #endif /* #ifndef MT32EMU_C_TYPES_H */
diff --git a/audio/softsynth/mt32/c_interface/cpp_interface.h b/audio/softsynth/mt32/c_interface/cpp_interface.h
index 3b02c03258..82fa44b2e3 100644
--- a/audio/softsynth/mt32/c_interface/cpp_interface.h
+++ b/audio/softsynth/mt32/c_interface/cpp_interface.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
@@ -60,6 +60,7 @@ mt32emu_service_i mt32emu_get_service_i();
 #define mt32emu_convert_synth_to_output_timestamp iV1()->convertSynthToOutputTimestamp
 #define mt32emu_flush_midi_queue i.v0->flushMIDIQueue
 #define mt32emu_set_midi_event_queue_size i.v0->setMIDIEventQueueSize
+#define mt32emu_configure_midi_event_queue_sysex_storage iV3()->configureMIDIEventQueueSysexStorage
 #define mt32emu_set_midi_receiver i.v0->setMIDIReceiver
 #define mt32emu_get_internal_rendered_sample_count iV2()->getInternalRenderedSampleCount
 #define mt32emu_parse_stream i.v0->parseStream
@@ -81,6 +82,7 @@ mt32emu_service_i mt32emu_get_service_i();
 #define mt32emu_set_reverb_compatibility_mode i.v0->setReverbCompatibilityMode
 #define mt32emu_is_mt32_reverb_compatibility_mode i.v0->isMT32ReverbCompatibilityMode
 #define mt32emu_is_default_reverb_mt32_compatible i.v0->isDefaultReverbMT32Compatible
+#define mt32emu_preallocate_reverb_memory iV3()->preallocateReverbMemory
 #define mt32emu_set_dac_input_mode i.v0->setDACInputMode
 #define mt32emu_get_dac_input_mode i.v0->getDACInputMode
 #define mt32emu_set_midi_delay_mode i.v0->setMIDIDelayMode
@@ -93,6 +95,10 @@ mt32emu_service_i mt32emu_get_service_i();
 #define mt32emu_is_reversed_stereo_enabled i.v0->isReversedStereoEnabled
 #define mt32emu_set_nice_amp_ramp_enabled iV2()->setNiceAmpRampEnabled
 #define mt32emu_is_nice_amp_ramp_enabled iV2()->isNiceAmpRampEnabled
+#define mt32emu_set_nice_panning_enabled iV3()->setNicePanningEnabled
+#define mt32emu_is_nice_panning_enabled iV3()->isNicePanningEnabled
+#define mt32emu_set_nice_partial_mixing_enabled iV3()->setNicePartialMixingEnabled
+#define mt32emu_is_nice_partial_mixing_enabled iV3()->isNicePartialMixingEnabled
 #define mt32emu_render_bit16s i.v0->renderBit16s
 #define mt32emu_render_float i.v0->renderFloat
 #define mt32emu_render_bit16s_streams i.v0->renderBit16sStreams
@@ -213,6 +219,7 @@ public:
 	Bit32u convertSynthToOutputTimestamp(Bit32u synth_timestamp) { return mt32emu_convert_synth_to_output_timestamp(c, synth_timestamp); }
 	void flushMIDIQueue() { mt32emu_flush_midi_queue(c); }
 	Bit32u setMIDIEventQueueSize(const Bit32u queue_size) { return mt32emu_set_midi_event_queue_size(c, queue_size); }
+	void configureMIDIEventQueueSysexStorage(const Bit32u storage_buffer_size) { mt32emu_configure_midi_event_queue_sysex_storage(c, storage_buffer_size); }
 	void setMIDIReceiver(mt32emu_midi_receiver_i midi_receiver, void *instance_data) { mt32emu_set_midi_receiver(c, midi_receiver, instance_data); }
 	void setMIDIReceiver(IMidiReceiver &midi_receiver) { setMIDIReceiver(CppInterfaceImpl::getMidiReceiverThunk(), &midi_receiver); }
 
@@ -238,6 +245,7 @@ public:
 	void setReverbCompatibilityMode(const bool mt32_compatible_mode) { mt32emu_set_reverb_compatibility_mode(c, mt32_compatible_mode ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE); }
 	bool isMT32ReverbCompatibilityMode() { return mt32emu_is_mt32_reverb_compatibility_mode(c) != MT32EMU_BOOL_FALSE; }
 	bool isDefaultReverbMT32Compatible() { return mt32emu_is_default_reverb_mt32_compatible(c) != MT32EMU_BOOL_FALSE; }
+	void preallocateReverbMemory(const bool enabled) { mt32emu_preallocate_reverb_memory(c, enabled ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE); }
 
 	void setDACInputMode(const DACInputMode mode) { mt32emu_set_dac_input_mode(c, static_cast<mt32emu_dac_input_mode>(mode)); }
 	DACInputMode getDACInputMode() { return static_cast<DACInputMode>(mt32emu_get_dac_input_mode(c)); }
@@ -256,6 +264,12 @@ public:
 	void setNiceAmpRampEnabled(const bool enabled) { mt32emu_set_nice_amp_ramp_enabled(c, enabled ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE); }
 	bool isNiceAmpRampEnabled() { return mt32emu_is_nice_amp_ramp_enabled(c) != MT32EMU_BOOL_FALSE; }
 
+	void setNicePanningEnabled(const bool enabled) { mt32emu_set_nice_panning_enabled(c, enabled ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE); }
+	bool isNicePanningEnabled() { return mt32emu_is_nice_panning_enabled(c) != MT32EMU_BOOL_FALSE; }
+
+	void setNicePartialMixingEnabled(const bool enabled) { mt32emu_set_nice_partial_mixing_enabled(c, enabled ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE); }
+	bool isNicePartialMixingEnabled() { return mt32emu_is_nice_partial_mixing_enabled(c) != MT32EMU_BOOL_FALSE; }
+
 	void renderBit16s(Bit16s *stream, Bit32u len) { mt32emu_render_bit16s(c, stream, len); }
 	void renderFloat(float *stream, Bit32u len) { mt32emu_render_float(c, stream, len); }
 	void renderBit16sStreams(const mt32emu_dac_output_bit16s_streams *streams, Bit32u len) { mt32emu_render_bit16s_streams(c, streams, len); }
@@ -279,6 +293,7 @@ private:
 #if MT32EMU_API_TYPE == 2
 	const mt32emu_service_i_v1 *iV1() { return (getVersionID() < MT32EMU_SERVICE_VERSION_1) ? NULL : i.v1; }
 	const mt32emu_service_i_v2 *iV2() { return (getVersionID() < MT32EMU_SERVICE_VERSION_2) ? NULL : i.v2; }
+	const mt32emu_service_i_v3 *iV3() { return (getVersionID() < MT32EMU_SERVICE_VERSION_3) ? NULL : i.v3; }
 #endif
 };
 
@@ -428,6 +443,7 @@ static mt32emu_midi_receiver_i getMidiReceiverThunk() {
 #undef mt32emu_convert_synth_to_output_timestamp
 #undef mt32emu_flush_midi_queue
 #undef mt32emu_set_midi_event_queue_size
+#undef mt32emu_configure_midi_event_queue_sysex_storage
 #undef mt32emu_set_midi_receiver
 #undef mt32emu_get_internal_rendered_sample_count
 #undef mt32emu_parse_stream
@@ -449,6 +465,7 @@ static mt32emu_midi_receiver_i getMidiReceiverThunk() {
 #undef mt32emu_set_reverb_compatibility_mode
 #undef mt32emu_is_mt32_reverb_compatibility_mode
 #undef mt32emu_is_default_reverb_mt32_compatible
+#undef mt32emu_preallocate_reverb_memory
 #undef mt32emu_set_dac_input_mode
 #undef mt32emu_get_dac_input_mode
 #undef mt32emu_set_midi_delay_mode
@@ -461,6 +478,10 @@ static mt32emu_midi_receiver_i getMidiReceiverThunk() {
 #undef mt32emu_is_reversed_stereo_enabled
 #undef mt32emu_set_nice_amp_ramp_enabled
 #undef mt32emu_is_nice_amp_ramp_enabled
+#undef mt32emu_set_nice_panning_enabled
+#undef mt32emu_is_nice_panning_enabled
+#undef mt32emu_set_nice_partial_mixing_enabled
+#undef mt32emu_is_nice_partial_mixing_enabled
 #undef mt32emu_render_bit16s
 #undef mt32emu_render_float
 #undef mt32emu_render_bit16s_streams
diff --git a/audio/softsynth/mt32/config.h b/audio/softsynth/mt32/config.h
index 5ad650c08b..51e4098868 100644
--- a/audio/softsynth/mt32/config.h
+++ b/audio/softsynth/mt32/config.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
@@ -18,9 +18,9 @@
 #ifndef MT32EMU_CONFIG_H
 #define MT32EMU_CONFIG_H
 
-#define MT32EMU_VERSION      "2.3.0"
+#define MT32EMU_VERSION      "2.4.0"
 #define MT32EMU_VERSION_MAJOR 2
-#define MT32EMU_VERSION_MINOR 3
+#define MT32EMU_VERSION_MINOR 4
 #define MT32EMU_VERSION_PATCH 0
 
 /* Library Exports Configuration
diff --git a/audio/softsynth/mt32/globals.h b/audio/softsynth/mt32/globals.h
index 2d984c82b6..243ff82ae0 100644
--- a/audio/softsynth/mt32/globals.h
+++ b/audio/softsynth/mt32/globals.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/internals.h b/audio/softsynth/mt32/internals.h
index 0bae8d9f7b..8a609546cd 100644
--- a/audio/softsynth/mt32/internals.h
+++ b/audio/softsynth/mt32/internals.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
@@ -81,12 +81,6 @@
 
 // Configuration
 
-// If non-zero, deletes reverb buffers that are not in use to save memory.
-// If zero, keeps reverb buffers for all modes around all the time to avoid allocating/freeing in the critical path.
-#ifndef MT32EMU_REDUCE_REVERB_MEMORY
-#define MT32EMU_REDUCE_REVERB_MEMORY 1
-#endif
-
 // 0: Maximum speed at the cost of a bit lower emulation accuracy.
 // 1: Maximum achievable emulation accuracy.
 #ifndef MT32EMU_BOSS_REVERB_PRECISE_MODE
diff --git a/audio/softsynth/mt32/mmath.h b/audio/softsynth/mt32/mmath.h
index 9a9e642ba1..a66fad5664 100644
--- a/audio/softsynth/mt32/mmath.h
+++ b/audio/softsynth/mt32/mmath.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/mt32emu.h b/audio/softsynth/mt32/mt32emu.h
index 6b93121bee..cfb50fb288 100644
--- a/audio/softsynth/mt32/mt32emu.h
+++ b/audio/softsynth/mt32/mt32emu.h
@@ -1,5 +1,5 @@
 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
+ * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/srchelper/InternalResampler.cpp b/audio/softsynth/mt32/srchelper/InternalResampler.cpp
index 320408459c..56bd1ac05a 100644
--- a/audio/softsynth/mt32/srchelper/InternalResampler.cpp
+++ b/audio/softsynth/mt32/srchelper/InternalResampler.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2017 Sergey V. Mikayev
+/* Copyright (C) 2015-2020 Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/srchelper/InternalResampler.h b/audio/softsynth/mt32/srchelper/InternalResampler.h
index be54077597..cf08c82612 100644
--- a/audio/softsynth/mt32/srchelper/InternalResampler.h
+++ b/audio/softsynth/mt32/srchelper/InternalResampler.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2017 Sergey V. Mikayev
+/* Copyright (C) 2015-2020 Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/srchelper/SamplerateAdapter.cpp b/audio/softsynth/mt32/srchelper/SamplerateAdapter.cpp
index 715d298720..2a417ed2e9 100644
--- a/audio/softsynth/mt32/srchelper/SamplerateAdapter.cpp
+++ b/audio/softsynth/mt32/srchelper/SamplerateAdapter.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2017 Sergey V. Mikayev
+/* Copyright (C) 2015-2020 Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/srchelper/SamplerateAdapter.h b/audio/softsynth/mt32/srchelper/SamplerateAdapter.h
index 0991fd7713..eed9799a9b 100644
--- a/audio/softsynth/mt32/srchelper/SamplerateAdapter.h
+++ b/audio/softsynth/mt32/srchelper/SamplerateAdapter.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2017 Sergey V. Mikayev
+/* Copyright (C) 2015-2020 Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/srchelper/SoxrAdapter.cpp b/audio/softsynth/mt32/srchelper/SoxrAdapter.cpp
index 5e8dca97d6..a88c133ecd 100644
--- a/audio/softsynth/mt32/srchelper/SoxrAdapter.cpp
+++ b/audio/softsynth/mt32/srchelper/SoxrAdapter.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2017 Sergey V. Mikayev
+/* Copyright (C) 2015-2020 Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/srchelper/SoxrAdapter.h b/audio/softsynth/mt32/srchelper/SoxrAdapter.h
index b97ca4da51..c6b9d3ade2 100644
--- a/audio/softsynth/mt32/srchelper/SoxrAdapter.h
+++ b/audio/softsynth/mt32/srchelper/SoxrAdapter.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2017 Sergey V. Mikayev
+/* Copyright (C) 2015-2020 Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/srchelper/srctools/include/FIRResampler.h b/audio/softsynth/mt32/srchelper/srctools/include/FIRResampler.h
index 7c09bf8ded..9032131dc0 100644
--- a/audio/softsynth/mt32/srchelper/srctools/include/FIRResampler.h
+++ b/audio/softsynth/mt32/srchelper/srctools/include/FIRResampler.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2017 Sergey V. Mikayev
+/* Copyright (C) 2015-2020 Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/srchelper/srctools/include/FloatSampleProvider.h b/audio/softsynth/mt32/srchelper/srctools/include/FloatSampleProvider.h
index 9820769f7f..4056db373c 100644
--- a/audio/softsynth/mt32/srchelper/srctools/include/FloatSampleProvider.h
+++ b/audio/softsynth/mt32/srchelper/srctools/include/FloatSampleProvider.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2017 Sergey V. Mikayev
+/* Copyright (C) 2015-2020 Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/srchelper/srctools/include/IIR2xResampler.h b/audio/softsynth/mt32/srchelper/srctools/include/IIR2xResampler.h
index 0bfe1c4c8b..ea150f9db1 100644
--- a/audio/softsynth/mt32/srchelper/srctools/include/IIR2xResampler.h
+++ b/audio/softsynth/mt32/srchelper/srctools/include/IIR2xResampler.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2017 Sergey V. Mikayev
+/* Copyright (C) 2015-2020 Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/srchelper/srctools/include/LinearResampler.h b/audio/softsynth/mt32/srchelper/srctools/include/LinearResampler.h
index c81ff2a385..0e30ea2e91 100644
--- a/audio/softsynth/mt32/srchelper/srctools/include/LinearResampler.h
+++ b/audio/softsynth/mt32/srchelper/srctools/include/LinearResampler.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2017 Sergey V. Mikayev
+/* Copyright (C) 2015-2020 Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/srchelper/srctools/include/ResamplerModel.h b/audio/softsynth/mt32/srchelper/srctools/include/ResamplerModel.h
index f0ac237071..b7a64f02ea 100644
--- a/audio/softsynth/mt32/srchelper/srctools/include/ResamplerModel.h
+++ b/audio/softsynth/mt32/srchelper/srctools/include/ResamplerModel.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2017 Sergey V. Mikayev
+/* Copyright (C) 2015-2020 Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/srchelper/srctools/include/ResamplerStage.h b/audio/softsynth/mt32/srchelper/srctools/include/ResamplerStage.h
index e335c0c380..edd7678c1d 100644
--- a/audio/softsynth/mt32/srchelper/srctools/include/ResamplerStage.h
+++ b/audio/softsynth/mt32/srchelper/srctools/include/ResamplerStage.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2017 Sergey V. Mikayev
+/* Copyright (C) 2015-2020 Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/srchelper/srctools/include/SincResampler.h b/audio/softsynth/mt32/srchelper/srctools/include/SincResampler.h
index 1551a1eda8..bac8440437 100644
--- a/audio/softsynth/mt32/srchelper/srctools/include/SincResampler.h
+++ b/audio/softsynth/mt32/srchelper/srctools/include/SincResampler.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2017 Sergey V. Mikayev
+/* Copyright (C) 2015-2020 Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/srchelper/srctools/src/FIRResampler.cpp b/audio/softsynth/mt32/srchelper/srctools/src/FIRResampler.cpp
index 15d95c5fc6..b5ab5585c4 100644
--- a/audio/softsynth/mt32/srchelper/srctools/src/FIRResampler.cpp
+++ b/audio/softsynth/mt32/srchelper/srctools/src/FIRResampler.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2017 Sergey V. Mikayev
+/* Copyright (C) 2015-2020 Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/srchelper/srctools/src/IIR2xResampler.cpp b/audio/softsynth/mt32/srchelper/srctools/src/IIR2xResampler.cpp
index 1adc593593..98f7a3a5b4 100644
--- a/audio/softsynth/mt32/srchelper/srctools/src/IIR2xResampler.cpp
+++ b/audio/softsynth/mt32/srchelper/srctools/src/IIR2xResampler.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2017 Sergey V. Mikayev
+/* Copyright (C) 2015-2020 Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/srchelper/srctools/src/LinearResampler.cpp b/audio/softsynth/mt32/srchelper/srctools/src/LinearResampler.cpp
index e7b60c62a8..1ca143a386 100644
--- a/audio/softsynth/mt32/srchelper/srctools/src/LinearResampler.cpp
+++ b/audio/softsynth/mt32/srchelper/srctools/src/LinearResampler.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2017 Sergey V. Mikayev
+/* Copyright (C) 2015-2020 Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/srchelper/srctools/src/ResamplerModel.cpp b/audio/softsynth/mt32/srchelper/srctools/src/ResamplerModel.cpp
index 44b969cbd1..2a7f75822a 100644
--- a/audio/softsynth/mt32/srchelper/srctools/src/ResamplerModel.cpp
+++ b/audio/softsynth/mt32/srchelper/srctools/src/ResamplerModel.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2017 Sergey V. Mikayev
+/* Copyright (C) 2015-2020 Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
diff --git a/audio/softsynth/mt32/srchelper/srctools/src/SincResampler.cpp b/audio/softsynth/mt32/srchelper/srctools/src/SincResampler.cpp
index fff2703746..60a18256ca 100644
--- a/audio/softsynth/mt32/srchelper/srctools/src/SincResampler.cpp
+++ b/audio/softsynth/mt32/srchelper/srctools/src/SincResampler.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2017 Sergey V. Mikayev
+/* Copyright (C) 2015-2020 Sergey V. Mikayev
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by


Commit: d831c5984ed7a6db3ac680ccbea71fba0ecabeee
    https://github.com/scummvm/scummvm/commit/d831c5984ed7a6db3ac680ccbea71fba0ecabeee
Author: Lothar Serra Mari (mail at serra.me)
Date: 2020-06-07T00:55:45+02:00

Commit Message:
MT32: Fix MSVC warning

see 369ba0c4b7f1278c415f7c7655cfa6cc5ae2b5fb for reference.

Changed paths:
    audio/softsynth/mt32/FileStream.cpp


diff --git a/audio/softsynth/mt32/FileStream.cpp b/audio/softsynth/mt32/FileStream.cpp
index 3fa1a31074..c42d90d5be 100644
--- a/audio/softsynth/mt32/FileStream.cpp
+++ b/audio/softsynth/mt32/FileStream.cpp
@@ -21,6 +21,11 @@
 
 #include "internals.h"
 
+// Disable MSVC STL exceptions
+#ifdef _MSC_VER
+#define _HAS_EXCEPTIONS 0
+#endif
+
 #include "FileStream.h"
 
 namespace MT32Emu {


Commit: b0b0e573fb4f82ebfc740d95565c2822682c2248
    https://github.com/scummvm/scummvm/commit/b0b0e573fb4f82ebfc740d95565c2822682c2248
Author: Lothar Serra Mari (mail at serra.me)
Date: 2020-06-07T00:55:45+02:00

Commit Message:
MT32: Add missing default switch cases

See 4d911012e26eb9fc2098d586b0c2108667d3c2af for reference.

Changed paths:
    audio/softsynth/mt32/Analog.cpp
    audio/softsynth/mt32/BReverbModel.cpp
    audio/softsynth/mt32/Synth.cpp


diff --git a/audio/softsynth/mt32/Analog.cpp b/audio/softsynth/mt32/Analog.cpp
index b14d824dda..1f3e2e079b 100644
--- a/audio/softsynth/mt32/Analog.cpp
+++ b/audio/softsynth/mt32/Analog.cpp
@@ -273,6 +273,8 @@ Analog *Analog::createAnalog(const AnalogOutputMode mode, const bool oldMT32Anal
 		return new AnalogImpl<IntSampleEx>(mode, oldMT32AnalogLPF);
 	case RendererType_FLOAT:
 		return new AnalogImpl<FloatSample>(mode, oldMT32AnalogLPF);
+	default:
+		break;
 	}
 	return NULL;
 }
diff --git a/audio/softsynth/mt32/BReverbModel.cpp b/audio/softsynth/mt32/BReverbModel.cpp
index 1eb6f7e568..7507cfc9a1 100644
--- a/audio/softsynth/mt32/BReverbModel.cpp
+++ b/audio/softsynth/mt32/BReverbModel.cpp
@@ -633,6 +633,8 @@ BReverbModel *BReverbModel::createBReverbModel(const ReverbMode mode, const bool
 		return new BReverbModelImpl<IntSample>(mode, mt32CompatibleModel);
 	case RendererType_FLOAT:
 		return new BReverbModelImpl<FloatSample>(mode, mt32CompatibleModel);
+	default:
+		break;
 	}
 	return NULL;
 }
diff --git a/audio/softsynth/mt32/Synth.cpp b/audio/softsynth/mt32/Synth.cpp
index d61ad44a6c..bd7510471b 100644
--- a/audio/softsynth/mt32/Synth.cpp
+++ b/audio/softsynth/mt32/Synth.cpp
@@ -1674,6 +1674,8 @@ void Synth::writeMemoryRegion(const MemoryRegion *region, Bit32u addr, Bit32u le
 	case MR_Reset:
 		reset();
 		break;
+	default:
+		break;
 	}
 }
 




More information about the Scummvm-git-logs mailing list