From 48ec16f3d2a04295767b6bac38aed7bef5180881 Mon Sep 17 00:00:00 2001 From: Wohlstand Date: Wed, 29 Jun 2022 18:27:00 +0300 Subject: Added the chip channels allocation mode option --- src/adlmidi.cpp | 23 +++++++++++++++++++++++ src/adlmidi_midiplay.cpp | 30 ++++++++++++++++++++++-------- src/adlmidi_opl3.cpp | 4 +++- src/adlmidi_opl3.hpp | 3 +++ 4 files changed, 51 insertions(+), 9 deletions(-) (limited to 'src') 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(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(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]; -- cgit v1.2.3