aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJP Cimalando <jpcima@users.noreply.github.com>2018-08-25 20:19:03 +0200
committerJP Cimalando <jpcima@users.noreply.github.com>2018-08-25 21:24:56 +0200
commit8bd614ddcb75541711ef287880f08c9f49f139b1 (patch)
tree953e7ab0582f53b8f9906ca55e7c331f09a00773 /src
parente8882d58c9c4db8992b0620565e671979cd6a696 (diff)
downloadlibADLMIDI-8bd614ddcb75541711ef287880f08c9f49f139b1.tar.gz
libADLMIDI-8bd614ddcb75541711ef287880f08c9f49f139b1.tar.bz2
libADLMIDI-8bd614ddcb75541711ef287880f08c9f49f139b1.zip
upgrade timing resolution to the microsecond
Diffstat (limited to 'src')
-rw-r--r--src/adlmidi_midiplay.cpp52
-rw-r--r--src/adlmidi_private.hpp22
2 files changed, 37 insertions, 37 deletions
diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp
index ded81b3..fc5a019 100644
--- a/src/adlmidi_midiplay.cpp
+++ b/src/adlmidi_midiplay.cpp
@@ -100,19 +100,19 @@ inline bool isXgPercChannel(uint8_t msb, uint8_t lsb)
return (msb == 0x7E || msb == 0x7F) && (lsb == 0);
}
-void MIDIplay::AdlChannel::addAge(int64_t ms)
+void MIDIplay::AdlChannel::addAge(int64_t us)
{
- const int64_t neg = static_cast<int64_t>(-0x1FFFFFFFl);
+ const int64_t neg = 1000 * static_cast<int64_t>(-0x1FFFFFFFll);
if(users_empty())
- koff_time_until_neglible = std::max(int64_t(koff_time_until_neglible - ms), neg);
+ koff_time_until_neglible_us = std::max(koff_time_until_neglible_us - us, neg);
else
{
- koff_time_until_neglible = 0;
+ koff_time_until_neglible_us = 0;
for(LocationData *i = users_first; i; i = i->next)
{
if(!i->fixed_sustain)
- i->kon_time_until_neglible = std::max(i->kon_time_until_neglible - ms, neg);
- i->vibdelay += ms;
+ i->kon_time_until_neglible_us = std::max(i->kon_time_until_neglible_us - us, neg);
+ i->vibdelay_us += us;
}
}
}
@@ -233,7 +233,7 @@ void MIDIplay::resetMIDI()
void MIDIplay::TickIterators(double s)
{
for(uint16_t c = 0; c < m_synth.m_numChannels; ++c)
- m_chipChannels[c].addAge(static_cast<int64_t>(s * 1000.0));
+ m_chipChannels[c].addAge(static_cast<int64_t>(s * 1e6));
updateVibrato(s);
updateArpeggio(s);
#if !defined(ADLMIDI_AUDIO_TICK_HANDLER)
@@ -1113,9 +1113,9 @@ void MIDIplay::noteUpdate(size_t midCh,
if(d) // inserts if necessary
{
d->sustained = AdlChannel::LocationData::Sustain_None;
- d->vibdelay = 0;
+ d->vibdelay_us = 0;
d->fixed_sustain = (ains.ms_sound_kon == static_cast<uint16_t>(adlNoteOnMaxTime));
- d->kon_time_until_neglible = ains.ms_sound_kon;
+ d->kon_time_until_neglible_us = 1000 * ains.ms_sound_kon;
d->ins = ins;
}
}
@@ -1147,11 +1147,11 @@ void MIDIplay::noteUpdate(size_t midCh,
if(props_mask & Upd_Mute) // Mute the note
{
m_synth.touchNote(c, 0);
- m_chipChannels[c].koff_time_until_neglible = 0;
+ m_chipChannels[c].koff_time_until_neglible_us = 0;
}
else
{
- m_chipChannels[c].koff_time_until_neglible = ains.ms_sound_koff;
+ m_chipChannels[c].koff_time_until_neglible_us = 1000 * ains.ms_sound_koff;
}
}
}
@@ -1279,7 +1279,7 @@ void MIDIplay::noteUpdate(size_t midCh,
phase = ains.voice2_fine_tune;//0.125; // Detune the note slightly (this is what Doom does)
}
- if(vibrato && (!d || d->vibdelay >= m_midiChannels[midCh].vibdelay))
+ if(vibrato && (!d || d->vibdelay_us >= m_midiChannels[midCh].vibdelay_us))
bend += static_cast<double>(vibrato) * m_midiChannels[midCh].vibdepth * std::sin(m_midiChannels[midCh].vibpos);
#define BEND_COEFFICIENT 172.4387
@@ -1321,7 +1321,8 @@ void MIDIplay::setErrorString(const std::string &err)
int64_t MIDIplay::calculateChipChannelGoodness(size_t c, const MIDIchannel::NoteInfo::Phys &ins) const
{
- int64_t s = (m_synth.m_musicMode != OPL3::MODE_CMF) ? -m_chipChannels[c].koff_time_until_neglible : 0;
+ 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;
// Same midi-instrument = some stability
//if(c == MidCh) s += 4;
@@ -1329,10 +1330,9 @@ int64_t MIDIplay::calculateChipChannelGoodness(size_t c, const MIDIchannel::Note
{
s -= 4000;
- if(j->sustained == AdlChannel::LocationData::Sustain_None)
- s -= j->kon_time_until_neglible;
- else
- s -= (j->kon_time_until_neglible / 2);
+ int64_t kon_ms = j->kon_time_until_neglible_us / 1000;
+ s -= (j->sustained == AdlChannel::LocationData::Sustain_None) ?
+ kon_ms : (kon_ms / 2);
MIDIchannel::activenoteiterator
k = const_cast<MIDIchannel &>(m_midiChannels[j->loc.MidCh]).activenotes_find(j->loc.note);
@@ -1344,8 +1344,8 @@ int64_t MIDIplay::calculateChipChannelGoodness(size_t c, const MIDIchannel::Note
{
s += 300;
// Arpeggio candidate = even better
- if(j->vibdelay < 70
- || j->kon_time_until_neglible > 20000)
+ if(j->vibdelay_us < 70000
+ || j->kon_time_until_neglible_us > 20000000)
s += 0;
}
@@ -1376,7 +1376,7 @@ int64_t MIDIplay::calculateChipChannelGoodness(size_t c, const MIDIchannel::Note
for(AdlChannel::LocationData *m = m_chipChannels[c2].users_first; m; m = m->next)
{
if(m->sustained != AdlChannel::LocationData::Sustain_None) continue;
- if(m->vibdelay >= 200) continue;
+ if(m->vibdelay_us >= 200000) continue;
if(m->ins != j->ins) continue;
n_evacuation_stations += 1;
}
@@ -1407,8 +1407,8 @@ void MIDIplay::prepareChipChannelForNewNote(size_t c, const MIDIchannel::NoteInf
(m_midiChannels[j->loc.MidCh].activenotes_ensure_find(j->loc.note));
// Check if we can do arpeggio.
- if((j->vibdelay < 70
- || j->kon_time_until_neglible > 20000)
+ if((j->vibdelay_us < 70000
+ || j->kon_time_until_neglible_us > 20000000)
&& j->ins == ins)
{
// Do arpeggio together with this note.
@@ -1458,8 +1458,8 @@ void MIDIplay::killOrEvacuate(size_t from_channel,
for(AdlChannel::LocationData *m = adlch.users_first; m; m = m->next)
{
- if(m->vibdelay >= 200
- && m->kon_time_until_neglible < 10000) continue;
+ if(m->vibdelay_us >= 200000
+ && m->kon_time_until_neglible_us < 10000000) continue;
if(m->ins != j->ins)
continue;
if(hooks.onNote)
@@ -1596,7 +1596,7 @@ void MIDIplay::setRPN(size_t midCh, unsigned value, bool MSB)
case 0x010A + 1*0x10000 + 1*0x20000:
if((m_synthMode & Mode_XG) != 0) // Vibrato delay in millisecons
{
- m_midiChannels[midCh].vibdelay = value ? int64_t(0.2092 * std::exp(0.0795 * (double)value)) : 0;
+ m_midiChannels[midCh].vibdelay_us = value ? int64_t(209.2 * std::exp(0.0795 * (double)value)) : 0;
}
break;
default:/* UI.PrintLn("%s %04X <- %d (%cSB) (ch %u)",
@@ -1702,7 +1702,7 @@ retry_arpeggio:
if(i->sustained == AdlChannel::LocationData::Sustain_None)
{
- if(i->kon_time_until_neglible <= 0l)
+ if(i->kon_time_until_neglible_us <= 0)
{
noteUpdate(
i->loc.MidCh,
diff --git a/src/adlmidi_private.hpp b/src/adlmidi_private.hpp
index f719f01..0b7994a 100644
--- a/src/adlmidi_private.hpp
+++ b/src/adlmidi_private.hpp
@@ -558,7 +558,7 @@ public:
//! Vibrato depth value
vibdepth;
//! Vibrato delay time
- int64_t vibdelay;
+ int64_t vibdelay_us;
//! Last LSB part of RPN value received
uint8_t lastlrpn,
//! Last MSB poart of RPN value received
@@ -801,7 +801,7 @@ public:
noteAfterTouchInUse = false;
vibspeed = 2 * 3.141592653 * 5.0;
vibdepth = 0.5 / 127;
- vibdelay = 0;
+ vibdelay_us = 0;
panning = 64;
portamento = 0;
portamentoEnable = false;
@@ -866,12 +866,12 @@ public:
//! Has fixed sustain, don't iterate "on" timeout
bool fixed_sustain;
//! Timeout until note will be allowed to be killed by channel manager while it is on
- int64_t kon_time_until_neglible;
- int64_t vibdelay;
+ int64_t kon_time_until_neglible_us;
+ int64_t vibdelay_us;
};
//! Time left until sounding will be muted after key off
- int64_t koff_time_until_neglible;
+ int64_t koff_time_until_neglible_us;
enum { users_max = 128 };
LocationData *users_first, *users_free_cells;
@@ -888,12 +888,12 @@ public:
void users_assign(const LocationData *users, size_t count);
// For channel allocation:
- AdlChannel(): koff_time_until_neglible(0)
+ AdlChannel(): koff_time_until_neglible_us(0)
{
users_clear();
}
- AdlChannel(const AdlChannel &oth): koff_time_until_neglible(oth.koff_time_until_neglible)
+ AdlChannel(const AdlChannel &oth): koff_time_until_neglible_us(oth.koff_time_until_neglible_us)
{
if(oth.users_first)
{
@@ -906,16 +906,16 @@ public:
AdlChannel &operator=(const AdlChannel &oth)
{
- koff_time_until_neglible = oth.koff_time_until_neglible;
+ koff_time_until_neglible_us = oth.koff_time_until_neglible_us;
users_assign(oth.users_first, oth.users_size);
return *this;
}
/**
- * @brief Increases age of active note in milliseconds time
- * @param ms Amount time in milliseconds
+ * @brief Increases age of active note in microseconds time
+ * @param us Amount time in microseconds
*/
- void addAge(int64_t ms);
+ void addAge(int64_t us);
};
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER