Updated libADLMIDI to version 1.5.1

Changelog
 * Added an ability to disable the automatical arpeggio
 * Added an ability to set the count of loops (how many times to play the song)
 * Added an ability to disable/enable playing of selected MIDI channels
 * Fixed memory damages and crashes while playing XMI files
 * Added bank-specific MT32 defaults (to don't confuse XMI playback between different games, works for AIL and IBK only, and for WOPL if set at the header)
 * Added the chip channels allocation mode option
 * Fixed the playback of multi-song XMI files
 * Added an ability to switch the XMI song on the fly

ALSO (future updates)
 * Fixed the work on big endian processors
 * Fixed ARM64 build on some platforms
 * Improved support of the EA-MUS files (Thanks to [dashodanger](https://github.com/dashodanger))
 * Fixed crash on attempt to change the volume of a blank note
This commit is contained in:
Wohlstand 2023-01-02 01:17:44 +03:00 committed by Christoph Oelckers
parent 36a5308de1
commit 5bd573478b
32 changed files with 594 additions and 6603 deletions

View file

@ -2,7 +2,7 @@
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation * libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
* *
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi> * Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru> * ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
* *
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation: * Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
* http://iki.fi/bisqwit/source/adlmidi.html * http://iki.fi/bisqwit/source/adlmidi.html
@ -551,6 +551,24 @@ ADLMIDI_EXPORT void adl_setFullRangeBrightness(struct ADL_MIDIPlayer *device, in
play->m_setup.fullRangeBrightnessCC74 = (fr_brightness != 0); play->m_setup.fullRangeBrightnessCC74 = (fr_brightness != 0);
} }
ADLMIDI_EXPORT void adl_setAutoArpeggio(ADL_MIDIPlayer *device, int aaEn)
{
if(!device)
return;
MidiPlayer *play = GET_MIDI_PLAYER(device);
assert(play);
play->m_setup.enableAutoArpeggio = (aaEn != 0);
}
ADLMIDI_EXPORT int adl_getAutoArpeggio(ADL_MIDIPlayer *device)
{
if(!device)
return 0;
MidiPlayer *play = GET_MIDI_PLAYER(device);
assert(play);
return play->m_setup.enableAutoArpeggio ? 1 : 0;
}
ADLMIDI_EXPORT void adl_setLoopEnabled(ADL_MIDIPlayer *device, int loopEn) ADLMIDI_EXPORT void adl_setLoopEnabled(ADL_MIDIPlayer *device, int loopEn)
{ {
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
@ -565,6 +583,34 @@ ADLMIDI_EXPORT void adl_setLoopEnabled(ADL_MIDIPlayer *device, int loopEn)
#endif #endif
} }
ADLMIDI_EXPORT void adl_setLoopCount(ADL_MIDIPlayer *device, int loopCount)
{
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
if(!device)
return;
MidiPlayer *play = GET_MIDI_PLAYER(device);
assert(play);
play->m_sequencer->setLoopsCount(loopCount);
#else
ADL_UNUSED(device);
ADL_UNUSED(loopCount);
#endif
}
ADLMIDI_EXPORT void adl_setLoopHooksOnly(ADL_MIDIPlayer *device, int loopHooksOnly)
{
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
if(!device)
return;
MidiPlayer *play = GET_MIDI_PLAYER(device);
assert(play);
play->m_sequencer->setLoopHooksOnly(loopHooksOnly);
#else
ADL_UNUSED(device);
ADL_UNUSED(loopHooksOnly);
#endif
}
ADLMIDI_EXPORT void adl_setSoftPanEnabled(ADL_MIDIPlayer *device, int softPanEn) ADLMIDI_EXPORT void adl_setSoftPanEnabled(ADL_MIDIPlayer *device, int softPanEn)
{ {
if(!device) if(!device)
@ -618,6 +664,29 @@ ADLMIDI_EXPORT int adl_getVolumeRangeModel(struct ADL_MIDIPlayer *device)
return play->m_synth->getVolumeScaleModel(); return play->m_synth->getVolumeScaleModel();
} }
ADLMIDI_EXPORT void adl_setChannelAllocMode(struct ADL_MIDIPlayer *device, int chanalloc)
{
if(!device)
return;
MidiPlayer *play = GET_MIDI_PLAYER(device);
assert(play);
Synth &synth = *play->m_synth;
if(chanalloc < -1 || chanalloc >= ADLMIDI_ChanAlloc_Count)
chanalloc = ADLMIDI_ChanAlloc_AUTO;
synth.m_channelAlloc = static_cast<ADLMIDI_ChannelAlloc>(chanalloc);
}
ADLMIDI_EXPORT int adl_getChannelAllocMode(struct ADL_MIDIPlayer *device)
{
if(!device)
return -1;
MidiPlayer *play = GET_MIDI_PLAYER(device);
assert(play);
return static_cast<int>(play->m_synth->m_channelAlloc);
}
ADLMIDI_EXPORT int adl_openBankFile(struct ADL_MIDIPlayer *device, const char *filePath) ADLMIDI_EXPORT int adl_openBankFile(struct ADL_MIDIPlayer *device, const char *filePath)
{ {
if(device) if(device)
@ -716,6 +785,35 @@ ADLMIDI_EXPORT int adl_openData(ADL_MIDIPlayer *device, const void *mem, unsigne
return -1; return -1;
} }
ADLMIDI_EXPORT void adl_selectSongNum(struct ADL_MIDIPlayer *device, int songNumber)
{
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
if(!device)
return;
MidiPlayer *play = GET_MIDI_PLAYER(device);
assert(play);
play->m_sequencer->setSongNum(songNumber);
#else
ADL_UNUSED(device);
ADL_UNUSED(songNumber);
#endif
}
ADLMIDI_EXPORT int adl_getSongsCount(struct ADL_MIDIPlayer *device)
{
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
if(!device)
return 0;
MidiPlayer *play = GET_MIDI_PLAYER(device);
assert(play);
return play->m_sequencer->getSongsCount();
#else
ADL_UNUSED(device);
return 0;
#endif
}
ADLMIDI_EXPORT const char *adl_emulatorName() ADLMIDI_EXPORT const char *adl_emulatorName()
{ {
@ -1083,6 +1181,36 @@ ADLMIDI_EXPORT void adl_setDebugMessageHook(struct ADL_MIDIPlayer *device, ADL_D
#endif #endif
} }
/* Set loop start hook */
ADLMIDI_EXPORT void adl_setLoopStartHook(struct ADL_MIDIPlayer *device, ADL_LoopPointHook loopStartHook, void *userData)
{
if(!device)
return;
MidiPlayer *play = GET_MIDI_PLAYER(device);
assert(play);
play->hooks.onLoopStart = loopStartHook;
play->hooks.onLoopStart_userData = userData;
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
play->m_sequencerInterface->onloopStart = loopStartHook;
play->m_sequencerInterface->onloopStart_userData = userData;
#endif
}
/* Set loop end hook */
ADLMIDI_EXPORT void adl_setLoopEndHook(struct ADL_MIDIPlayer *device, ADL_LoopPointHook loopEndHook, void *userData)
{
if(!device)
return;
MidiPlayer *play = GET_MIDI_PLAYER(device);
assert(play);
play->hooks.onLoopEnd = loopEndHook;
play->hooks.onLoopEnd_userData = userData;
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
play->m_sequencerInterface->onloopEnd = loopEndHook;
play->m_sequencerInterface->onloopEnd_userData = userData;
#endif
}
#ifndef ADLMIDI_HW_OPL #ifndef ADLMIDI_HW_OPL
# ifndef __WATCOMC__ # ifndef __WATCOMC__
@ -1310,9 +1438,6 @@ ADLMIDI_EXPORT int adl_playFormat(ADL_MIDIPlayer *device, int sampleCount,
while(left > 0) while(left > 0)
{ {
{//...
if(setup.delay <= 0.0)
setup.delay = double(left / 2) / double(setup.PCM_RATE);
const double eat_delay = setup.delay < setup.maxdelay ? setup.delay : setup.maxdelay; const double eat_delay = setup.delay < setup.maxdelay ? setup.delay : setup.maxdelay;
if(hasSkipped) if(hasSkipped)
{ {
@ -1376,8 +1501,6 @@ ADLMIDI_EXPORT int adl_playFormat(ADL_MIDIPlayer *device, int sampleCount,
} }
else else
setup.delay = player->Tick(eat_delay, setup.mindelay); setup.delay = player->Tick(eat_delay, setup.mindelay);
}//...
} }
return static_cast<int>(gotten_len); return static_cast<int>(gotten_len);
@ -1420,7 +1543,6 @@ ADLMIDI_EXPORT int adl_generateFormat(struct ADL_MIDIPlayer *device, int sampleC
while(left > 0) while(left > 0)
{ {
{//...
if(delay <= 0.0) if(delay <= 0.0)
delay = double(left / 2) / double(setup.PCM_RATE); delay = double(left / 2) / double(setup.PCM_RATE);
const double eat_delay = delay < setup.maxdelay ? delay : setup.maxdelay; const double eat_delay = delay < setup.maxdelay ? delay : setup.maxdelay;
@ -1460,7 +1582,6 @@ ADLMIDI_EXPORT int adl_generateFormat(struct ADL_MIDIPlayer *device, int sampleC
} }
player->TickIterators(eat_delay); player->TickIterators(eat_delay);
}//...
} }
return static_cast<int>(gotten_len); return static_cast<int>(gotten_len);
@ -1552,6 +1673,27 @@ ADLMIDI_EXPORT int adl_setTrackOptions(struct ADL_MIDIPlayer *device, size_t tra
#endif #endif
} }
ADLMIDI_EXPORT int adl_setChannelEnabled(struct ADL_MIDIPlayer *device, size_t channelNumber, int enabled)
{
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
if(!device)
return -1;
MidiPlayer *play = GET_MIDI_PLAYER(device);
assert(play);
MidiSequencer &seq = *play->m_sequencer;
if(!seq.setChannelEnabled(channelNumber, (bool)enabled))
return -1;
return 0;
#else
ADL_UNUSED(device);
ADL_UNUSED(channelNumber);
ADL_UNUSED(enabled);
return -1;
#endif
}
ADLMIDI_EXPORT int adl_setTriggerHandler(struct ADL_MIDIPlayer *device, ADL_TriggerHandler handler, void *userData) ADLMIDI_EXPORT int adl_setTriggerHandler(struct ADL_MIDIPlayer *device, ADL_TriggerHandler handler, void *userData)
{ {
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER #ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER

View file

@ -2,7 +2,7 @@
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation * libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
* *
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi> * Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru> * ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
* *
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation: * Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
* http://iki.fi/bisqwit/source/adlmidi.html * http://iki.fi/bisqwit/source/adlmidi.html
@ -30,7 +30,7 @@ extern "C" {
#define ADLMIDI_VERSION_MAJOR 1 #define ADLMIDI_VERSION_MAJOR 1
#define ADLMIDI_VERSION_MINOR 5 #define ADLMIDI_VERSION_MINOR 5
#define ADLMIDI_VERSION_PATCHLEVEL 0 #define ADLMIDI_VERSION_PATCHLEVEL 1
#define ADLMIDI_TOSTR_I(s) #s #define ADLMIDI_TOSTR_I(s) #s
#define ADLMIDI_TOSTR(s) ADLMIDI_TOSTR_I(s) #define ADLMIDI_TOSTR(s) ADLMIDI_TOSTR_I(s)
@ -125,7 +125,26 @@ enum ADLMIDI_VolumeModels
/*! HMI Sound Operating System volume scaling model */ /*! HMI Sound Operating System volume scaling model */
ADLMIDI_VolumeModel_HMI = 10, ADLMIDI_VolumeModel_HMI = 10,
/*! HMI Sound Operating System volume scaling model, older variant with bugs */ /*! HMI Sound Operating System volume scaling model, older variant with bugs */
ADLMIDI_VolumeModel_HMI_OLD = 11 ADLMIDI_VolumeModel_HMI_OLD = 11,
/*! Count of available volume model modes */
ADLMIDI_VolumeModel_Count
};
/*!
* \brief Algorithms of channel allocation for new notes
*/
enum ADLMIDI_ChannelAlloc
{
/*! Automatical choise of the method according to the volume model and internal preferrences */
ADLMIDI_ChanAlloc_AUTO = -1,
/*! Take only channels that has expired sounding delay */
ADLMIDI_ChanAlloc_OffDelay,
/*! Take any first released channel with the same instrument */
ADLMIDI_ChanAlloc_SameInst,
/*! Take any first released channel */
ADLMIDI_ChanAlloc_AnyReleased,
/*! Count of available channel allocation modes */
ADLMIDI_ChanAlloc_Count
}; };
/** /**
@ -548,6 +567,21 @@ extern ADLMIDI_DECLSPEC void adl_setScaleModulators(struct ADL_MIDIPlayer *devic
*/ */
extern ADLMIDI_DECLSPEC void adl_setFullRangeBrightness(struct ADL_MIDIPlayer *device, int fr_brightness); extern ADLMIDI_DECLSPEC void adl_setFullRangeBrightness(struct ADL_MIDIPlayer *device, int fr_brightness);
/**
* @brief Enable(1) or Disable(0) the automatical arpeggio system
*
* @param device Instance of the library
* @param aaEn 0 - disabled, 1 - enabled
*/
extern ADLMIDI_DECLSPEC void adl_setAutoArpeggio(struct ADL_MIDIPlayer *device, int aaEn);
/**
* @brief Get the state of the automatical arpeggio system enable state
* @param device Instalce of the library
* @return 0 - disabled, 1 - enabled
*/
extern ADLMIDI_DECLSPEC int adl_getAutoArpeggio(struct ADL_MIDIPlayer *device);
/** /**
* @brief Enable or disable built-in loop (built-in loop supports 'loopStart' and 'loopEnd' tags to loop specific part) * @brief Enable or disable built-in loop (built-in loop supports 'loopStart' and 'loopEnd' tags to loop specific part)
* @param device Instance of the library * @param device Instance of the library
@ -555,6 +589,23 @@ extern ADLMIDI_DECLSPEC void adl_setFullRangeBrightness(struct ADL_MIDIPlayer *d
*/ */
extern ADLMIDI_DECLSPEC void adl_setLoopEnabled(struct ADL_MIDIPlayer *device, int loopEn); extern ADLMIDI_DECLSPEC void adl_setLoopEnabled(struct ADL_MIDIPlayer *device, int loopEn);
/**
* @brief Set how many times loop will be played
*
* Note: The song will be played once if loop has been disabled with no matter which value of loop count was set
*
* @param device Instance of the library
* @param loopCount Number of loops or -1 to loop infinitely
*/
extern ADLMIDI_DECLSPEC void adl_setLoopCount(struct ADL_MIDIPlayer *device, int loopCount);
/**
* @brief Make song immediately stop on reaching a loop end point
* @param device Instance of the library
* @param loopHooksOnly 0 - disabled, 1 - enabled
*/
extern ADLMIDI_DECLSPEC void adl_setLoopHooksOnly(struct ADL_MIDIPlayer *device, int loopHooksOnly);
/** /**
* @brief Enable or disable soft panning with chip emulators * @brief Enable or disable soft panning with chip emulators
* @param device Instance of the library * @param device Instance of the library
@ -584,6 +635,20 @@ extern ADLMIDI_DECLSPEC void adl_setVolumeRangeModel(struct ADL_MIDIPlayer *devi
*/ */
extern ADLMIDI_DECLSPEC int adl_getVolumeRangeModel(struct ADL_MIDIPlayer *device); extern ADLMIDI_DECLSPEC int adl_getVolumeRangeModel(struct ADL_MIDIPlayer *device);
/**
* @brief Set the channel allocation mode
* @param device Instance of the library
* @param chanalloc Channel allocation mode (#ADLMIDI_ChannelAlloc)
*/
extern ADLMIDI_DECLSPEC void adl_setChannelAllocMode(struct ADL_MIDIPlayer *device, int chanalloc);
/**
* @brief Get the current channel allocation mode
* @param device Instance of the library
* @return Channel allocation mode (#ADLMIDI_ChannelAlloc)
*/
extern ADLMIDI_DECLSPEC int adl_getChannelAllocMode(struct ADL_MIDIPlayer *device);
/** /**
* @brief Load WOPL bank file from File System * @brief Load WOPL bank file from File System
* *
@ -766,6 +831,27 @@ extern ADLMIDI_DECLSPEC int adl_openFile(struct ADL_MIDIPlayer *device, const ch
*/ */
extern ADLMIDI_DECLSPEC int adl_openData(struct ADL_MIDIPlayer *device, const void *mem, unsigned long size); extern ADLMIDI_DECLSPEC int adl_openData(struct ADL_MIDIPlayer *device, const void *mem, unsigned long size);
/**
* @brief Switch another song if multi-song file is playing (for example, XMI)
*
* Note: to set the initial song to load, you should call this function
* BBEFORE calling `adl_openFile` or `adl_openData`. When loaded file has more than
* one built-in songs (Usually XMIformat), it will be started from the selected number.
* You may call this function to switch another song.
*
* @param device Instance of the library
* @param songNumber Identifier of the track to load (or -1 to mix all tracks as one song)
* @return
*/
extern ADLMIDI_DECLSPEC void adl_selectSongNum(struct ADL_MIDIPlayer *device, int songNumber);
/**
* @brief Retrive the number of songs in a currently opened file
* @param device Instance of the library
* @return Number of songs in the file. If 1 or less, means, the file has only one song inside.
*/
extern ADLMIDI_DECLSPEC int adl_getSongsCount(struct ADL_MIDIPlayer *device);
/** /**
* @brief Resets MIDI player (per-channel setup) into initial state * @brief Resets MIDI player (per-channel setup) into initial state
* @param device Instance of the library * @param device Instance of the library
@ -876,6 +962,15 @@ enum ADLMIDI_TrackOptions
*/ */
extern ADLMIDI_DECLSPEC int adl_setTrackOptions(struct ADL_MIDIPlayer *device, size_t trackNumber, unsigned trackOptions); extern ADLMIDI_DECLSPEC int adl_setTrackOptions(struct ADL_MIDIPlayer *device, size_t trackNumber, unsigned trackOptions);
/**
* @brief Sets the channel of the current sequence enable state
* @param device Instance of the library
* @param channelNumber Number of the channel (from 0 to 15)
* @param enabled 1 to enable and 0 to disable
* @return 0 on success, <0 when any error has occurred
*/
extern ADLMIDI_DECLSPEC int adl_setChannelEnabled(struct ADL_MIDIPlayer *device, size_t channelNumber, int enabled);
/** /**
* @brief Handler of callback trigger events * @brief Handler of callback trigger events
* @param userData Pointer to user data (usually, context of something) * @param userData Pointer to user data (usually, context of something)
@ -1210,8 +1305,19 @@ typedef void (*ADL_NoteHook)(void *userdata, int adlchn, int note, int ins, int
*/ */
typedef void (*ADL_DebugMessageHook)(void *userdata, const char *fmt, ...); typedef void (*ADL_DebugMessageHook)(void *userdata, const char *fmt, ...);
/**
* @brief Loop start/end point reach hook
* @param userdata Pointer to user data (usually, context of someting)
*/
typedef void (*ADL_LoopPointHook)(void *userdata);
/** /**
* @brief Set raw MIDI event hook * @brief Set raw MIDI event hook
*
* CAUTION: Don't call any libADLMIDI API functions from off this hook directly!
* Suggestion: Use boolean variables to mark the fact this hook got been called, and then,
* apply your action outside of this hook, for example, in the next after audio output call.
*
* @param device Instance of the library * @param device Instance of the library
* @param rawEventHook Pointer to the callback function which will be called on every MIDI event * @param rawEventHook Pointer to the callback function which will be called on every MIDI event
* @param userData Pointer to user data which will be passed through the callback. * @param userData Pointer to user data which will be passed through the callback.
@ -1220,6 +1326,11 @@ extern ADLMIDI_DECLSPEC void adl_setRawEventHook(struct ADL_MIDIPlayer *device,
/** /**
* @brief Set note hook * @brief Set note hook
*
* CAUTION: Don't call any libADLMIDI API functions from off this hook directly!
* Suggestion: Use boolean variables to mark the fact this hook got been called, and then,
* apply your action outside of this hook, for example, in the next after audio output call.
*
* @param device Instance of the library * @param device Instance of the library
* @param noteHook Pointer to the callback function which will be called on every noteOn MIDI event * @param noteHook Pointer to the callback function which will be called on every noteOn MIDI event
* @param userData Pointer to user data which will be passed through the callback. * @param userData Pointer to user data which will be passed through the callback.
@ -1228,12 +1339,46 @@ extern ADLMIDI_DECLSPEC void adl_setNoteHook(struct ADL_MIDIPlayer *device, ADL_
/** /**
* @brief Set debug message hook * @brief Set debug message hook
*
* CAUTION: Don't call any libADLMIDI API functions from off this hook directly!
* Suggestion: Use boolean variables to mark the fact this hook got been called, and then,
* apply your action outside of this hook, for example, in the next after audio output call.
*
* @param device Instance of the library * @param device Instance of the library
* @param debugMessageHook Pointer to the callback function which will be called on every debug message * @param debugMessageHook Pointer to the callback function which will be called on every debug message
* @param userData Pointer to user data which will be passed through the callback. * @param userData Pointer to user data which will be passed through the callback.
*/ */
extern ADLMIDI_DECLSPEC void adl_setDebugMessageHook(struct ADL_MIDIPlayer *device, ADL_DebugMessageHook debugMessageHook, void *userData); extern ADLMIDI_DECLSPEC void adl_setDebugMessageHook(struct ADL_MIDIPlayer *device, ADL_DebugMessageHook debugMessageHook, void *userData);
/**
* @brief Set the look start point hook
*
* CAUTION: Don't call any libADLMIDI API functions from off this hook directly!
* Suggestion: Use boolean variables to mark the fact this hook got been called, and then,
* apply your action outside of this hook, for example, in the next after audio output call.
*
* @param device Instance of the library
* @param loopStartHook Pointer to the callback function which will be called on every loop start point passing
* @param userData Pointer to user data which will be passed through the callback.
*/
extern ADLMIDI_DECLSPEC void adl_setLoopStartHook(struct ADL_MIDIPlayer *device, ADL_LoopPointHook loopStartHook, void *userData);
/**
* @brief Set the look start point hook
*
* CAUTION: Don't call any libADLMIDI API functions from off this hook directly!
* Suggestion: Use boolean variables to mark the fact this hook got been called, and then,
* apply your action outside of this hook, for example, in the next after audio output call.
*
* If you want to switch the song after calling this hook, suggested to call the function
* adl_setLoopHooksOnly(device, 1) to immediately stop the song on reaching the loop point
*
* @param device Instance of the library
* @param loopStartHook Pointer to the callback function which will be called on every loop start point passing
* @param userData Pointer to user data which will be passed through the callback.
*/
extern ADLMIDI_DECLSPEC void adl_setLoopEndHook(struct ADL_MIDIPlayer *device, ADL_LoopPointHook loopEndHook, void *userData);
/** /**
* @brief Get a textual description of the channel state. For display only. * @brief Get a textual description of the channel state. For display only.
* @param device Instance of the library * @param device Instance of the library

View file

@ -2,7 +2,7 @@
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation * libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
* *
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi> * Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru> * ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
* *
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation: * Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
* http://iki.fi/bisqwit/source/adlmidi.html * http://iki.fi/bisqwit/source/adlmidi.html

View file

@ -2,7 +2,7 @@
* libADLMIDI is a free MIDI to WAV conversion library with OPL3 emulation * libADLMIDI is a free MIDI to WAV conversion library with OPL3 emulation
* *
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi> * Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru> * ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
* *
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation: * Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
* http://iki.fi/bisqwit/source/adlmidi.html * http://iki.fi/bisqwit/source/adlmidi.html

View file

@ -2,7 +2,7 @@
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation * libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
* *
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi> * Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru> * ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
* *
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation: * Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
* http://iki.fi/bisqwit/source/adlmidi.html * http://iki.fi/bisqwit/source/adlmidi.html

View file

@ -2,7 +2,7 @@
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation * libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
* *
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi> * Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru> * ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
* *
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation: * Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
* http://iki.fi/bisqwit/source/adlmidi.html * http://iki.fi/bisqwit/source/adlmidi.html
@ -31,7 +31,7 @@
#include <stddef.h> #include <stddef.h>
#include <vector> #include <vector>
#ifndef _MSC_VER #if !defined(_MSC_VER) && !defined(__aarch64__) && !defined(__3DS__)
#define ATTRIB_PACKED __attribute__((__packed__)) #define ATTRIB_PACKED __attribute__((__packed__))
#else #else
#define ATTRIB_PACKED #define ATTRIB_PACKED

View file

@ -2,7 +2,7 @@
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation * libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
* *
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi> * Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru> * ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
* *
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation: * Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
* http://iki.fi/bisqwit/source/adlmidi.html * http://iki.fi/bisqwit/source/adlmidi.html
@ -117,6 +117,7 @@ bool MIDIplay::LoadBank(FileAndMemReader &fr)
synth.m_insBankSetup.scaleModulators = false; synth.m_insBankSetup.scaleModulators = false;
synth.m_insBankSetup.deepTremolo = (wopl->opl_flags & WOPL_FLAG_DEEP_TREMOLO) != 0; synth.m_insBankSetup.deepTremolo = (wopl->opl_flags & WOPL_FLAG_DEEP_TREMOLO) != 0;
synth.m_insBankSetup.deepVibrato = (wopl->opl_flags & WOPL_FLAG_DEEP_VIBRATO) != 0; synth.m_insBankSetup.deepVibrato = (wopl->opl_flags & WOPL_FLAG_DEEP_VIBRATO) != 0;
synth.m_insBankSetup.mt32defaults = (wopl->opl_flags & WOPL_FLAG_MT32) != 0;
synth.m_insBankSetup.volumeModel = wopl->volume_model; synth.m_insBankSetup.volumeModel = wopl->volume_model;
m_setup.deepTremoloMode = -1; m_setup.deepTremoloMode = -1;
m_setup.deepVibratoMode = -1; m_setup.deepVibratoMode = -1;

View file

@ -2,7 +2,7 @@
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation * libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
* *
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi> * Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru> * ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
* *
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation: * Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
* http://iki.fi/bisqwit/source/adlmidi.html * http://iki.fi/bisqwit/source/adlmidi.html
@ -36,7 +36,8 @@ enum { MasterVolumeDefault = 127 };
inline bool isXgPercChannel(uint8_t msb, uint8_t lsb) inline bool isXgPercChannel(uint8_t msb, uint8_t lsb)
{ {
return (msb == 0x7E || msb == 0x7F) && (lsb == 0); ADL_UNUSED(lsb);
return (msb == 0x7E || msb == 0x7F);
} }
void MIDIplay::AdlChannel::addAge(int64_t us) void MIDIplay::AdlChannel::addAge(int64_t us)
@ -90,6 +91,7 @@ MIDIplay::MIDIplay(unsigned long sampleRate):
//m_setup.SkipForward = 0; //m_setup.SkipForward = 0;
m_setup.scaleModulators = -1; m_setup.scaleModulators = -1;
m_setup.fullRangeBrightnessCC74 = false; m_setup.fullRangeBrightnessCC74 = false;
m_setup.enableAutoArpeggio = false;
m_setup.delay = 0.0; m_setup.delay = 0.0;
m_setup.carry = 0.0; m_setup.carry = 0.0;
m_setup.tick_skip_samples_delay = 0; m_setup.tick_skip_samples_delay = 0;
@ -126,6 +128,7 @@ void MIDIplay::applySetup()
synth.m_insBankSetup.volumeModel = (b.bankSetup & 0x00FF); synth.m_insBankSetup.volumeModel = (b.bankSetup & 0x00FF);
synth.m_insBankSetup.deepTremolo = (b.bankSetup >> 8 & 0x0001) != 0; synth.m_insBankSetup.deepTremolo = (b.bankSetup >> 8 & 0x0001) != 0;
synth.m_insBankSetup.deepVibrato = (b.bankSetup >> 8 & 0x0002) != 0; synth.m_insBankSetup.deepVibrato = (b.bankSetup >> 8 & 0x0002) != 0;
synth.m_insBankSetup.mt32defaults = (b.bankSetup >> 8 & 0x0004) != 0;
} }
#endif #endif
@ -200,15 +203,15 @@ void MIDIplay::resetMIDIDefaults(int offset)
for(size_t c = offset, n = m_midiChannels.size(); c < n; ++c) for(size_t c = offset, n = m_midiChannels.size(); c < n; ++c)
{ {
MIDIchannel &ch = m_midiChannels[c]; MIDIchannel &ch = m_midiChannels[c];
if(synth.m_musicMode == Synth::MODE_XMIDI)
if(synth.m_musicMode == Synth::MODE_RSXX)
ch.def_volume = 127;
else if(synth.m_insBankSetup.mt32defaults)
{ {
ch.def_volume = 127; ch.def_volume = 127;
ch.def_bendsense_lsb = 0; ch.def_bendsense_lsb = 0;
ch.def_bendsense_msb = 12; ch.def_bendsense_msb = 12;
} }
else
if(synth.m_musicMode == Synth::MODE_RSXX)
ch.def_volume = 127;
} }
} }
@ -290,9 +293,10 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
if(!i.is_end()) if(!i.is_end())
{ {
MIDIchannel::NoteInfo &ni = i->value; MIDIchannel::NoteInfo &ni = i->value;
const int veloffset = ni.ains->midiVelocityOffset; const int veloffset = ni.ains ? ni.ains->midiVelocityOffset : 0;
velocity = (uint8_t)std::min(127, std::max(1, (int)velocity + veloffset)); velocity = (uint8_t)std::min(127, std::max(1, (int)velocity + veloffset));
ni.vol = velocity; ni.vol = velocity;
if(ni.ains)
noteUpdate(channel, i, Upd_Volume); noteUpdate(channel, i, Upd_Volume);
return false; return false;
} }
@ -329,7 +333,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
// Let XG Percussion bank will use (0...127 LSB range in WOPN file) // Let XG Percussion bank will use (0...127 LSB range in WOPN file)
// Choose: SFX or Drum Kits // Choose: SFX or Drum Kits
bank = midiins + ((bank == 0x7E00) ? 128 : 0); bank = midiins + ((midiChan.bank_msb == 0x7E) ? 128 : 0);
} }
else else
{ {
@ -357,8 +361,8 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
caughtMissingBank = true; caughtMissingBank = true;
} }
//Or fall back to bank ignoring LSB (GS) //Or fall back to bank ignoring LSB (GS/XG)
if((ains->flags & OplInstMeta::Flag_NoSound) && ((m_synthMode & Mode_GS) != 0)) if(ains->flags & OplInstMeta::Flag_NoSound)
{ {
size_t fallback = bank & ~(size_t)0x7F; size_t fallback = bank & ~(size_t)0x7F;
if(fallback != bank) if(fallback != bank)
@ -1345,6 +1349,17 @@ int64_t MIDIplay::calculateChipChannelGoodness(size_t c, const MIDIchannel::Note
const AdlChannel &chan = m_chipChannels[c]; const AdlChannel &chan = m_chipChannels[c];
int64_t koff_ms = chan.koff_time_until_neglible_us / 1000; int64_t koff_ms = chan.koff_time_until_neglible_us / 1000;
int64_t s = -koff_ms; int64_t s = -koff_ms;
ADLMIDI_ChannelAlloc allocType = synth.m_channelAlloc;
if(allocType == ADLMIDI_ChanAlloc_AUTO)
{
if(synth.m_musicMode == Synth::MODE_CMF)
allocType = ADLMIDI_ChanAlloc_SameInst;
else if(synth.m_volumeScale == Synth::VOLUME_HMI)
allocType = ADLMIDI_ChanAlloc_AnyReleased; // HMI doesn't care about the same instrument
else
allocType = ADLMIDI_ChanAlloc_OffDelay;
}
// Rate channel with a releasing note // Rate channel with a releasing note
if(s < 0 && chan.users.empty()) if(s < 0 && chan.users.empty())
@ -1353,19 +1368,22 @@ int64_t MIDIplay::calculateChipChannelGoodness(size_t c, const MIDIchannel::Note
s -= 40000; s -= 40000;
// If it's same instrument, better chance to get it when no free channels // If it's same instrument, better chance to get it when no free channels
if(synth.m_musicMode == Synth::MODE_CMF) switch(allocType)
{ {
case ADLMIDI_ChanAlloc_SameInst:
if(isSame) if(isSame)
s = 0; // Re-use releasing channel with the same instrument s = 0; // Re-use releasing channel with the same instrument
} break;
else if(synth.m_volumeScale == Synth::VOLUME_HMI)
{ case ADLMIDI_ChanAlloc_AnyReleased:
s = 0; // HMI doesn't care about the same instrument s = 0; // Re-use any releasing channel
} break;
else
{ default:
case ADLMIDI_ChanAlloc_OffDelay:
if(isSame) if(isSame)
s = -koff_ms; // Wait until releasing sound will complete s = -koff_ms; // Wait until releasing sound will complete
break;
} }
return s; return s;
@ -1502,6 +1520,9 @@ void MIDIplay::killOrEvacuate(size_t from_channel,
{ {
uint16_t cs = static_cast<uint16_t>(c); uint16_t cs = static_cast<uint16_t>(c);
if(!m_setup.enableAutoArpeggio)
break; // Arpeggio disabled completely
if(c >= maxChannels) if(c >= maxChannels)
break; break;
if(c == from_channel) if(c == from_channel)
@ -1725,6 +1746,13 @@ void MIDIplay::updateArpeggio(double) // amount = amount of time passed
Synth &synth = *m_synth; Synth &synth = *m_synth;
if(!m_setup.enableAutoArpeggio) // Arpeggio was disabled
{
if(m_arpeggioCounter != 0)
m_arpeggioCounter = 0;
return;
}
#if 0 #if 0
const unsigned desired_arpeggio_rate = 40; // Hz (upper limit) const unsigned desired_arpeggio_rate = 40; // Hz (upper limit)
# if 1 # if 1

View file

@ -2,7 +2,7 @@
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation * libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
* *
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi> * Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru> * ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
* *
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation: * Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
* http://iki.fi/bisqwit/source/adlmidi.html * http://iki.fi/bisqwit/source/adlmidi.html
@ -37,6 +37,10 @@ struct MIDIEventHooks
MIDIEventHooks() : MIDIEventHooks() :
onNote(NULL), onNote(NULL),
onNote_userData(NULL), onNote_userData(NULL),
onLoopStart(NULL),
onLoopStart_userData(NULL),
onLoopEnd(NULL),
onLoopEnd_userData(NULL),
onDebugMessage(NULL), onDebugMessage(NULL),
onDebugMessage_userData(NULL) onDebugMessage_userData(NULL)
{} {}
@ -46,6 +50,13 @@ struct MIDIEventHooks
NoteHook onNote; NoteHook onNote;
void *onNote_userData; void *onNote_userData;
// Loop start/end hooks
ADL_LoopPointHook onLoopStart;
void *onLoopStart_userData;
ADL_LoopPointHook onLoopEnd;
void *onLoopEnd_userData;
//! Library internal debug messages //! Library internal debug messages
typedef void (*DebugMessageHook)(void *userdata, const char *fmt, ...); typedef void (*DebugMessageHook)(void *userdata, const char *fmt, ...);
DebugMessageHook onDebugMessage; DebugMessageHook onDebugMessage;
@ -526,6 +537,7 @@ public:
//unsigned int SkipForward; //unsigned int SkipForward;
int scaleModulators; int scaleModulators;
bool fullRangeBrightnessCC74; bool fullRangeBrightnessCC74;
bool enableAutoArpeggio;
double delay; double delay;
double carry; double carry;

View file

@ -2,7 +2,7 @@
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation * libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
* *
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi> * Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru> * ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
* *
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation: * Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
* http://iki.fi/bisqwit/source/adlmidi.html * http://iki.fi/bisqwit/source/adlmidi.html
@ -868,12 +868,14 @@ OPL3::OPL3() :
m_softPanning(false), m_softPanning(false),
m_masterVolume(MasterVolumeDefault), m_masterVolume(MasterVolumeDefault),
m_musicMode(MODE_MIDI), m_musicMode(MODE_MIDI),
m_volumeScale(VOLUME_Generic) m_volumeScale(VOLUME_Generic),
m_channelAlloc(ADLMIDI_ChanAlloc_AUTO)
{ {
m_insBankSetup.volumeModel = OPL3::VOLUME_Generic; m_insBankSetup.volumeModel = OPL3::VOLUME_Generic;
m_insBankSetup.deepTremolo = false; m_insBankSetup.deepTremolo = false;
m_insBankSetup.deepVibrato = false; m_insBankSetup.deepVibrato = false;
m_insBankSetup.scaleModulators = false; m_insBankSetup.scaleModulators = false;
m_insBankSetup.mt32defaults = false;
#ifdef DISABLE_EMBEDDED_BANKS #ifdef DISABLE_EMBEDDED_BANKS
m_embeddedBank = CustomBankTag; m_embeddedBank = CustomBankTag;
@ -913,6 +915,7 @@ void OPL3::setEmbeddedBank(uint32_t bank)
const BanksDump::BankEntry &bankEntry = g_embeddedBanks[m_embeddedBank]; const BanksDump::BankEntry &bankEntry = g_embeddedBanks[m_embeddedBank];
m_insBankSetup.deepTremolo = ((bankEntry.bankSetup >> 8) & 0x01) != 0; m_insBankSetup.deepTremolo = ((bankEntry.bankSetup >> 8) & 0x01) != 0;
m_insBankSetup.deepVibrato = ((bankEntry.bankSetup >> 8) & 0x02) != 0; m_insBankSetup.deepVibrato = ((bankEntry.bankSetup >> 8) & 0x02) != 0;
m_insBankSetup.mt32defaults = ((bankEntry.bankSetup >> 8) & 0x04) != 0;
m_insBankSetup.volumeModel = (bankEntry.bankSetup & 0xFF); m_insBankSetup.volumeModel = (bankEntry.bankSetup & 0xFF);
m_insBankSetup.scaleModulators = false; m_insBankSetup.scaleModulators = false;
@ -1628,6 +1631,7 @@ void OPL3::setVolumeScaleModel(ADLMIDI_VolumeModels volumeModel)
{ {
switch(volumeModel) switch(volumeModel)
{ {
default:
case ADLMIDI_VolumeModel_AUTO://Do nothing until restart playing case ADLMIDI_VolumeModel_AUTO://Do nothing until restart playing
break; break;

View file

@ -2,7 +2,7 @@
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation * libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
* *
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi> * Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru> * ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
* *
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation: * Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
* http://iki.fi/bisqwit/source/adlmidi.html * http://iki.fi/bisqwit/source/adlmidi.html
@ -162,6 +162,9 @@ public:
VOLUME_HMI_OLD VOLUME_HMI_OLD
} m_volumeScale; } m_volumeScale;
//! Channel allocation algorithm
ADLMIDI_ChannelAlloc m_channelAlloc;
//! Reserved //! Reserved
char _padding3[8]; char _padding3[8];

View file

@ -2,7 +2,7 @@
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation * libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
* *
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi> * Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru> * ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
* *
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation: * Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
* http://iki.fi/bisqwit/source/adlmidi.html * http://iki.fi/bisqwit/source/adlmidi.html

View file

@ -2,7 +2,7 @@
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation * libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
* *
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi> * Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru> * ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
* *
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation: * Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
* http://iki.fi/bisqwit/source/adlmidi.html * http://iki.fi/bisqwit/source/adlmidi.html

View file

@ -2,7 +2,7 @@
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation * libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
* *
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi> * Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru> * ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
* *
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation: * Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
* http://iki.fi/bisqwit/source/adlmidi.html * http://iki.fi/bisqwit/source/adlmidi.html

View file

@ -2,7 +2,7 @@
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation * libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
* *
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi> * Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru> * ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
* *
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation: * Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
* http://iki.fi/bisqwit/source/adlmidi.html * http://iki.fi/bisqwit/source/adlmidi.html
@ -21,14 +21,26 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#if !defined(_WIN32) #ifndef DOSBOX_NO_MUTEX
#include <pthread.h> # if defined(USE_LIBOGC_MUTEX)
# include <ogc/mutex.h>
typedef mutex_t MutexNativeObject;
# elif defined(USE_WUT_MUTEX)
# if __cplusplus < 201103L || (defined(_MSC_VER) && _MSC_VER < 1900)
# define static_assert(x, y)
# endif
# include <coreinit/mutex.h>
typedef OSMutex MutexNativeObject;
# elif !defined(_WIN32)
# include <pthread.h>
typedef pthread_mutex_t MutexNativeObject; typedef pthread_mutex_t MutexNativeObject;
#else # else
#include <windows.h> # include <windows.h>
typedef CRITICAL_SECTION MutexNativeObject; typedef CRITICAL_SECTION MutexNativeObject;
# endif
#endif #endif
class Mutex class Mutex
{ {
public: public:
@ -37,7 +49,9 @@ public:
void lock(); void lock();
void unlock(); void unlock();
private: private:
#if !defined(DOSBOX_NO_MUTEX)
MutexNativeObject m; MutexNativeObject m;
#endif
Mutex(const Mutex &); Mutex(const Mutex &);
Mutex &operator=(const Mutex &); Mutex &operator=(const Mutex &);
}; };
@ -53,7 +67,65 @@ private:
MutexHolder &operator=(const MutexHolder &); MutexHolder &operator=(const MutexHolder &);
}; };
#if !defined(_WIN32) #if defined(DOSBOX_NO_MUTEX) // No mutex, just a dummy
inline Mutex::Mutex()
{}
inline Mutex::~Mutex()
{}
inline void Mutex::lock()
{}
inline void Mutex::unlock()
{}
#elif defined(USE_WUT_MUTEX)
inline Mutex::Mutex()
{
OSInitMutex(&m);
}
inline Mutex::~Mutex()
{}
inline void Mutex::lock()
{
OSLockMutex(&m);
}
inline void Mutex::unlock()
{
OSUnlockMutex(&m);
}
#elif defined(USE_LIBOGC_MUTEX)
inline Mutex::Mutex()
{
m = LWP_MUTEX_NULL;
LWP_MutexInit(&m, 0);
}
inline Mutex::~Mutex()
{
LWP_MutexDestroy(m);
}
inline void Mutex::lock()
{
LWP_MutexLock(m);
}
inline void Mutex::unlock()
{
LWP_MutexUnlock(m);
}
#elif !defined(_WIN32) // pthread
inline Mutex::Mutex() inline Mutex::Mutex()
{ {
pthread_mutex_init(&m, NULL); pthread_mutex_init(&m, NULL);
@ -73,7 +145,9 @@ inline void Mutex::unlock()
{ {
pthread_mutex_unlock(&m); pthread_mutex_unlock(&m);
} }
#else
#else // Win32
inline Mutex::Mutex() inline Mutex::Mutex()
{ {
InitializeCriticalSection(&m); InitializeCriticalSection(&m);

View file

@ -2,7 +2,7 @@
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation * libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
* *
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi> * Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru> * ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
* *
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation: * Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
* http://iki.fi/bisqwit/source/adlmidi.html * http://iki.fi/bisqwit/source/adlmidi.html

View file

@ -1,7 +1,7 @@
/* /*
* Interfaces over Yamaha OPL3 (YMF262) chip emulators * Interfaces over Yamaha OPL3 (YMF262) chip emulators
* *
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand) * Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public

View file

@ -1,7 +1,7 @@
/* /*
* Interfaces over Yamaha OPL3 (YMF262) chip emulators * Interfaces over Yamaha OPL3 (YMF262) chip emulators
* *
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand) * Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public

View file

@ -1,7 +1,7 @@
/* /*
* Interfaces over Yamaha OPL3 (YMF262) chip emulators * Interfaces over Yamaha OPL3 (YMF262) chip emulators
* *
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand) * Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public

View file

@ -1,7 +1,7 @@
/* /*
* Interfaces over Yamaha OPL3 (YMF262) chip emulators * Interfaces over Yamaha OPL3 (YMF262) chip emulators
* *
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand) * Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public

View file

@ -1,7 +1,7 @@
/* /*
* Interfaces over Yamaha OPL3 (YMF262) chip emulators * Interfaces over Yamaha OPL3 (YMF262) chip emulators
* *
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand) * Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public

View file

@ -1,7 +1,7 @@
/* /*
* Interfaces over Yamaha OPL3 (YMF262) chip emulators * Interfaces over Yamaha OPL3 (YMF262) chip emulators
* *
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand) * Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public

View file

@ -1,7 +1,7 @@
/* /*
* Interfaces over Yamaha OPL3 (YMF262) chip emulators * Interfaces over Yamaha OPL3 (YMF262) chip emulators
* *
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand) * Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public

View file

@ -1,7 +1,7 @@
/* /*
* Interfaces over Yamaha OPL3 (YMF262) chip emulators * Interfaces over Yamaha OPL3 (YMF262) chip emulators
* *
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand) * Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public

View file

@ -1,7 +1,7 @@
/* /*
* Interfaces over Yamaha OPL3 (YMF262) chip emulators * Interfaces over Yamaha OPL3 (YMF262) chip emulators
* *
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand) * Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public

View file

@ -1,7 +1,7 @@
/* /*
* Interfaces over Yamaha OPL3 (YMF262) chip emulators * Interfaces over Yamaha OPL3 (YMF262) chip emulators
* *
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand) * Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017-2020 Vitaly Novichkov (Wohlstand) * Copyright (c) 2017-2022 Vitaly Novichkov (Wohlstand)
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public

View file

@ -1,7 +1,7 @@
/* /*
* FileAndMemoryReader - a tiny helper to utify file reading from a disk and memory block * FileAndMemoryReader - a tiny helper to utify file reading from a disk and memory block
* *
* Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru> * Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the "Software"), * a copy of this software and associated documentation files (the "Software"),

File diff suppressed because one or more lines are too long

View file

@ -2,7 +2,7 @@
* libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation * libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
* *
* Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi> * Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
* ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru> * ADLMIDI Library API: Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
* *
* Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation: * Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
* http://iki.fi/bisqwit/source/adlmidi.html * http://iki.fi/bisqwit/source/adlmidi.html
@ -106,6 +106,7 @@ struct OplBankSetup
bool deepTremolo; bool deepTremolo;
bool deepVibrato; bool deepVibrato;
bool scaleModulators; bool scaleModulators;
bool mt32defaults;
}; };
/** /**

View file

@ -1,7 +1,7 @@
/* /*
* Wohlstand's OPL3 Bank File - a bank format to store OPL3 timbre data and setup * Wohlstand's OPL3 Bank File - a bank format to store OPL3 timbre data and setup
* *
* Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru> * Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the "Software"), * a copy of this software and associated documentation files (the "Software"),

View file

@ -1,7 +1,7 @@
/* /*
* Wohlstand's OPL3 Bank File - a bank format to store OPL3 timbre data and setup * Wohlstand's OPL3 Bank File - a bank format to store OPL3 timbre data and setup
* *
* Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru> * Copyright (c) 2015-2022 Vitaly Novichkov <admin@wohlnet.ru>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the "Software"), * a copy of this software and associated documentation files (the "Software"),
@ -32,8 +32,22 @@
extern "C" { extern "C" {
#endif #endif
#if !defined(__STDC_VERSION__) || (defined(__STDC_VERSION__) && (__STDC_VERSION__ < 199901L)) \ /* Solaris defines the integer types regardless of what C/C++ standard is actually available,
|| defined(__STRICT_ANSI__) || !defined(__cplusplus) * so avoid defining them at all by ourselves. */
#if !defined(WOPL_STDINT_TYPEDEFS_NOT_NEEDED) && defined(__sun)
# define WOPL_STDINT_TYPEDEFS_NOT_NEEDED
#endif
#if !defined(WOPL_STDINT_TYPEDEFS_NEEDED) && !defined(WOPL_STDINT_TYPEDEFS_NOT_NEEDED)
# if !defined(__STDC_VERSION__) || \
(defined(__STDC_VERSION__) && (__STDC_VERSION__ < 199901L)) || \
defined(__STRICT_ANSI__) || \
!defined(__cplusplus)
# define WOPL_STDINT_TYPEDEFS_NEEDED
# endif
#endif
#ifdef WOPL_STDINT_TYPEDEFS_NEEDED
typedef signed char int8_t; typedef signed char int8_t;
typedef unsigned char uint8_t; typedef unsigned char uint8_t;
typedef signed short int int16_t; typedef signed short int int16_t;
@ -46,7 +60,9 @@ typedef enum WOPLFileFlags
/* Enable Deep-Tremolo flag */ /* Enable Deep-Tremolo flag */
WOPL_FLAG_DEEP_TREMOLO = 0x01, WOPL_FLAG_DEEP_TREMOLO = 0x01,
/* Enable Deep-Vibrato flag */ /* Enable Deep-Vibrato flag */
WOPL_FLAG_DEEP_VIBRATO = 0x02 WOPL_FLAG_DEEP_VIBRATO = 0x02,
/* Enable MT32 defaults (127 initials and octave-wide pitch bend by default, etc.) */
WOPL_FLAG_MT32 = 0x04
} WOPLFileFlags; } WOPLFileFlags;
/* Volume scaling model implemented in the libADLMIDI */ /* Volume scaling model implemented in the libADLMIDI */