aboutsummaryrefslogtreecommitdiff
path: root/src/adlmidi_midiplay.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/adlmidi_midiplay.cpp')
-rw-r--r--src/adlmidi_midiplay.cpp506
1 files changed, 281 insertions, 225 deletions
diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp
index 7c40fa0..0623ce7 100644
--- a/src/adlmidi_midiplay.cpp
+++ b/src/adlmidi_midiplay.cpp
@@ -25,7 +25,7 @@
// Mapping from MIDI volume level to OPL level value.
-static const uint32_t DMX_volume_mapping_table[] =
+static const uint8_t DMX_volume_mapping_table[128] =
{
0, 1, 3, 5, 6, 8, 10, 11,
13, 14, 16, 17, 19, 20, 22, 23,
@@ -43,23 +43,6 @@ static const uint32_t DMX_volume_mapping_table[] =
116, 117, 117, 118, 118, 119, 119, 120,
120, 121, 121, 122, 122, 123, 123, 123,
124, 124, 125, 125, 126, 126, 127, 127,
- //Protection entries to avoid crash if value more than 127
- 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127,
};
static const uint8_t W9X_volume_mapping_table[32] =
@@ -117,17 +100,16 @@ inline bool isXgPercChannel(uint8_t msb, uint8_t lsb)
void MIDIplay::AdlChannel::AddAge(int64_t ms)
{
+ const int64_t neg = static_cast<int64_t>(-0x1FFFFFFFl);
if(users_empty())
- koff_time_until_neglible =
- std::max(int64_t(koff_time_until_neglible - ms), static_cast<int64_t>(-0x1FFFFFFFl));
+ koff_time_until_neglible = std::max(int64_t(koff_time_until_neglible - ms), neg);
else
{
koff_time_until_neglible = 0;
-
for(LocationData *i = users_first; i; i = i->next)
{
- i->kon_time_until_neglible =
- std::max(i->kon_time_until_neglible - ms, static_cast<int64_t>(-0x1FFFFFFFl));
+ if(!i->fixed_sustain)
+ i->kon_time_until_neglible = std::max(i->kon_time_until_neglible - ms, neg);
i->vibdelay += ms;
}
}
@@ -222,7 +204,9 @@ void MIDIplay::MidiTrackRow::sortEvents(bool *noteStates)
j = noteOffs.erase(j);
markAsOn.erase(note_i);
continue;
- } else {
+ }
+ else
+ {
//When same row has many note-offs on same row
//that means a zero-length note follows previous note
//it must be shuted down
@@ -451,17 +435,17 @@ bool MIDIplay::buildTrackData()
if(track.empty())
continue;//Empty track is useless!
- #ifdef DEBUG_TIME_CALCULATION
+#ifdef DEBUG_TIME_CALCULATION
std::fprintf(stdout, "\n============Track %" PRIuPTR "=============\n", tk);
std::fflush(stdout);
- #endif
+#endif
MidiTrackRow *posPrev = &(*(track.begin()));//First element
for(MidiTrackQueue::iterator it = track.begin(); it != track.end(); it++)
{
- #ifdef DEBUG_TIME_CALCULATION
+#ifdef DEBUG_TIME_CALCULATION
bool tempoChanged = false;
- #endif
+#endif
MidiTrackRow &pos = *it;
if((posPrev != &pos) && //Skip first event
(!tempos.empty()) && //Only when in-track tempo events are available
@@ -507,9 +491,9 @@ bool MIDIplay::buildTrackData()
//Apply next tempo
currentTempo = points[j].tempo;
- #ifdef DEBUG_TIME_CALCULATION
+#ifdef DEBUG_TIME_CALCULATION
tempoChanged = true;
- #endif
+#endif
}
//Then calculate time between last tempo change point and end point
TempoChangePoint tailTempo = points.back();
@@ -552,10 +536,10 @@ bool MIDIplay::buildTrackData()
loopEndTime = pos.time;
}
- #ifdef DEBUG_TIME_CALCULATION
+#ifdef DEBUG_TIME_CALCULATION
std::fprintf(stdout, "= %10" PRId64 " = %10f%s\n", pos.absPos, pos.time, tempoChanged ? " <----TEMPO CHANGED" : "");
std::fflush(stdout);
- #endif
+#endif
abs_position += pos.delay;
posPrev = &pos;
@@ -575,7 +559,7 @@ bool MIDIplay::buildTrackData()
//Resolve "hell of all times" of too short drum notes:
//move too short percussion note-offs far far away as possible
/********************************************************************************/
- #if 1 //Use this to record WAVEs for comparison before/after implementing of this
+#if 1 //Use this to record WAVEs for comparison before/after implementing of this
if(opl.m_musicMode == OPL3::MODE_MIDI)//Percussion fix is needed for MIDI only, not for IMF/RSXX or CMF
{
//! Minimal real time in seconds
@@ -625,8 +609,8 @@ bool MIDIplay::buildTrackData()
}
bool percussion = (et->channel == 9) ||
- banks[et->channel] == 0x7E00 || //XG SFX1/SFX2 channel (16128 signed decimal)
- banks[et->channel] == 0x7F00; //XG Percussion channel (16256 signed decimal)
+ banks[et->channel] == 0x7E00 || //XG SFX1/SFX2 channel (16128 signed decimal)
+ banks[et->channel] == 0x7F00; //XG Percussion channel (16256 signed decimal)
if(!percussion)
continue;
@@ -687,7 +671,7 @@ bool MIDIplay::buildTrackData()
#undef DRUM_NOTE_MIN_TIME
#undef DRUM_NOTE_MIN_TICKS
}
- #endif
+#endif
return true;
}
@@ -695,7 +679,8 @@ bool MIDIplay::buildTrackData()
MIDIplay::MIDIplay(unsigned long sampleRate):
- cmf_percussion_mode(false)
+ cmf_percussion_mode(false),
+ m_arpeggioCounter(0)
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
, fullSongTimeLength(0.0),
postSongWaitDelay(1.0),
@@ -740,16 +725,28 @@ MIDIplay::MIDIplay(unsigned long sampleRate):
void MIDIplay::applySetup()
{
m_setup.tick_skip_samples_delay = 0;
- opl.HighTremoloMode = m_setup.HighTremoloMode == -1 ? adlbanksetup[m_setup.AdlBank].deepTremolo : (bool)m_setup.HighTremoloMode;
- opl.HighVibratoMode = m_setup.HighVibratoMode == -1 ? adlbanksetup[m_setup.AdlBank].deepVibrato : (bool)m_setup.HighVibratoMode;
- opl.AdlPercussionMode = m_setup.AdlPercussionMode == -1 ? adlbanksetup[m_setup.AdlBank].adLibPercussions : (bool)m_setup.AdlPercussionMode;
- opl.ScaleModulators = m_setup.ScaleModulators == -1 ? adlbanksetup[m_setup.AdlBank].scaleModulators : (bool)m_setup.ScaleModulators;
- opl.LogarithmicVolumes = m_setup.LogarithmicVolumes;
- //opl.CartoonersVolumes = false;
+
+ if(opl.AdlBank != ~0u)
+ opl.dynamic_bank_setup = adlbanksetup[m_setup.AdlBank];
+
+ opl.HighTremoloMode = m_setup.HighTremoloMode < 0 ?
+ opl.dynamic_bank_setup.deepTremolo :
+ (m_setup.HighTremoloMode != 0);
+ opl.HighVibratoMode = m_setup.HighVibratoMode < 0 ?
+ opl.dynamic_bank_setup.deepVibrato :
+ (m_setup.HighVibratoMode != 0);
+ opl.AdlPercussionMode = m_setup.AdlPercussionMode < 0 ?
+ opl.dynamic_bank_setup.adLibPercussions :
+ (m_setup.AdlPercussionMode != 0);
+ opl.ScaleModulators = m_setup.ScaleModulators < 0 ?
+ opl.dynamic_bank_setup.scaleModulators :
+ (m_setup.ScaleModulators != 0);
+ if(m_setup.LogarithmicVolumes)
+ opl.ChangeVolumeRangesModel(ADLMIDI_VolumeModel_NativeOPL3);
opl.m_musicMode = OPL3::MODE_MIDI;
opl.ChangeVolumeRangesModel(static_cast<ADLMIDI_VolumeModels>(m_setup.VolumeModel));
if(m_setup.VolumeModel == ADLMIDI_VolumeModel_AUTO)//Use bank default volume model
- opl.m_volumeScale = (OPL3::VolumesScale)adlbanksetup[m_setup.AdlBank].volumeModel;
+ opl.m_volumeScale = (OPL3::VolumesScale)opl.dynamic_bank_setup.volumeModel;
opl.NumCards = m_setup.NumCards;
opl.NumFourOps = m_setup.NumFourOps;
@@ -758,6 +755,9 @@ void MIDIplay::applySetup()
opl.Reset(m_setup.emulator, m_setup.PCM_RATE);
ch.clear();
ch.resize(opl.NumChannels);
+
+ // Reset the arpeggio counter
+ m_arpeggioCounter = 0;
}
#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
@@ -796,9 +796,9 @@ uint64_t MIDIplay::ReadVarLenEx(uint8_t **ptr, uint8_t *end, bool &ok)
double MIDIplay::Tick(double s, double granularity)
{
s *= tempoMultiplier;
- #ifdef ENABLE_BEGIN_SILENCE_SKIPPING
+#ifdef ENABLE_BEGIN_SILENCE_SKIPPING
if(CurrentPositionNew.began)
- #endif
+#endif
CurrentPositionNew.wait -= s;
CurrentPositionNew.absTimePosition += s;
@@ -827,7 +827,7 @@ double MIDIplay::Tick(double s, double granularity)
return CurrentPositionNew.wait;
}
-#endif
+#endif /* ADLMIDI_DISABLE_MIDI_SEQUENCER */
void MIDIplay::TickIteratos(double s)
{
@@ -944,7 +944,7 @@ void MIDIplay::setTempo(double tempo)
{
tempoMultiplier = tempo;
}
-#endif
+#endif /* ADLMIDI_DISABLE_MIDI_SEQUENCER */
void MIDIplay::realTime_ResetState()
{
@@ -964,6 +964,9 @@ void MIDIplay::realTime_ResetState()
bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
{
+ if(note >= 128)
+ note = 127;
+
if((opl.m_musicMode == OPL3::MODE_RSXX) && (velocity != 0))
{
// Check if this is just a note after-touch
@@ -986,14 +989,16 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
if(velocity == 0)
return false;
- size_t midiins = Ch[channel].patch;
- bool isPercussion = (channel % 16 == 9);
+ MIDIchannel &midiChan = Ch[channel];
+
+ size_t midiins = midiChan.patch;
+ bool isPercussion = (channel % 16 == 9);
bool isXgPercussion = false;
uint16_t bank = 0;
- if(Ch[channel].bank_msb || Ch[channel].bank_lsb)
+ if(midiChan.bank_msb || midiChan.bank_lsb)
{
- bank = (uint16_t(Ch[channel].bank_msb) * 256) + uint16_t(Ch[channel].bank_lsb);
+ bank = (uint16_t(midiChan.bank_msb) * 256) + uint16_t(midiChan.bank_lsb);
//0x7E00 - XG SFX1/SFX2 channel (16128 signed decimal)
//0x7F00 - XG Percussion channel (16256 signed decimal)
if(bank == 0x7E00 || bank == 0x7F00)
@@ -1001,7 +1006,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
//Let XG SFX1/SFX2 bank will have LSB==1 (128...255 range in WOPN file)
//Let XG Percussion bank will use (0...127 range in WOPN file)
bank = (uint16_t)midiins + ((bank == 0x7E00) ? 128 : 0); // MIDI instrument defines the patch
- midiins = opl.dynamic_percussion_offset + note; // Percussion instrument
+ midiins = note; // Percussion instrument
isXgPercussion = true;
isPercussion = false;
}
@@ -1010,43 +1015,43 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
if(isPercussion)
{
bank = (uint16_t)midiins; // MIDI instrument defines the patch
- midiins = opl.dynamic_percussion_offset + note; // Percussion instrument
+ midiins = note; // Percussion instrument
}
+ if(isPercussion || isXgPercussion)
+ bank += OPL3::PercussionTag;
+
+ const adlinsdata2 *ains = &OPL3::emptyInstrument;
//Set bank bank
- if(bank > 0)
+ const OPL3::Bank *bnk = NULL;
+ if((bank & ~(uint16_t)OPL3::PercussionTag) > 0)
{
- if(isPercussion || isXgPercussion)
- {
- OPL3::BankMap::iterator b = opl.dynamic_percussion_banks.find(bank);
- if(b != opl.dynamic_percussion_banks.end())
- midiins += b->second * 128;
- else
- if(hooks.onDebugMessage)
- {
- if(!caugh_missing_banks_melodic.count(bank))
- {
- hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing percussion MIDI bank %i (patch %i)", channel, bank, midiins);
- caugh_missing_banks_melodic.insert(bank);
- }
- }
- }
- else
+ OPL3::BankMap::iterator b = opl.dynamic_banks.find(bank);
+ if(b != opl.dynamic_banks.end())
+ bnk = &b->second;
+
+ if(bnk)
+ ains = &bnk->ins[midiins];
+ else if(hooks.onDebugMessage)
{
- OPL3::BankMap::iterator b = opl.dynamic_melodic_banks.find(bank);
- if(b != opl.dynamic_melodic_banks.end())
- midiins += b->second * 128;
- else
- if(hooks.onDebugMessage)
- {
- if(!caugh_missing_banks_percussion.count(bank))
- {
- hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing melodic MIDI bank %i (patch %i)", channel, bank, midiins);
- caugh_missing_banks_percussion.insert(bank);
- }
- }
+ std::set<uint16_t> &missing = (isPercussion || isXgPercussion) ?
+ caugh_missing_banks_percussion : caugh_missing_banks_melodic;
+ const char *text = (isPercussion || isXgPercussion) ?
+ "percussion" : "melodic";
+ if(missing.insert(bank).second)
+ hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing %s MIDI bank %i (patch %i)", channel, text, bank, midiins);
}
}
+ //Or fall back to first bank
+ if(ains->flags & adlinsdata::Flag_NoSound)
+ {
+ OPL3::BankMap::iterator b = opl.dynamic_banks.find(bank & OPL3::PercussionTag);
+ if(b != opl.dynamic_banks.end())
+ bnk = &b->second;
+
+ if(bnk)
+ ains = &bnk->ins[midiins];
+ }
/*
if(MidCh%16 == 9 || (midiins != 32 && midiins != 46 && midiins != 48 && midiins != 50))
@@ -1057,8 +1062,6 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
//if(midiins == 56) vol = vol*6/10; // HACK
//int meta = banks[opl.AdlBank][midiins];
- size_t meta = opl.GetAdlMetaNumber(midiins);
- const adlinsdata *ains = &opl.GetAdlMetaIns(meta);
int16_t tone = note;
if(!isPercussion && !isXgPercussion && (bank > 0)) // For non-zero banks
@@ -1067,23 +1070,18 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
{
if(hooks.onDebugMessage)
{
- if(!caugh_missing_instruments.count(static_cast<uint8_t>(midiins)))
- {
+ if(caugh_missing_instruments.insert(static_cast<uint8_t>(midiins)).second)
hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Caugh a blank instrument %i (offset %i) in the MIDI bank %u", channel, Ch[channel].patch, midiins, bank);
- caugh_missing_instruments.insert(static_cast<uint8_t>(midiins));
- }
}
bank = 0;
- midiins = Ch[channel].patch;
- meta = opl.GetAdlMetaNumber(midiins);
- ains = &opl.GetAdlMetaIns(meta);
+ midiins = midiChan.patch;
}
}
if(ains->tone)
{
- /*if(ains.tone < 20)
- tone += ains.tone;
+ /*if(ains->tone < 20)
+ tone += ains->tone;
else*/
if(ains->tone < 128)
tone = ains->tone;
@@ -1091,24 +1089,32 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
tone -= ains->tone - 128;
}
- //uint16_t i[2] = { ains.adlno1, ains.adlno2 };
+ //uint16_t i[2] = { ains->adlno1, ains->adlno2 };
bool pseudo_4op = ains->flags & adlinsdata::Flag_Pseudo4op;
+#ifndef __WATCOMC__
MIDIchannel::NoteInfo::Phys voices[MIDIchannel::NoteInfo::MaxNumPhysChans] =
{
- {0, ains->adlno1, false},
- {0, ains->adlno2, pseudo_4op}
+ {0, ains->adl[0], false},
+ {0, ains->adl[1], pseudo_4op}
};
+#else /* Unfortunately, WatCom can't brace-initialize structure that incluses structure fields */
+ MIDIchannel::NoteInfo::Phys voices[MIDIchannel::NoteInfo::MaxNumPhysChans];
+ voices[0].chip_chan = 0;
+ voices[0].ains = ains->adl[0];
+ voices[0].pseudo4op = false;
+ voices[1].chip_chan = 0;
+ voices[1].ains = ains->adl[1];
+ voices[1].pseudo4op = pseudo_4op;
+#endif /* __WATCOMC__ */
if((opl.AdlPercussionMode == 1) && PercussionMap[midiins & 0xFF])
voices[1] = voices[0];//i[1] = i[0];
if(hooks.onDebugMessage)
{
- if(!caugh_missing_instruments.count(static_cast<uint8_t>(midiins)) && (ains->flags & adlinsdata::Flag_NoSound))
- {
+ if((ains->flags & adlinsdata::Flag_NoSound) &&
+ caugh_missing_instruments.insert(static_cast<uint8_t>(midiins)).second)
hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing instrument %i", channel, midiins);
- caugh_missing_instruments.insert(static_cast<uint8_t>(midiins));
- }
}
// Allocate AdLib channel (the physical sound channel for the note)
@@ -1132,7 +1138,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
if(ccount == 1 && static_cast<int32_t>(a) == adlchannel[0]) continue;
// ^ Don't use the same channel for primary&secondary
- if(voices[0].insId == voices[1].insId || pseudo_4op/*i[0] == i[1] || pseudo_4op*/)
+ if(voices[0].ains == voices[1].ains || pseudo_4op/*i[0] == i[1] || pseudo_4op*/)
{
// Only use regular channels
uint8_t expected_mode = 0;
@@ -1177,7 +1183,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
if(hooks.onDebugMessage)
hooks.onDebugMessage(hooks.onDebugMessage_userData,
"ignored unplaceable note [bank %i, inst %i, note %i, MIDI channel %i]",
- bank, Ch[channel].patch, note, channel);
+ bank, midiChan.patch, note, channel);
continue; // Could not play this note. Ignore it.
}
@@ -1196,11 +1202,12 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
// Allocate active note for MIDI channel
std::pair<MIDIchannel::activenoteiterator, bool>
- ir = Ch[channel].activenotes_insert(note);
+ ir = midiChan.activenotes_insert(note);
ir.first->vol = velocity;
+ ir.first->vibrato = midiChan.noteAftertouch[note];
ir.first->tone = tone;
ir.first->midiins = midiins;
- ir.first->insmeta = meta;
+ ir.first->ains = ains;
ir.first->chip_channels_count = 0;
for(unsigned ccount = 0; ccount < MIDIchannel::NoteInfo::MaxNumPhysChans; ++ccount)
@@ -1224,29 +1231,28 @@ void MIDIplay::realTime_NoteOff(uint8_t channel, uint8_t note)
void MIDIplay::realTime_NoteAfterTouch(uint8_t channel, uint8_t note, uint8_t atVal)
{
channel = channel % 16;
- MIDIchannel::activenoteiterator
- i = Ch[channel].activenotes_find(note);
- if(!i)
+ MIDIchannel &chan = Ch[channel];
+ MIDIchannel::activenoteiterator i = Ch[channel].activenotes_find(note);
+ if(i)
{
- // Ignore touch if note is not active
- return;
+ i->vibrato = atVal;
+ }
+
+ uint8_t oldAtVal = chan.noteAftertouch[note % 128];
+ if(atVal != oldAtVal)
+ {
+ chan.noteAftertouch[note % 128] = atVal;
+ bool inUse = atVal != 0;
+ for(unsigned n = 0; !inUse && n < 128; ++n)
+ inUse = chan.noteAftertouch[n] != 0;
+ chan.noteAfterTouchInUse = inUse;
}
- i->vol = 127 - atVal;
- NoteUpdate(channel, i, Upd_Volume);
}
void MIDIplay::realTime_ChannelAfterTouch(uint8_t channel, uint8_t atVal)
{
- // TODO: Verify, is this correct action?
channel = channel % 16;
- for(MIDIchannel::activenoteiterator
- i = Ch[channel].activenotes_begin(); i; ++i)
- {
- // Set this pressure to all active notes on the channel
- i->vol = 127 - atVal;
- }
-
- NoteUpdate_All(channel, Upd_Volume);
+ Ch[channel].aftertouch = atVal;
}
void MIDIplay::realTime_Controller(uint8_t channel, uint8_t type, uint8_t value)
@@ -1393,14 +1399,14 @@ void MIDIplay::realTime_PatchChange(uint8_t channel, uint8_t patch)
void MIDIplay::realTime_PitchBend(uint8_t channel, uint16_t pitch)
{
channel = channel % 16;
- Ch[channel].bend = (uint32_t(pitch) - 8192) * Ch[channel].bendsense;
+ Ch[channel].bend = int(pitch) - 8192;
NoteUpdate_All(channel, Upd_Pitch);
}
void MIDIplay::realTime_PitchBend(uint8_t channel, uint8_t msb, uint8_t lsb)
{
channel = channel % 16;
- Ch[channel].bend = (int(lsb) + int(msb) * 128 - 8192) * Ch[channel].bendsense;
+ Ch[channel].bend = int(lsb) + int(msb) * 128 - 8192;
NoteUpdate_All(channel, Upd_Pitch);
}
@@ -1438,9 +1444,8 @@ void MIDIplay::NoteUpdate(uint16_t MidCh,
MIDIchannel::NoteInfo &info = *i;
const int16_t tone = info.tone;
const uint8_t vol = info.vol;
- const int midiins = info.midiins;
- const size_t insmeta = info.insmeta;
- const adlinsdata &ains = opl.GetAdlMetaIns(insmeta);
+ const int midiins = static_cast<int>(info.midiins);
+ const adlinsdata2 &ains = *info.ains;
AdlChannel::Location my_loc;
my_loc.MidCh = MidCh;
my_loc.note = info.note;
@@ -1454,11 +1459,13 @@ void MIDIplay::NoteUpdate(uint16_t MidCh,
if(props_mask & Upd_Patch)
{
- opl.Patch(c, ins.insId);
+ opl.Patch(c, ins.ains);
AdlChannel::LocationData *d = ch[c].users_find_or_create(my_loc);
- if(d) { // inserts if necessary
+ if(d) // inserts if necessary
+ {
d->sustained = false;
d->vibdelay = 0;
+ d->fixed_sustain = (ains.ms_sound_kon == static_cast<uint16_t>(adlNoteOnMaxTime));
d->kon_time_until_neglible = ains.ms_sound_kon;
d->ins = ins;
}
@@ -1492,7 +1499,9 @@ void MIDIplay::NoteUpdate(uint16_t MidCh,
{
opl.Touch_Real(c, 0);
ch[c].koff_time_until_neglible = 0;
- } else {
+ }
+ else
+ {
ch[c].koff_time_until_neglible = ains.ms_sound_koff;
}
}
@@ -1533,8 +1542,8 @@ void MIDIplay::NoteUpdate(uint16_t MidCh,
switch(opl.m_volumeScale)
{
+
case OPL3::VOLUME_Generic:
- case OPL3::VOLUME_CMF:
{
volume = vol * Ch[MidCh].volume * Ch[MidCh].expression;
@@ -1547,25 +1556,29 @@ void MIDIplay::NoteUpdate(uint16_t MidCh,
*/
//volume = (int)(volume * std::sqrt( (double) ch[c].users.size() ));
- if(opl.LogarithmicVolumes)
- volume = volume * 127 / (127 * 127 * 127) / 2;
- else
- {
- // The formula below: SOLVE(V=127^3 * 2^( (A-63.49999) / 8), A)
- volume = volume > 8725 ? static_cast<uint32_t>(std::log(static_cast<double>(volume)) * 11.541561 + (0.5 - 104.22845)) : 0;
- // The incorrect formula below: SOLVE(V=127^3 * (2^(A/63)-1), A)
- //opl.Touch_Real(c, volume>11210 ? 91.61112 * std::log(4.8819E-7*volume + 1.0)+0.5 : 0);
- }
+ // The formula below: SOLVE(V=127^3 * 2^( (A-63.49999) / 8), A)
+ volume = volume > 8725 ? static_cast<uint32_t>(std::log(static_cast<double>(volume)) * 11.541561 + (0.5 - 104.22845)) : 0;
+ // The incorrect formula below: SOLVE(V=127^3 * (2^(A/63)-1), A)
+ //opl.Touch_Real(c, volume>11210 ? 91.61112 * std::log(4.8819E-7*volume + 1.0)+0.5 : 0);
+
opl.Touch_Real(c, volume, brightness);
//opl.Touch(c, volume);
}
break;
+ case OPL3::VOLUME_NATIVE:
+ {
+ volume = vol * Ch[MidCh].volume * Ch[MidCh].expression;
+ volume = volume * 127 / (127 * 127 * 127) / 2;
+ opl.Touch_Real(c, volume, brightness);
+ }
+ break;
+
case OPL3::VOLUME_DMX:
{
volume = 2 * ((Ch[MidCh].volume * Ch[MidCh].expression) * 127 / 16129) + 1;
//volume = 2 * (Ch[MidCh].volume) + 1;
- volume = (DMX_volume_mapping_table[vol] * volume) >> 9;
+ volume = (DMX_volume_mapping_table[(vol < 128) ? vol : 127] * volume) >> 9;
opl.Touch_Real(c, volume, brightness);
}
break;
@@ -1610,26 +1623,29 @@ void MIDIplay::NoteUpdate(uint16_t MidCh,
// Don't bend a sustained note
if(!d || !d->sustained)
{
- double bend = Ch[MidCh].bend + opl.GetAdlIns(ins.insId).finetune;
+ double midibend = Ch[MidCh].bend * Ch[MidCh].bendsense;
+ double bend = midibend + ins.ains.finetune;
double phase = 0.0;
+ uint8_t vibrato = std::max(Ch[MidCh].vibrato, Ch[MidCh].aftertouch);
+ vibrato = std::max(vibrato, i->vibrato);
if((ains.flags & adlinsdata::Flag_Pseudo4op) && ins.pseudo4op)
{
phase = ains.voice2_fine_tune;//0.125; // Detune the note slightly (this is what Doom does)
}
- if(Ch[MidCh].vibrato && (!d || d->vibdelay >= Ch[MidCh].vibdelay))
- bend += Ch[MidCh].vibrato * Ch[MidCh].vibdepth * std::sin(Ch[MidCh].vibpos);
+ if(vibrato && (!d || d->vibdelay >= Ch[MidCh].vibdelay))
+ bend += static_cast<double>(vibrato) * Ch[MidCh].vibdepth * std::sin(Ch[MidCh].vibpos);
- #ifdef ADLMIDI_USE_DOSBOX_OPL
-#define BEND_COEFFICIENT 172.00093
- #else
-#define BEND_COEFFICIENT 172.4387
- #endif
- opl.NoteOn(c, BEND_COEFFICIENT * std::exp(0.057762265 * (tone + bend + phase)));
+#ifdef ADLMIDI_USE_DOSBOX_OPL
+# define BEND_COEFFICIENT 172.00093
+#else
+# define BEND_COEFFICIENT 172.4387
+#endif
+ opl.NoteOn(c, BEND_COEFFICIENT * std::exp(0.057762265 * (static_cast<double>(tone) + bend + phase)));
#undef BEND_COEFFICIENT
if(hooks.onNote)
- hooks.onNote(hooks.onNote_userData, c, tone, midiins, vol, Ch[MidCh].bend);
+ hooks.onNote(hooks.onNote_userData, c, tone, midiins, vol, midibend);
}
}
}
@@ -1650,9 +1666,9 @@ bool MIDIplay::ProcessEventsNew(bool isSeek)
const size_t TrackCount = CurrentPositionNew.track.size();
const PositionNew RowBeginPosition(CurrentPositionNew);
- #ifdef DEBUG_TIME_CALCULATION
+#ifdef DEBUG_TIME_CALCULATION
double maxTime = 0.0;
- #endif
+#endif
for(size_t tk = 0; tk < TrackCount; ++tk)
{
@@ -1670,10 +1686,10 @@ bool MIDIplay::ProcessEventsNew(bool isSeek)
for(size_t i = 0; i < track.pos->events.size(); i++)
{
const MidiEvent &evt = track.pos->events[i];
- #ifdef ENABLE_BEGIN_SILENCE_SKIPPING
+#ifdef ENABLE_BEGIN_SILENCE_SKIPPING
if(!CurrentPositionNew.began && (evt.type == MidiEvent::T_NOTEON))
CurrentPositionNew.began = true;
- #endif
+#endif
if(isSeek && (evt.type == MidiEvent::T_NOTEON))
continue;
HandleEvent(tk, evt, track.status);
@@ -1681,10 +1697,10 @@ bool MIDIplay::ProcessEventsNew(bool isSeek)
break;//Stop event handling on catching loopEnd event!
}
- #ifdef DEBUG_TIME_CALCULATION
+#ifdef DEBUG_TIME_CALCULATION
if(maxTime < track.pos->time)
maxTime = track.pos->time;
- #endif
+#endif
// Read next event time (unless the track just ended)
if(track.status >= 0)
{
@@ -1694,11 +1710,11 @@ bool MIDIplay::ProcessEventsNew(bool isSeek)
}
}
- #ifdef DEBUG_TIME_CALCULATION
+#ifdef DEBUG_TIME_CALCULATION
std::fprintf(stdout, " \r");
std::fprintf(stdout, "Time: %10f; Audio: %10f\r", maxTime, CurrentPositionNew.absTimePosition);
std::fflush(stdout);
- #endif
+#endif
// Find shortest delay from all track
uint64_t shortest = 0;
@@ -1722,9 +1738,9 @@ bool MIDIplay::ProcessEventsNew(bool isSeek)
fraction<uint64_t> t = shortest * Tempo;
- #ifdef ENABLE_BEGIN_SILENCE_SKIPPING
+#ifdef ENABLE_BEGIN_SILENCE_SKIPPING
if(CurrentPositionNew.began)
- #endif
+#endif
CurrentPositionNew.wait += t.value();
//if(shortest > 0) UI.PrintLn("Delay %ld (%g)", shortest, (double)t.valuel());
@@ -1750,9 +1766,7 @@ bool MIDIplay::ProcessEventsNew(bool isSeek)
return true;//Has events in queue
}
-#endif
-#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER
MIDIplay::MidiEvent MIDIplay::parseEvent(uint8_t **pptr, uint8_t *end, int &status)
{
uint8_t *&ptr = *pptr;
@@ -1800,6 +1814,14 @@ MIDIplay::MidiEvent MIDIplay::parseEvent(uint8_t **pptr, uint8_t *end, int &stat
evt.subtype = evtype;
evt.data.insert(evt.data.begin(), data.begin(), data.end());
+#if 0 /* Print all tempo events */
+ if(evt.subtype == MidiEvent::ST_TEMPOCHANGE)
+ {
+ if(hooks.onDebugMessage)
+ hooks.onDebugMessage(hooks.onDebugMessage_userData, "Temp Change: %02X%02X%02X", evt.data[0], evt.data[1], evt.data[2]);
+ }
+#endif
+
/* TODO: Store those meta-strings separately and give ability to read them
* by external functions (to display song title and copyright in the player) */
if(evt.subtype == MidiEvent::ST_COPYRIGHT)
@@ -1930,9 +1952,16 @@ MIDIplay::MidiEvent MIDIplay::parseEvent(uint8_t **pptr, uint8_t *end, int &stat
evt.data.push_back(*(ptr++));
evt.data.push_back(*(ptr++));
- if((evType == MidiEvent::T_NOTEON) && (evt.data[1] == 0))
+ /* TODO: Implement conversion of RSXX's note volumes out of synthesizer */
+ /*if((opl.m_musicMode == OPL3::MODE_RSXX) && (evType == MidiEvent::T_NOTEON) && (evt.data[1] != 0))
+ {
+ //NOT WORKING YET
+ evt.type = MidiEvent::T_NOTETOUCH;
+ }
+ else */if((evType == MidiEvent::T_NOTEON) && (evt.data[1] == 0))
+ {
evt.type = MidiEvent::T_NOTEOFF; // Note ON with zero velocity is Note OFF!
- //111'th loopStart controller (RPG Maker and others)
+ } //111'th loopStart controller (RPG Maker and others)
else if((evType == MidiEvent::T_CTRLCHANGE) && (evt.data[0] == 111))
{
//Change event type to custom Loop Start event and clear data
@@ -1956,7 +1985,7 @@ MIDIplay::MidiEvent MIDIplay::parseEvent(uint8_t **pptr, uint8_t *end, int &stat
return evt;
}
-#endif
+#endif /* ADLMIDI_DISABLE_MIDI_SEQUENCER */
const std::string &MIDIplay::getErrorString()
{
@@ -2045,7 +2074,7 @@ void MIDIplay::HandleEvent(size_t tk, const MIDIplay::MidiEvent &evt, int &statu
v |= 0x30;
//std::printf("OPL poke %02X, %02X\n", i, v);
//std::fflush(stdout);
- opl.PokeN(0, i, v);
+ opl.Poke(0, i, v);
return;
}
@@ -2125,15 +2154,15 @@ void MIDIplay::HandleEvent(size_t tk, const MIDIplay::MidiEvent &evt, int &statu
}
}
}
-#endif
+#endif /* ADLMIDI_DISABLE_MIDI_SEQUENCER */
-int64_t MIDIplay::CalculateAdlChannelGoodness(unsigned c, const MIDIchannel::NoteInfo::Phys &ins, uint16_t) const
+int64_t MIDIplay::CalculateAdlChannelGoodness(size_t c, const MIDIchannel::NoteInfo::Phys &ins, uint16_t) const
{
int64_t s = -ch[c].koff_time_until_neglible;
// Same midi-instrument = some stability
//if(c == MidCh) s += 4;
- for (AdlChannel::LocationData *j = ch[c].users_first; j; j = j->next)
+ for(AdlChannel::LocationData *j = ch[c].users_first; j; j = j->next)
{
s -= 4000;
@@ -2174,7 +2203,7 @@ int64_t MIDIplay::CalculateAdlChannelGoodness(unsigned c, const MIDIchannel::Not
// increase the score slightly.
unsigned n_evacuation_stations = 0;
- for(unsigned c2 = 0; c2 < opl.NumChannels; ++c2)
+ for(size_t c2 = 0; c2 < static_cast<size_t>(opl.NumChannels); ++c2)
{
if(c2 == c) continue;
@@ -2275,11 +2304,11 @@ void MIDIplay::KillOrEvacuate(size_t from_channel,
hooks.onNote(hooks.onNote_userData,
(int)from_channel,
i->tone,
- i->midiins, 0, 0.0);
+ static_cast<int>(i->midiins), 0, 0.0);
hooks.onNote(hooks.onNote_userData,
(int)c,
i->tone,
- i->midiins,
+ static_cast<int>(i->midiins),
i->vol, 0.0);
}
@@ -2358,7 +2387,12 @@ void MIDIplay::SetRPN(unsigned MidCh, unsigned value, bool MSB)
switch(addr + nrpn * 0x10000 + MSB * 0x20000)
{
case 0x0000 + 0*0x10000 + 1*0x20000: // Pitch-bender sensitivity
- Ch[MidCh].bendsense = value / 8192.0;
+ Ch[MidCh].bendsense_msb = value;
+ Ch[MidCh].updateBendSensitivity();
+ break;
+ case 0x0000 + 0*0x10000 + 0*0x20000: // Pitch-bender sensitivity LSB
+ Ch[MidCh].bendsense_lsb = value;
+ Ch[MidCh].updateBendSensitivity();
break;
case 0x0108 + 1*0x10000 + 1*0x20000: // Vibrato speed
if(value == 64) Ch[MidCh].vibspeed = 1.0;
@@ -2412,7 +2446,7 @@ void MIDIplay::UpdateVibrato(double amount)
{
for(size_t a = 0, b = Ch.size(); a < b; ++a)
{
- if(Ch[a].vibrato && !Ch[a].activenotes_empty())
+ if(Ch[a].hasVibrato() && !Ch[a].activenotes_empty())
{
NoteUpdate_All(static_cast<uint16_t>(a), Upd_Pitch);
Ch[a].vibpos += amount * Ch[a].vibspeed;
@@ -2442,9 +2476,9 @@ void MIDIplay::UpdateArpeggio(double) // amount = amount of time passed
{
// If there is an adlib channel that has multiple notes
// simulated on the same channel, arpeggio them.
- #if 0
+#if 0
const unsigned desired_arpeggio_rate = 40; // Hz (upper limit)
- #if 1
+# if 1
static unsigned cache = 0;
amount = amount; // Ignore amount. Assume we get a constant rate.
cache += MaxSamplesAtTime * desired_arpeggio_rate;
@@ -2452,17 +2486,17 @@ void MIDIplay::UpdateArpeggio(double) // amount = amount of time passed
if(cache < PCM_RATE) return;
cache %= PCM_RATE;
- #else
+# else
static double arpeggio_cache = 0;
arpeggio_cache += amount * desired_arpeggio_rate;
if(arpeggio_cache < 1.0) return;
arpeggio_cache = 0.0;
- #endif
- #endif
- static unsigned arpeggio_counter = 0;
- ++arpeggio_counter;
+# endif
+#endif
+
+ ++m_arpeggioCounter;
for(uint32_t c = 0; c < opl.NumChannels; ++c)
{
@@ -2483,8 +2517,8 @@ retry_arpeggio:
if(n_users >= 4)
rate_reduction = 1;
- for(unsigned count = (arpeggio_counter / rate_reduction) % n_users,
- n = 0; n < count; ++n)
+ for(size_t count = (m_arpeggioCounter / rate_reduction) % n_users,
+ n = 0; n < count; ++n)
i = i->next;
if(i->sustained == false)
@@ -2512,36 +2546,48 @@ retry_arpeggio:
#ifndef ADLMIDI_DISABLE_CPP_EXTRAS
+struct AdlInstrumentTester::Impl
+{
+ uint32_t cur_gm;
+ uint32_t ins_idx;
+ std::vector<uint32_t> adl_ins_list;
+ OPL3 *opl;
+ MIDIplay *play;
+};
+
ADLMIDI_EXPORT AdlInstrumentTester::AdlInstrumentTester(ADL_MIDIPlayer *device)
+ : P(new Impl)
{
- cur_gm = 0;
- ins_idx = 0;
- play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
- if(!play)
- return;
- opl = &play->opl;
+ MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
+ P->cur_gm = 0;
+ P->ins_idx = 0;
+ P->play = play;
+ P->opl = play ? &play->opl : NULL;
}
ADLMIDI_EXPORT AdlInstrumentTester::~AdlInstrumentTester()
-{}
+{
+ delete P;
+}
ADLMIDI_EXPORT void AdlInstrumentTester::FindAdlList()
{
const unsigned NumBanks = (unsigned)adl_getBanksCount();
std::set<unsigned> adl_ins_set;
for(unsigned bankno = 0; bankno < NumBanks; ++bankno)
- adl_ins_set.insert(banks[bankno][cur_gm]);
- adl_ins_list.assign(adl_ins_set.begin(), adl_ins_set.end());
- ins_idx = 0;
+ adl_ins_set.insert(banks[bankno][P->cur_gm]);
+ P->adl_ins_list.assign(adl_ins_set.begin(), adl_ins_set.end());
+ P->ins_idx = 0;
NextAdl(0);
- opl->Silence();
+ P->opl->Silence();
}
ADLMIDI_EXPORT void AdlInstrumentTester::Touch(unsigned c, unsigned volume) // Volume maxes at 127*127*127
{
- if(opl->LogarithmicVolumes)
+ OPL3 *opl = P->opl;
+ if(opl->m_volumeScale == OPL3::VOLUME_NATIVE)
opl->Touch_Real(c, volume * 127 / (127 * 127 * 127) / 2);
else
{
@@ -2554,11 +2600,13 @@ ADLMIDI_EXPORT void AdlInstrumentTester::Touch(unsigned c, unsigned volume) // V
ADLMIDI_EXPORT void AdlInstrumentTester::DoNote(int note)
{
- if(adl_ins_list.empty()) FindAdlList();
- const unsigned meta = adl_ins_list[ins_idx];
- const adlinsdata &ains = opl->GetAdlMetaIns(meta);
+ MIDIplay *play = P->play;
+ OPL3 *opl = P->opl;
+ if(P->adl_ins_list.empty()) FindAdlList();
+ const unsigned meta = P->adl_ins_list[P->ins_idx];
+ const adlinsdata2 ains(adlins[meta]);
- int tone = (cur_gm & 128) ? (cur_gm & 127) : (note + 50);
+ int tone = (P->cur_gm & 128) ? (P->cur_gm & 127) : (note + 50);
if(ains.tone)
{
/*if(ains.tone < 20)
@@ -2570,16 +2618,15 @@ ADLMIDI_EXPORT void AdlInstrumentTester::DoNote(int note)
tone -= ains.tone - 128;
}
double hertz = 172.00093 * std::exp(0.057762265 * (tone + 0.0));
- int i[2] = { ains.adlno1, ains.adlno2 };
int32_t adlchannel[2] = { 0, 3 };
- if(i[0] == i[1])
+ if(ains.adl[0] == ains.adl[1])
{
adlchannel[1] = -1;
adlchannel[0] = 6; // single-op
if(play->hooks.onDebugMessage)
{
play->hooks.onDebugMessage(play->hooks.onDebugMessage_userData,
- "noteon at %d(%d) for %g Hz\n", adlchannel[0], i[0], hertz);
+ "noteon at %d for %g Hz\n", adlchannel[0], hertz);
}
}
else
@@ -2587,7 +2634,7 @@ ADLMIDI_EXPORT void AdlInstrumentTester::DoNote(int note)
if(play->hooks.onDebugMessage)
{
play->hooks.onDebugMessage(play->hooks.onDebugMessage_userData,
- "noteon at %d(%d) and %d(%d) for %g Hz\n", adlchannel[0], i[0], adlchannel[1], i[1], hertz);
+ "noteon at %d and %d for %g Hz\n", adlchannel[0], adlchannel[1], hertz);
}
}
@@ -2597,7 +2644,7 @@ ADLMIDI_EXPORT void AdlInstrumentTester::DoNote(int note)
for(unsigned c = 0; c < 2; ++c)
{
if(adlchannel[c] < 0) continue;
- opl->Patch((uint16_t)adlchannel[c], (uint16_t)i[c]);
+ opl->Patch((uint16_t)adlchannel[c], ains.adl[c]);
opl->Touch_Real((uint16_t)adlchannel[c], 127 * 127 * 100);
opl->Pan((uint16_t)adlchannel[c], 0x30);
opl->NoteOn((uint16_t)adlchannel[c], hertz);
@@ -2606,17 +2653,18 @@ ADLMIDI_EXPORT void AdlInstrumentTester::DoNote(int note)
ADLMIDI_EXPORT void AdlInstrumentTester::NextGM(int offset)
{
- cur_gm = (cur_gm + 256 + (uint32_t)offset) & 0xFF;
+ P->cur_gm = (P->cur_gm + 256 + (uint32_t)offset) & 0xFF;
FindAdlList();
}
ADLMIDI_EXPORT void AdlInstrumentTester::NextAdl(int offset)
{
- if(adl_ins_list.empty()) FindAdlList();
+ //OPL3 *opl = P->opl;
+ if(P->adl_ins_list.empty()) FindAdlList();
const unsigned NumBanks = (unsigned)adl_getBanksCount();
- ins_idx = (uint32_t)((int32_t)ins_idx + (int32_t)adl_ins_list.size() + offset) % adl_ins_list.size();
+ P->ins_idx = (uint32_t)((int32_t)P->ins_idx + (int32_t)P->adl_ins_list.size() + offset) % P->adl_ins_list.size();
- #if 0
+#if 0
UI.Color(15);
std::fflush(stderr);
std::printf("SELECTED G%c%d\t%s\n",
@@ -2625,12 +2673,12 @@ ADLMIDI_EXPORT void AdlInstrumentTester::NextAdl(int offset)
std::fflush(stdout);
UI.Color(7);
std::fflush(stderr);
- #endif
+#endif
- for(unsigned a = 0; a < adl_ins_list.size(); ++a)
+ for(unsigned a = 0, n = P->adl_ins_list.size(); a < n; ++a)
{
- const unsigned i = adl_ins_list[a];
- const adlinsdata &ains = opl->GetAdlMetaIns(i);
+ const unsigned i = P->adl_ins_list[a];
+ const adlinsdata2 ains(adlins[i]);
char ToneIndication[8] = " ";
if(ains.tone)
@@ -2645,13 +2693,13 @@ ADLMIDI_EXPORT void AdlInstrumentTester::NextAdl(int offset)
}
std::printf("%s%s%s%u\t",
ToneIndication,
- ains.adlno1 != ains.adlno2 ? "[2]" : " ",
- (ins_idx == a) ? "->" : "\t",
+ ains.adl[0] != ains.adl[1] ? "[2]" : " ",
+ (P->ins_idx == a) ? "->" : "\t",
i
);
for(unsigned bankno = 0; bankno < NumBanks; ++bankno)
- if(banks[bankno][cur_gm] == i)
+ if(banks[bankno][P->cur_gm] == i)
std::printf(" %u", bankno);
std::printf("\n");
@@ -2685,9 +2733,9 @@ ADLMIDI_EXPORT bool AdlInstrumentTester::HandleInputChar(char ch)
NextGM(+1);
break;
case 3:
- #if !((!defined(__WIN32__) || defined(__CYGWIN__)) && !defined(__DJGPP__))
+#if !((!defined(__WIN32__) || defined(__CYGWIN__)) && !defined(__DJGPP__))
case 27:
- #endif
+#endif
return false;
default:
const char *p = std::strchr(notes, ch);
@@ -2697,7 +2745,7 @@ ADLMIDI_EXPORT bool AdlInstrumentTester::HandleInputChar(char ch)
return true;
}
-#endif//ADLMIDI_DISABLE_CPP_EXTRAS
+#endif /* ADLMIDI_DISABLE_CPP_EXTRAS */
// Implement the user map data structure.
@@ -2737,13 +2785,15 @@ MIDIplay::AdlChannel::LocationData *MIDIplay::AdlChannel::users_allocate()
MIDIplay::AdlChannel::LocationData *MIDIplay::AdlChannel::users_find_or_create(Location loc)
{
LocationData *user = users_find(loc);
- if(!user) {
+ if(!user)
+ {
user = users_allocate();
if(!user)
return NULL;
LocationData *prev = user->prev, *next = user->next;
*user = LocationData();
- user->prev = prev; user->next = next;
+ user->prev = prev;
+ user->next = next;
user->loc = loc;
}
return user;
@@ -2759,7 +2809,8 @@ MIDIplay::AdlChannel::LocationData *MIDIplay::AdlChannel::users_insert(const Loc
return NULL;
LocationData *prev = user->prev, *next = user->next;
*user = x;
- user->prev = prev; user->next = next;
+ user->prev = prev;
+ user->next = next;
}
return user;
}
@@ -2792,8 +2843,10 @@ void MIDIplay::AdlChannel::users_clear()
void MIDIplay::AdlChannel::users_assign(const LocationData *users, size_t count)
{
+ ADL_UNUSED(count);//Avoid warning for release builds
assert(count <= users_max);
- if(users == users_first && users) {
+ if(users == users_first && users)
+ {
// self assignment
assert(users_size == count);
return;
@@ -2801,17 +2854,20 @@ void MIDIplay::AdlChannel::users_assign(const LocationData *users, size_t count)
users_clear();
const LocationData *src_cell = users;
// move to the last
- if(src_cell) {
+ if(src_cell)
+ {
while(src_cell->next)
src_cell = src_cell->next;
}
// push cell copies in reverse order
- while(src_cell) {
+ while(src_cell)
+ {
LocationData *dst_cell = users_allocate();
assert(dst_cell);
LocationData *prev = dst_cell->prev, *next = dst_cell->next;
*dst_cell = *src_cell;
- dst_cell->prev = prev; dst_cell->next = next;
+ dst_cell->prev = prev;
+ dst_cell->next = next;
src_cell = src_cell->prev;
}
assert(users_size == count);