aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/adlmidi.cpp23
-rw-r--r--src/adlmidi_midiplay.cpp30
-rw-r--r--src/adlmidi_opl3.cpp4
-rw-r--r--src/adlmidi_opl3.hpp3
4 files changed, 51 insertions, 9 deletions
diff --git a/src/adlmidi.cpp b/src/adlmidi.cpp
index 54d839b..a9ec918 100644
--- a/src/adlmidi.cpp
+++ b/src/adlmidi.cpp
@@ -651,6 +651,29 @@ ADLMIDI_EXPORT int adl_getVolumeRangeModel(struct ADL_MIDIPlayer *device)
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)
{
if(device)
diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp
index 3f4adc9..5576e65 100644
--- a/src/adlmidi_midiplay.cpp
+++ b/src/adlmidi_midiplay.cpp
@@ -1348,6 +1348,17 @@ int64_t MIDIplay::calculateChipChannelGoodness(size_t c, const MIDIchannel::Note
const AdlChannel &chan = m_chipChannels[c];
int64_t koff_ms = chan.koff_time_until_neglible_us / 1000;
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
if(s < 0 && chan.users.empty())
@@ -1356,19 +1367,22 @@ int64_t MIDIplay::calculateChipChannelGoodness(size_t c, const MIDIchannel::Note
s -= 40000;
// 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)
s = 0; // Re-use releasing channel with the same instrument
- }
- else if(synth.m_volumeScale == Synth::VOLUME_HMI)
- {
- s = 0; // HMI doesn't care about the same instrument
- }
- else
- {
+ break;
+
+ case ADLMIDI_ChanAlloc_AnyReleased:
+ s = 0; // Re-use any releasing channel
+ break;
+
+ default:
+ case ADLMIDI_ChanAlloc_OffDelay:
if(isSame)
s = -koff_ms; // Wait until releasing sound will complete
+ break;
}
return s;
diff --git a/src/adlmidi_opl3.cpp b/src/adlmidi_opl3.cpp
index dc5644f..e3c627c 100644
--- a/src/adlmidi_opl3.cpp
+++ b/src/adlmidi_opl3.cpp
@@ -868,7 +868,8 @@ OPL3::OPL3() :
m_softPanning(false),
m_masterVolume(MasterVolumeDefault),
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.deepTremolo = false;
@@ -1630,6 +1631,7 @@ void OPL3::setVolumeScaleModel(ADLMIDI_VolumeModels volumeModel)
{
switch(volumeModel)
{
+ default:
case ADLMIDI_VolumeModel_AUTO://Do nothing until restart playing
break;
diff --git a/src/adlmidi_opl3.hpp b/src/adlmidi_opl3.hpp
index f15e413..e36997b 100644
--- a/src/adlmidi_opl3.hpp
+++ b/src/adlmidi_opl3.hpp
@@ -162,6 +162,9 @@ public:
VOLUME_HMI_OLD
} m_volumeScale;
+ //! Channel allocation algorithm
+ ADLMIDI_ChannelAlloc m_channelAlloc;
+
//! Reserved
char _padding3[8];