Initial commit
This commit is contained in:
591
audio/mt32gm.h
Normal file
591
audio/mt32gm.h
Normal file
@@ -0,0 +1,591 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef AUDIO_MT32GM_H
|
||||
#define AUDIO_MT32GM_H
|
||||
|
||||
#include "audio/mididrv.h"
|
||||
#include "audio/mididrv_ms.h"
|
||||
#include "common/list.h"
|
||||
#include "common/mutex.h"
|
||||
|
||||
/**
|
||||
* @defgroup audio_mt32_gm MIDI driver for MT-32 and GM
|
||||
* @ingroup audio
|
||||
*
|
||||
* @brief MIDI driver for MT-32 and GM compatible emulators and devices.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* MIDI driver for MT-32 and GM compatible emulators and devices.
|
||||
*
|
||||
* This class contains some commonly needed functionality for these devices and
|
||||
* the MIDI data that targets them. It wraps the MidiDriver instance that does
|
||||
* the actual communication with the MT-32 or GM device.
|
||||
*
|
||||
* This driver has the following features:
|
||||
*
|
||||
* - MIDI device initialization
|
||||
* Construct the driver with the type of MIDI data that will be sent to it.
|
||||
* When the driver is opened, it will create an output MIDI driver appropriate
|
||||
* for the user configuration settings and the type of MIDI data. You can also
|
||||
* create the output MIDI driver yourself and pass it to the open function.
|
||||
* The driver will take care of initializing the MIDI device and setting up
|
||||
* for playback of MT-32 data on a GM/GS device or the other way around.
|
||||
*
|
||||
* - MT-32 <> GM conversion
|
||||
* If the incoming MIDI data has been set to MT-32 and the output device is
|
||||
* GM, the driver will map MT-32 instruments to GM equivalents. GM playback
|
||||
* on an MT-32 device is also supported. Set the _mt32ToGMInstrumentMap and
|
||||
* _gmToMT32InstrumentMap variables to override the standard instrument maps,
|
||||
* or override the mapMT32InstrumentToGM and mapGMInstrumentToMT32 functions
|
||||
* for more advanced mapping algorithms.
|
||||
*
|
||||
* - Reverse stereo
|
||||
* If the game has MIDI data with reversed stereo compared to the targeted
|
||||
* output device, set the MIDI_DATA_REVERSE_PANNING property to reverse
|
||||
* stereo. The driver wil automatically reverse stereo when MT-32 data is
|
||||
* sent to a GM/GS device or the other way around.
|
||||
*
|
||||
* - Correct Roland GS bank and drumkit selects
|
||||
* Some games' MIDI data relies on a feature of the Roland SC-55 MIDI module
|
||||
* which automatically corrects invalid bank selects and drumkit program
|
||||
* changes. The driver replicates this feature to ensure correct instrument
|
||||
* banks and drumkits on other hardware or softsynths.
|
||||
*
|
||||
* - SysEx queue
|
||||
* The sysExQueue function will queue a SysEx message and return immediately.
|
||||
* You can send more messages to the queue while the driver sends the
|
||||
* messages asynchronously with the necessary delays to the MIDI device. Use
|
||||
* the isReady function to check if the device has received all messages and
|
||||
* is ready to start playback. Use this instead of the sysEx function to
|
||||
* prevent the main game loop from being blocked while the driver waits the
|
||||
* necessary amount of time for the MIDI device to process the message.
|
||||
* Use clearSysExQueue to remove all messages from the queue, in case device
|
||||
* initialization has to be aborted.
|
||||
*
|
||||
* - Multiple MIDI sources
|
||||
* If the game plays multiple streams of MIDI data at the same time, each
|
||||
* stream can be marked with a source number. This enables the following
|
||||
* feature:
|
||||
* - Channel mapping
|
||||
* If multiple sources use the same MIDI channels, the driver can map the
|
||||
* data channels to different output channels to avoid conflicts. Use
|
||||
* allocateSourceChannels to allocate output channels to a source. The
|
||||
* data channels are automatically mapped to the allocated output channels
|
||||
* during playback. The allocated channels are freed when the source is
|
||||
* deinitialized.
|
||||
* If you only have one source of MIDI data or the sources do not use
|
||||
* conflicting channels, you do not need to allocate channels - the channels
|
||||
* in the MIDI data will be used directly. If you do use this feature, you
|
||||
* have to use it for all MIDI sources to avoid channel conflicts.
|
||||
* The standard channel allocation scheme will allocate the available output
|
||||
* channels with the lowest numbers and will fail if not enough channels are
|
||||
* available. You can override the allocateSourceChannels and
|
||||
* mapSourceChannel functions to customize the allocation and mapping
|
||||
* algorithms.
|
||||
* Note that you can also use the "standard" way of allocating channels
|
||||
* using the allocateChannel function and MidiChannel objects. These two
|
||||
* methods are not coordinated in any way, so don't use both at the same
|
||||
* time.
|
||||
*/
|
||||
class MidiDriver_MT32GM : public MidiDriver_Multisource {
|
||||
public:
|
||||
static const byte MT32_DEFAULT_INSTRUMENTS[8];
|
||||
static const int16 MT32_DEFAULT_INSTRUMENTS_CONTROLLER_DEFAULTS[16];
|
||||
static const byte MT32_DEFAULT_PANNING[8];
|
||||
static const uint8 MT32_DEFAULT_CHANNEL_VOLUME = 102;
|
||||
static const uint8 GM_DEFAULT_CHANNEL_VOLUME = 100;
|
||||
// Map for correcting Roland GS drumkit numbers.
|
||||
static const uint8 GS_DRUMKIT_FALLBACK_MAP[128];
|
||||
|
||||
static const uint8 MT32_DISPLAY_NUM_CHARS = 20;
|
||||
static const uint32 MT32_DISPLAY_MEMORY_ADDRESS = 0x20 << 14;
|
||||
|
||||
protected:
|
||||
static const uint8 MAXIMUM_MT32_ACTIVE_NOTES = 48;
|
||||
static const uint8 MAXIMUM_GM_ACTIVE_NOTES = 96;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* This stores the values of the MIDI controllers for
|
||||
* a MIDI channel. It is used to keep track of controller
|
||||
* values while a channel is locked, so they can be
|
||||
* restored when the channel is unlocked.
|
||||
*/
|
||||
struct MidiChannelControlData {
|
||||
// The source that last sent an event to this channel
|
||||
int8 source;
|
||||
// True if the source volume has been applied to this channel
|
||||
bool sourceVolumeApplied;
|
||||
|
||||
uint16 pitchWheel;
|
||||
byte program;
|
||||
// The Roland GS instrument bank
|
||||
byte instrumentBank;
|
||||
byte channelPressure;
|
||||
|
||||
byte modulation;
|
||||
// The volume specified by the MIDI data
|
||||
byte volume;
|
||||
// The volume set on the MIDI device. This is scaled using the source
|
||||
// volume and optionally the user-specified volume setting.
|
||||
byte scaledVolume;
|
||||
byte panPosition;
|
||||
byte expression;
|
||||
bool sustain;
|
||||
|
||||
// The currently selected Registered Parameter Number
|
||||
uint16 rpn;
|
||||
byte pitchBendSensitivity;
|
||||
|
||||
MidiChannelControlData() : source(-1),
|
||||
sourceVolumeApplied(false),
|
||||
pitchWheel(MIDI_PITCH_BEND_DEFAULT),
|
||||
program(0),
|
||||
instrumentBank(0),
|
||||
channelPressure(0),
|
||||
modulation(0),
|
||||
volume(0),
|
||||
scaledVolume(0),
|
||||
panPosition(MIDI_PANNING_DEFAULT),
|
||||
expression(MIDI_EXPRESSION_DEFAULT),
|
||||
sustain(false),
|
||||
rpn(MIDI_RPN_NULL),
|
||||
pitchBendSensitivity(0) { }
|
||||
};
|
||||
|
||||
/**
|
||||
* This stores data about a specific source of MIDI data.
|
||||
*/
|
||||
struct MidiSource {
|
||||
// Whether this source sends music or SFX MIDI data.
|
||||
SourceType type;
|
||||
// The source volume (relative volume for this source as defined by the game).
|
||||
// Default is the default neutral value (255).
|
||||
uint16 volume;
|
||||
// The source volume level at which no scaling is performed (volume as defined
|
||||
// in MIDI data is used directly). Volume values below this decrease volume,
|
||||
// values above increase volume (up to the maximum MIDI channel volume).
|
||||
// Set this to match the volume values used by the game engine to avoid having
|
||||
// to convert them. Default value is 255; minimum value is 1.
|
||||
uint16 neutralVolume;
|
||||
// The volume level at which the fade started.
|
||||
uint16 fadeStartVolume;
|
||||
// The target volume level for the fade.
|
||||
uint16 fadeEndVolume;
|
||||
// How much us has passed since the start of the fade.
|
||||
int32 fadePassedTime;
|
||||
// The total duration of the fade (us).
|
||||
int32 fadeDuration;
|
||||
// The mapping of MIDI data channels to output channels for this source.
|
||||
int8 channelMap[MIDI_CHANNEL_COUNT];
|
||||
// Bitmask specifying which MIDI channels are available for use by this source.
|
||||
uint16 availableChannels;
|
||||
|
||||
MidiSource() : type(SOURCE_TYPE_UNDEFINED), volume(DEFAULT_SOURCE_NEUTRAL_VOLUME),
|
||||
neutralVolume(DEFAULT_SOURCE_NEUTRAL_VOLUME), fadeStartVolume(0),
|
||||
fadeEndVolume(0), fadePassedTime(0), fadeDuration(0), availableChannels(0xFFFF) {
|
||||
memset(channelMap, 0, sizeof(channelMap));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This stores information about a note currently playing on the MIDI
|
||||
* device.
|
||||
*/
|
||||
struct ActiveNote {
|
||||
int8 source;
|
||||
uint8 channel;
|
||||
uint8 note;
|
||||
// True if the note is sustained. The note will turn off when the
|
||||
// sustain controller for the MIDI channel is turned off.
|
||||
bool sustain;
|
||||
|
||||
ActiveNote() { clear(); }
|
||||
|
||||
void clear() {
|
||||
source = 0x7F;
|
||||
channel = 0xFF;
|
||||
note = 0xFF;
|
||||
sustain = false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Stores data which is to be transmitted as a SysEx message to a MIDI
|
||||
* device. Neither data nor length should include the SysEx start and stop
|
||||
* bytes.
|
||||
*/
|
||||
struct SysExData {
|
||||
byte data[270];
|
||||
uint16 length;
|
||||
int8 source;
|
||||
SysExData() : length(0), source(-1) {
|
||||
memset(data, 0, sizeof(data));
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
// Callback hooked up to the driver wrapped by the MIDI driver
|
||||
// object. Executes onTimer and the external callback set by
|
||||
// the setTimerCallback function.
|
||||
static void timerCallback(void *data);
|
||||
|
||||
MidiDriver_MT32GM(MusicType midiType);
|
||||
~MidiDriver_MT32GM();
|
||||
|
||||
// MidiDriver interface
|
||||
int open() override;
|
||||
// Open the driver wrapping the specified MidiDriver instance.
|
||||
virtual int open(MidiDriver *driver, bool nativeMT32);
|
||||
void close() override;
|
||||
bool isOpen() const override { return _isOpen; }
|
||||
bool isReady(int8 source = -1) override;
|
||||
uint32 property(int prop, uint32 param) override;
|
||||
|
||||
using MidiDriver_BASE::send;
|
||||
void send(uint32 b) override;
|
||||
void send(int8 source, uint32 b) override;
|
||||
void sysEx(const byte *msg, uint16 length) override;
|
||||
uint16 sysExNoDelay(const byte *msg, uint16 length) override;
|
||||
/**
|
||||
* Puts a SysEx message on the SysEx queue. The message will be sent when
|
||||
* the device is ready to receive it, without blocking the thread.
|
||||
* Use the isReady function to determine if the SysEx has been sent. Other
|
||||
* MIDI messages (not using the queue) should not be sent until the queue
|
||||
* is empty.
|
||||
*/
|
||||
void sysExQueue(const byte *msg, uint16 length, int8 source = -1);
|
||||
/**
|
||||
* Write data to an MT-32 memory location using a SysEx message.
|
||||
* This function will add the necessary header and checksum bytes.
|
||||
*
|
||||
* @param msg Pointer to the data to write to a memory location
|
||||
* @param length The data length
|
||||
* @param targetAddress The start memory address in 8 bit format.
|
||||
* Note that MT-32 memory addresses are sometimes specified in 7 bit format;
|
||||
* these must be converted (f.e. System Area: 10 00 00 -> 04 00 00).
|
||||
* @param queue Specify this parameter to use the SysEx queue to send the
|
||||
* message (see sysExQueue for more information).
|
||||
* @param delay Set this to false to disable the delay to ensure that the
|
||||
* MT-32 has enough time to process the message. This parameter has no
|
||||
* effect if queue is true.
|
||||
* @return The delay in ms that must pass before the next SysEx message is
|
||||
* sent to the MT-32. If delay or queue is true this will be 0; otherwise
|
||||
* it is the caller's responsibility to make sure that the next SysEx is
|
||||
* not sent before this time has passed.
|
||||
*/
|
||||
uint16 sysExMT32(const byte *msg, uint16 length, const uint32 targetAddress, bool queue = false, bool delay = true, int8 source = -1);
|
||||
void metaEvent(int8 source, byte type, const byte *data, uint16 length) override;
|
||||
|
||||
void stopAllNotes(bool stopSustainedNotes = false) override;
|
||||
/**
|
||||
* Removes all SysEx messages in the SysEx queue.
|
||||
*/
|
||||
void clearSysExQueue();
|
||||
MidiChannel *allocateChannel() override;
|
||||
MidiChannel *getPercussionChannel() override;
|
||||
uint32 getBaseTempo() override;
|
||||
|
||||
/**
|
||||
* Allocates a number of MIDI channels for use by the specified source.
|
||||
* By default this implements a simple algorithm which allocates the
|
||||
* unallocated channel(s) with the lowest numbers. The channel numbers in
|
||||
* the MIDI data sent by this source will be mapped to the allocated MIDI
|
||||
* output channels. The function can be overridden to implement more
|
||||
* complex channel allocation algorithms.
|
||||
* Channels are freed when the source is deinitialized.
|
||||
* Note that sources are not required to allocate channels, so if sources
|
||||
* use conflicting MIDI channels, make sure to use this function
|
||||
* consistently.
|
||||
*
|
||||
* @param source The source for which to allocate channels
|
||||
* @param numChannels The number of channels to allocate
|
||||
* @return True if allocation was successful, false otherwise (usually
|
||||
* because insufficent channels were available)
|
||||
*/
|
||||
virtual bool allocateSourceChannels(uint8 source, uint8 numChannels);
|
||||
/**
|
||||
* Deinitializes a source. This will abort active fades, free any output
|
||||
* channels allocated to the source and stop active notes.
|
||||
*/
|
||||
void deinitSource(uint8 source) override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* This will initialize the _controlData array with the default values for
|
||||
* MT-32 or GM (depending on the _nativeMT32 value).
|
||||
*/
|
||||
virtual void initControlData();
|
||||
/**
|
||||
* Initializes the MIDI device. Will call initMT32 or initGM.
|
||||
*/
|
||||
virtual void initMidiDevice();
|
||||
/**
|
||||
* Initializes the MT-32 MIDI device. The device will be reset and,
|
||||
* if the parameter is specified, set up for General MIDI data.
|
||||
*
|
||||
* @param initForGM True if the MT-32 should be initialized for GM mapping
|
||||
*/
|
||||
virtual void initMT32(bool initForGM);
|
||||
/**
|
||||
* Initializes the General MIDI device. The device will be reset.
|
||||
* If the initForMT32 parameter is specified, the device will be set up for
|
||||
* MT-32 MIDI data. If the device supports Roland GS, the enableGS
|
||||
* parameter can be specified for enhanced GS MT-32 compatibility.
|
||||
*
|
||||
* @param initForMT32 True if the device should be initialized for MT-32 mapping
|
||||
* @param enableGS True if the device should be initialized for GS MT-32 mapping
|
||||
*/
|
||||
virtual void initGM(bool initForMT32, bool enableGS);
|
||||
/**
|
||||
* Processes a MIDI event. The type of event is determined and the
|
||||
* corresponding function is called to handle the event.
|
||||
* This function is called after mapping the MIDI data channel to an output
|
||||
* channel, so the specified output channel is used and not the channel in
|
||||
* the event bytes.
|
||||
*
|
||||
* @param source The source of the event
|
||||
* @param b The event MIDI bytes
|
||||
* @param outputChannel The output channel for the event
|
||||
* @param controlData The control data set to use when processing the event
|
||||
* @param channelLockedByOtherSource True if the output channel is locked
|
||||
* by another source. This will prevent the event from actually being sent
|
||||
* to the MIDI device, but controlData will be updated. Default is false.
|
||||
*/
|
||||
virtual void processEvent(int8 source, uint32 b, uint8 outputChannel,
|
||||
MidiChannelControlData &controlData, bool channelLockedByOtherSource = false);
|
||||
/**
|
||||
* Applies the controller default settings to the specified output channel
|
||||
* for the specified source.
|
||||
* This will set all default values specified on _controllerDefaults on the
|
||||
* channel except sustain, which is set by deinitSource.
|
||||
*
|
||||
* @param source The source triggering the default settings
|
||||
* @param controlData The control data set to use when setting the defaults
|
||||
* @param outputChannel The output channel on which the defaults should be
|
||||
* set
|
||||
* @param channelLockedByOtherSource True if the output channel is locked
|
||||
* by another source. This will prevent the defaults from actually being
|
||||
* sent to the MIDI device, but controlData will be updated. Default is
|
||||
* false.
|
||||
*/
|
||||
virtual void applyControllerDefaults(uint8 source, MidiChannelControlData &controlData, uint8 outputChannel, bool channelLockedByOtherSource);
|
||||
/**
|
||||
* Processes a note on or off MIDI event.
|
||||
* This will apply source volume if necessary, update the active note
|
||||
* registration and send the event to the MIDI device.
|
||||
*
|
||||
* @param outputChannel The MIDI output channel for the event
|
||||
* @param command The MIDI command byte
|
||||
* @param controlData The control data set that will be used for applying
|
||||
* source volume
|
||||
*/
|
||||
virtual void noteOnOff(byte outputChannel, byte command, byte note, byte velocity,
|
||||
int8 source, MidiChannelControlData &controlData);
|
||||
/**
|
||||
* Processes a polyphonic aftertouch MIDI event.
|
||||
* This implementation will just send the event to the MIDI device.
|
||||
*
|
||||
* @param outputChannel The MIDI output channel for the event
|
||||
* @param note The note on which aftertouch should be applied
|
||||
* @param pressure The amount of pressure which should be applied
|
||||
* @param source The source of the event
|
||||
* @param controlData The control data set for the MIDI channel
|
||||
* @param channelLockedByOtherSource True if the output channel is locked
|
||||
* by another source. Default is false.
|
||||
*/
|
||||
virtual void polyAftertouch(byte outputChannel, byte note, byte pressure,
|
||||
int8 source, MidiChannelControlData &controlData, bool channelLockedByOtherSource = false);
|
||||
/**
|
||||
* Process a control change MIDI event.
|
||||
* This will update the specified control data set and apply other
|
||||
* processing if necessary, and then send the event to the MIDI device.
|
||||
*
|
||||
* @param outputChannel The MIDI output channel for the event
|
||||
* @param controlData The control data set that the new controller value
|
||||
* should be stored on
|
||||
* @param channelLockedByOtherSource True if the output channel is locked
|
||||
* by another source. Default is false.
|
||||
*/
|
||||
virtual void controlChange(byte outputChannel, byte controllerNumber, byte controllerValue,
|
||||
int8 source, MidiChannelControlData &controlData, bool channelLockedByOtherSource = false);
|
||||
/**
|
||||
* Process a program change MIDI event.
|
||||
* This will update the specified control data set, apply MT-32 <> GM
|
||||
* instrument mapping and other processing, and send the event to the MIDI
|
||||
* device.
|
||||
*
|
||||
* @param outputChannel The MIDI output channel for the event
|
||||
* @param controlData The control data set that the new program value
|
||||
* should be stored on
|
||||
* @param channelLockedByOtherSource True if the output channel is locked
|
||||
* by another source. Default is false.
|
||||
*/
|
||||
virtual void programChange(byte outputChannel, byte patchId, int8 source,
|
||||
MidiChannelControlData &controlData, bool channelLockedByOtherSource = false);
|
||||
/**
|
||||
* Processes a channel aftertouch MIDI event.
|
||||
* This whil update the specified control data set and send the event to
|
||||
* the MIDI device.
|
||||
*
|
||||
* @param outputChannel The MIDI output channel for the event
|
||||
* @param pressure The amount of pressure which should be applied
|
||||
* @param source The source of the event
|
||||
* @param controlData The control data set for the MIDI channel
|
||||
* @param channelLockedByOtherSource True if the output channel is locked
|
||||
* by another source. Default is false.
|
||||
*/
|
||||
virtual void channelAftertouch(byte outputChannel, byte pressure, int8 source,
|
||||
MidiChannelControlData &controlData, bool channelLockedByOtherSource = false);
|
||||
/**
|
||||
* Processes a pitch bend MIDI event.
|
||||
* This whil update the specified control data set and send the event to
|
||||
* the MIDI device.
|
||||
*
|
||||
* @param outputChannel The MIDI output channel for the event
|
||||
* @param pitchBendLsb The pitch bend LSB
|
||||
* @param pitchBendMsb The pitch bend MSB
|
||||
* @param source The source of the event
|
||||
* @param controlData The control data set for the MIDI channel
|
||||
* @param channelLockedByOtherSource True if the output channel is locked
|
||||
* by another source. Default is false.
|
||||
*/
|
||||
virtual void pitchBend(byte outputChannel, uint8 pitchBendLsb, uint8 pitchBendMsb,
|
||||
int8 source, MidiChannelControlData &controlData, bool channelLockedByOtherSource = false);
|
||||
|
||||
/**
|
||||
* Adds a note to the active note registration.
|
||||
*/
|
||||
virtual bool addActiveNote(uint8 outputChannel, uint8 note, int8 source);
|
||||
/**
|
||||
* Removes a note from the active note registration.
|
||||
*/
|
||||
virtual bool removeActiveNote(uint8 outputChannel, uint8 note, int8 source);
|
||||
/**
|
||||
* Removes all sustained or all non-sustained notes on the specified MIDI
|
||||
* channel from the active note registration.
|
||||
*/
|
||||
virtual void removeActiveNotes(uint8 outputChannel, bool sustainedNotes);
|
||||
/**
|
||||
* Returns true if the MIDI device uses the specified MIDI channel.
|
||||
*/
|
||||
bool isOutputChannelUsed(int8 outputChannel);
|
||||
/**
|
||||
* Maps the specified MT-32 instrument to an equivalent GM instrument.
|
||||
* This implementation looks up the instrument in the _mt32ToGMInstrumentMap
|
||||
* array. Override this function to implement more complex mapping schemes.
|
||||
*/
|
||||
virtual byte mapMT32InstrumentToGM(byte mt32Instrument);
|
||||
/**
|
||||
* Maps the specified GM instrument to an equivalent MT-32 instrument.
|
||||
* This implementation looks up the instrument in the _gmToMT32InstrumentMap
|
||||
* array. Override this function to implement more complex mapping schemes.
|
||||
*/
|
||||
virtual byte mapGMInstrumentToMT32(byte gmInstrument);
|
||||
/**
|
||||
* Checks if the currently selected GS bank / instrument variation
|
||||
* on the specified channel is valid for the specified patch.
|
||||
* If this is not the case, the correct bank will be returned which
|
||||
* can be set by sending a bank select message. If no correction is
|
||||
* needed, 0xFF will be returned.
|
||||
* This emulates the fallback functionality of the Roland SC-55 v1.2x,
|
||||
* on which some games rely to correct wrong bank selects.
|
||||
*/
|
||||
byte correctInstrumentBank(byte outputChannel, byte patchId);
|
||||
|
||||
/**
|
||||
* Returns the MIDI output channel mapped to the specified data channel.
|
||||
* If the data channel has not been mapped yet, a new mapping to one of the
|
||||
* output channels available to the source will be created.
|
||||
*
|
||||
* @param source The source using the data channel
|
||||
* @param dataChannel The data channel to map
|
||||
* @return The mapped output channel, or -1 if no mapping is possible
|
||||
*/
|
||||
virtual int8 mapSourceChannel(uint8 source, uint8 dataChannel);
|
||||
|
||||
void applySourceVolume(uint8 source) override;
|
||||
void stopAllNotes(uint8 source, uint8 channel) override;
|
||||
/**
|
||||
* Runs the MIDI driver's timer related functionality. Will update volume
|
||||
* fades and sends messages from the SysEx queue if necessary.
|
||||
*/
|
||||
void onTimer() override;
|
||||
|
||||
Common::Mutex _allocationMutex; // For operations on MIDI channel allocation
|
||||
Common::Mutex _activeNotesMutex; // For operations on active notes registration
|
||||
|
||||
// The wrapped MIDI driver.
|
||||
MidiDriver *_driver;
|
||||
// The type of MIDI data supplied to the driver: MT-32 or General MIDI.
|
||||
MusicType _midiType;
|
||||
// True if the MIDI output is an MT-32 (hardware or 100% emulated),
|
||||
// false if the MIDI output is a General MIDI device.
|
||||
bool _nativeMT32;
|
||||
// True if the General MIDI output supports Roland GS for improved MT-32 mapping.
|
||||
bool _enableGS;
|
||||
// Indicates if the stereo panning in the MIDI data is reversed
|
||||
// compared to the stereo panning of the intended MIDI device.
|
||||
bool _midiDataReversePanning;
|
||||
// Indicates if the stereo panning of the output MIDI device is
|
||||
// reversed compared to the stereo panning of the type of MIDI
|
||||
// device targeted by the MIDI data (i.e. MT-32 data playing on
|
||||
// a GM device or the other way around).
|
||||
bool _midiDeviceReversePanning;
|
||||
// True if GS percussion channel volume should be scaled to match MT-32 volume.
|
||||
bool _scaleGSPercussionVolumeToMT32;
|
||||
|
||||
// True if this MIDI driver has been opened.
|
||||
bool _isOpen;
|
||||
// Bitmask of the MIDI channels in use by the output device.
|
||||
uint16 _outputChannelMask;
|
||||
int _baseFreq;
|
||||
|
||||
// stores the controller values for each MIDI channel
|
||||
MidiChannelControlData *_controlData[MIDI_CHANNEL_COUNT];
|
||||
// The mapping of MIDI data channels to output channels for each source.
|
||||
int8 _channelMap[MAXIMUM_SOURCES][MIDI_CHANNEL_COUNT];
|
||||
// Bitmask specifying which MIDI channels are available for use by each source.
|
||||
uint16 _availableChannels[MAXIMUM_SOURCES];
|
||||
|
||||
// Maps used for MT-32 <> GM instrument mapping. Set these to an alternate
|
||||
// 128 byte array to customize the mapping.
|
||||
const byte *_mt32ToGMInstrumentMap;
|
||||
const byte *_gmToMT32InstrumentMap;
|
||||
// The maximum active notes for the current MIDI device.
|
||||
uint8 _maximumActiveNotes;
|
||||
// Active note registration
|
||||
ActiveNote *_activeNotes;
|
||||
|
||||
// The current number of microseconds that have to elapse before the next
|
||||
// SysEx message can be sent.
|
||||
uint32 _sysExDelay;
|
||||
// Queue of SysEx messages to be sent to the MIDI device.
|
||||
Common::List<SysExData> _sysExQueue;
|
||||
// Mutex for write access to the SysEx queue.
|
||||
Common::Mutex _sysExQueueMutex;
|
||||
};
|
||||
/** @} */
|
||||
#endif
|
||||
Reference in New Issue
Block a user