aboutsummaryrefslogtreecommitdiff
path: root/src/adlmidi_midiplay.cpp
diff options
context:
space:
mode:
authorWohlstand <admin@wohlnet.ru>2018-10-01 12:38:32 +0300
committerWohlstand <admin@wohlnet.ru>2018-10-01 12:38:32 +0300
commit75daca694c01156dc447993060b1b285f3db3056 (patch)
tree0e70115d0e506d64b1e5d6abab054019c7e78bbb /src/adlmidi_midiplay.cpp
parentd9e1a993d5b8cbeae4f2db5bce81147c3dc42fa7 (diff)
parent314cde9fccb603bbd2b36b58dc9b3020c160ac4b (diff)
downloadlibADLMIDI-75daca694c01156dc447993060b1b285f3db3056.tar.gz
libADLMIDI-75daca694c01156dc447993060b1b285f3db3056.tar.bz2
libADLMIDI-75daca694c01156dc447993060b1b285f3db3056.zip
Merge branch 'master' of github.com:Wohlstand/libADLMIDI into stable
Diffstat (limited to 'src/adlmidi_midiplay.cpp')
-rw-r--r--src/adlmidi_midiplay.cpp41
1 files changed, 31 insertions, 10 deletions
diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp
index 42b5b01..1e1da07 100644
--- a/src/adlmidi_midiplay.cpp
+++ b/src/adlmidi_midiplay.cpp
@@ -104,7 +104,11 @@ void MIDIplay::AdlChannel::addAge(int64_t us)
{
const int64_t neg = 1000 * static_cast<int64_t>(-0x1FFFFFFFll);
if(users_empty())
+ {
koff_time_until_neglible_us = std::max(koff_time_until_neglible_us - us, neg);
+ if(koff_time_until_neglible_us < 0)
+ koff_time_until_neglible_us = 0;
+ }
else
{
koff_time_until_neglible_us = 0;
@@ -137,7 +141,7 @@ MIDIplay::MIDIplay(unsigned long sampleRate):
m_setup.maxdelay = 512.0 / (double)m_setup.PCM_RATE;
m_setup.bankId = 0;
- m_setup.numFourOps = 7;
+ m_setup.numFourOps = -1;
m_setup.numChips = 2;
m_setup.deepTremoloMode = -1;
m_setup.deepVibratoMode = -1;
@@ -194,9 +198,13 @@ void MIDIplay::applySetup()
m_synth.m_volumeScale = (OPL3::VolumesScale)m_synth.m_insBankSetup.volumeModel;
m_synth.m_numChips = m_setup.numChips;
- m_synth.m_numFourOps = m_setup.numFourOps;
m_cmfPercussionMode = false;
+ if(m_setup.numFourOps >= 0)
+ m_synth.m_numFourOps = m_setup.numFourOps;
+ else
+ adlCalculateFourOpChannels(this, true);
+
m_synth.reset(m_setup.emulator, m_setup.PCM_RATE, this);
m_chipChannels.clear();
m_chipChannels.resize(m_synth.m_numChannels);
@@ -584,6 +592,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
int32_t c = adlchannel[ccount];
if(c < 0)
continue;
+ m_chipChannels[c].recent_ins = voices[ccount];
m_chipChannels[c].addAge(0);
}
@@ -1161,7 +1170,7 @@ void MIDIplay::noteUpdate(size_t midCh,
}
else
{
- m_chipChannels[c].koff_time_until_neglible_us = 1000 * ains.ms_sound_koff;
+ m_chipChannels[c].koff_time_until_neglible_us = 1000 * int64_t(ains.ms_sound_koff);
}
}
}
@@ -1331,14 +1340,24 @@ void MIDIplay::setErrorString(const std::string &err)
int64_t MIDIplay::calculateChipChannelGoodness(size_t c, const MIDIchannel::NoteInfo::Phys &ins) const
{
- int64_t koff_ms = m_chipChannels[c].koff_time_until_neglible_us / 1000;
- int64_t s = (m_synth.m_musicMode != OPL3::MODE_CMF) ? -koff_ms : 0;
+ const AdlChannel &chan = m_chipChannels[c];
+ int64_t koff_ms = chan.koff_time_until_neglible_us / 1000;
+ int64_t s = -koff_ms;
+
+ // Rate channel with a releasing note
+ if(s < 0 && chan.users_empty())
+ {
+ s -= 40000;
+ // If it's same instrument, better chance to get it when no free channels
+ if(chan.recent_ins == ins)
+ s = (m_synth.m_musicMode == OPL3::MODE_CMF) ? 0 : -koff_ms;
+ return s;
+ }
// Same midi-instrument = some stability
- //if(c == MidCh) s += 4;
- for(AdlChannel::LocationData *j = m_chipChannels[c].users_first; j; j = j->next)
+ for(AdlChannel::LocationData *j = chan.users_first; j; j = j->next)
{
- s -= 4000;
+ s -= 4000000;
int64_t kon_ms = j->kon_time_until_neglible_us / 1000;
s -= (j->sustained == AdlChannel::LocationData::Sustain_None) ?
@@ -1356,7 +1375,7 @@ int64_t MIDIplay::calculateChipChannelGoodness(size_t c, const MIDIchannel::Note
// Arpeggio candidate = even better
if(j->vibdelay_us < 70000
|| j->kon_time_until_neglible_us > 20000000)
- s += 0;
+ s += 10;
}
// Percussion is inferior to melody
@@ -1446,6 +1465,8 @@ void MIDIplay::killOrEvacuate(size_t from_channel,
AdlChannel::LocationData *j,
MIDIplay::MIDIchannel::activenoteiterator i)
{
+ uint32_t maxChannels = ADL_MAX_CHIPS * 18;
+
// Before killing the note, check if it can be
// evacuated to another channel as an arpeggio
// instrument. This helps if e.g. all channels
@@ -1455,7 +1476,7 @@ void MIDIplay::killOrEvacuate(size_t from_channel,
{
uint16_t cs = static_cast<uint16_t>(c);
- if(c > std::numeric_limits<uint32_t>::max())
+ if(c >= maxChannels)
break;
if(c == from_channel)
continue;