3 Commits
v1.3 ... v1.5

Author SHA1 Message Date
Jack Andersen
e99dbc7e0a Initialization fix in SongConverter as indicated by valgrind 2016-06-30 09:30:13 -10:00
Jack Andersen
d6b9d4fca1 PC SNG decoder fixes 2016-06-27 12:43:04 -10:00
Jack Andersen
c7f093c5ee Minor adjustments to test PC SNG data extract 2016-06-27 11:02:10 -10:00
4 changed files with 33 additions and 61 deletions

View File

@@ -45,7 +45,7 @@ class SongState
uint16_t m_unk2; uint16_t m_unk2;
int16_t m_regionIndex; int16_t m_regionIndex;
int16_t m_unk3; int16_t m_unk3;
bool indexValid() const; bool indexValid(bool bigEndian) const;
}; };
/** Tempo change entry */ /** Tempo change entry */

View File

@@ -7,10 +7,10 @@ IntrusiveAudioGroupData::~IntrusiveAudioGroupData()
{ {
if (m_owns) if (m_owns)
{ {
delete m_pool; delete[] m_pool;
delete m_proj; delete[] m_proj;
delete m_sdir; delete[] m_sdir;
delete m_samp; delete[] m_samp;
} }
} }
@@ -27,10 +27,10 @@ IntrusiveAudioGroupData& IntrusiveAudioGroupData::operator=(IntrusiveAudioGroupD
{ {
if (m_owns) if (m_owns)
{ {
delete m_pool; delete[] m_pool;
delete m_proj; delete[] m_proj;
delete m_sdir; delete[] m_sdir;
delete m_samp; delete[] m_samp;
} }
m_owns = other.m_owns; m_owns = other.m_owns;

View File

@@ -42,8 +42,9 @@ struct PitchEvent {};
struct Event struct Event
{ {
bool endEvent = false; bool endEvent = false;
bool controlChange = false; bool isNote = false;
bool progChange = false; bool isControlChange = false;
bool isProgChange = false;
uint8_t channel; uint8_t channel;
uint8_t noteOrCtrl; uint8_t noteOrCtrl;
uint8_t velOrVal; uint8_t velOrVal;
@@ -54,15 +55,16 @@ struct Event
int pitchBend; int pitchBend;
Event(NoteEvent, uint8_t chan, uint8_t note, uint8_t vel, uint16_t len) Event(NoteEvent, uint8_t chan, uint8_t note, uint8_t vel, uint16_t len)
: controlChange(false), channel(chan), noteOrCtrl(note), velOrVal(vel), length(len) {} : isNote(true), channel(chan), noteOrCtrl(note), velOrVal(vel), length(len) {}
Event(CtrlEvent, uint8_t chan, uint8_t note, uint8_t vel, uint16_t len) Event(CtrlEvent, uint8_t chan, uint8_t note, uint8_t vel, uint16_t len)
: controlChange(true), channel(chan), noteOrCtrl(note), velOrVal(vel), length(len) {} : isControlChange(true), channel(chan), noteOrCtrl(note), velOrVal(vel), length(len) {}
Event(ProgEvent, uint8_t chan, uint8_t prog) Event(ProgEvent, uint8_t chan, uint8_t prog)
: progChange(true), channel(chan), program(prog) {} : isProgChange(true), channel(chan), program(prog) {}
Event(PitchEvent, uint8_t chan, int pBend) : isPitchBend(true), channel(chan), pitchBend(pBend) {} Event(PitchEvent, uint8_t chan, int pBend)
: isPitchBend(true), channel(chan), pitchBend(pBend) {}
}; };
class MIDIDecoder class MIDIDecoder
@@ -711,7 +713,7 @@ std::vector<uint8_t> SongConverter::SongToMIDI(const unsigned char* data, Target
std::multimap<int, Event> allEvents; std::multimap<int, Event> allEvents;
/* Iterate all regions */ /* Iterate all regions */
while (trk->m_nextRegion->indexValid()) while (trk->m_nextRegion->indexValid(song.m_bigEndian))
{ {
std::multimap<int, Event> events; std::multimap<int, Event> events;
trk->advanceRegion(nullptr); trk->advanceRegion(nullptr);
@@ -814,27 +816,12 @@ std::vector<uint8_t> SongConverter::SongToMIDI(const unsigned char* data, Target
while (true) while (true)
{ {
/* Load next command */ /* Load next command */
if (*reinterpret_cast<const uint32_t*>(trk->m_data) == 0xffff0000) if (*reinterpret_cast<const uint16_t*>(&trk->m_data[2]) == 0xffff)
{ {
/* End of channel */ /* End of channel */
trk->m_data = nullptr; trk->m_data = nullptr;
break; break;
} }
else if (trk->m_data[0] & 0x80 && trk->m_data[1] & 0x80)
{
/* Control change */
uint8_t val = trk->m_data[0] & 0x7f;
uint8_t ctrl = trk->m_data[1] & 0x7f;
events.emplace(regStart + trk->m_eventWaitCountdown, Event{CtrlEvent{}, trk->m_midiChan, ctrl, val, 0});
trk->m_data += 2;
}
else if (trk->m_data[0] & 0x80)
{
/* Program change */
uint8_t prog = trk->m_data[0] & 0x7f;
events.emplace(regStart + trk->m_eventWaitCountdown, Event{ProgEvent{}, trk->m_midiChan, prog});
trk->m_data += 2;
}
else else
{ {
if ((trk->m_data[2] & 0x80) != 0x80) if ((trk->m_data[2] & 0x80) != 0x80)
@@ -877,7 +864,7 @@ std::vector<uint8_t> SongConverter::SongToMIDI(const unsigned char* data, Target
/* Resolve key-off events */ /* Resolve key-off events */
for (auto& pair : events) for (auto& pair : events)
{ {
if (!pair.second.controlChange) if (pair.second.isNote)
{ {
auto it = allEvents.emplace(pair.first + pair.second.length, pair.second); auto it = allEvents.emplace(pair.first + pair.second.length, pair.second);
it->second.endEvent = true; it->second.endEvent = true;
@@ -892,11 +879,11 @@ std::vector<uint8_t> SongConverter::SongToMIDI(const unsigned char* data, Target
encoder._sendContinuedValue(pair.first - lastTime); encoder._sendContinuedValue(pair.first - lastTime);
lastTime = pair.first; lastTime = pair.first;
if (pair.second.controlChange) if (pair.second.isControlChange)
{ {
encoder.controlChange(pair.second.channel, pair.second.noteOrCtrl, pair.second.velOrVal); encoder.controlChange(pair.second.channel, pair.second.noteOrCtrl, pair.second.velOrVal);
} }
else if (pair.second.progChange) else if (pair.second.isProgChange)
{ {
encoder.programChange(trk->m_midiChan, pair.second.program); encoder.programChange(trk->m_midiChan, pair.second.program);
} }
@@ -904,7 +891,7 @@ std::vector<uint8_t> SongConverter::SongToMIDI(const unsigned char* data, Target
{ {
encoder.pitchBend(trk->m_midiChan, pair.second.pitchBend); encoder.pitchBend(trk->m_midiChan, pair.second.pitchBend);
} }
else else if (pair.second.isNote)
{ {
if (pair.second.endEvent) if (pair.second.endEvent)
encoder.noteOff(pair.second.channel, pair.second.noteOrCtrl, pair.second.velOrVal); encoder.noteOff(pair.second.channel, pair.second.noteOrCtrl, pair.second.velOrVal);
@@ -1092,7 +1079,7 @@ std::vector<uint8_t> SongConverter::MIDIToSong(const std::vector<uint8_t>& data,
lastModVal = 0; lastModVal = 0;
} }
if (event.second.controlChange) if (event.second.isControlChange)
{ {
if (event.second.noteOrCtrl == 1) if (event.second.noteOrCtrl == 1)
{ {
@@ -1129,7 +1116,7 @@ std::vector<uint8_t> SongConverter::MIDIToSong(const std::vector<uint8_t>& data,
} }
} }
} }
else if (event.second.progChange) else if (event.second.isProgChange)
{ {
if (target == Target::GCN) if (target == Target::GCN)
{ {
@@ -1163,7 +1150,7 @@ std::vector<uint8_t> SongConverter::MIDIToSong(const std::vector<uint8_t>& data,
EncodeContinuousRLE(region.pitchBuf, newPitch - lastPitchVal); EncodeContinuousRLE(region.pitchBuf, newPitch - lastPitchVal);
lastPitchVal = newPitch; lastPitchVal = newPitch;
} }
else else if (event.second.isNote)
{ {
if (target == Target::GCN) if (target == Target::GCN)
{ {

View File

@@ -76,9 +76,9 @@ void SongState::Header::swapBig()
m_unkOff = SBig(m_unkOff); m_unkOff = SBig(m_unkOff);
} }
bool SongState::TrackRegion::indexValid() const bool SongState::TrackRegion::indexValid(bool bigEndian) const
{ {
return SBig(m_regionIndex) >= 0; return (bigEndian ? SBig(m_regionIndex) : m_regionIndex) >= 0;
} }
void SongState::TempoChange::swapBig() void SongState::TempoChange::swapBig()
@@ -187,7 +187,7 @@ bool SongState::Track::advance(Sequencer& seq, int32_t ticks)
int32_t endTick = m_parent.m_curTick + ticks; int32_t endTick = m_parent.m_curTick + ticks;
/* Advance region if needed */ /* Advance region if needed */
while (m_nextRegion->indexValid()) while (m_nextRegion->indexValid(m_parent.m_bigEndian))
{ {
uint32_t nextRegTick = (m_parent.m_bigEndian ? SBig(m_nextRegion->m_startTick) : uint32_t nextRegTick = (m_parent.m_bigEndian ? SBig(m_nextRegion->m_startTick) :
m_nextRegion->m_startTick); m_nextRegion->m_startTick);
@@ -212,7 +212,7 @@ bool SongState::Track::advance(Sequencer& seq, int32_t ticks)
} }
if (!m_data) if (!m_data)
return !m_nextRegion->indexValid(); return !m_nextRegion->indexValid(m_parent.m_bigEndian);
/* Update continuous pitch data */ /* Update continuous pitch data */
if (m_pitchWheelData) if (m_pitchWheelData)
@@ -300,7 +300,7 @@ bool SongState::Track::advance(Sequencer& seq, int32_t ticks)
{ {
/* End of channel */ /* End of channel */
m_data = nullptr; m_data = nullptr;
return !m_nextRegion->indexValid(); return !m_nextRegion->indexValid(m_parent.m_bigEndian);
} }
else if (m_data[0] & 0x80 && m_data[1] & 0x80) else if (m_data[0] & 0x80 && m_data[1] & 0x80)
{ {
@@ -348,26 +348,11 @@ bool SongState::Track::advance(Sequencer& seq, int32_t ticks)
} }
/* Load next command */ /* Load next command */
if (*reinterpret_cast<const uint32_t*>(m_data) == 0xffff0000) if (*reinterpret_cast<const uint16_t*>(&m_data[2]) == 0xffff)
{ {
/* End of channel */ /* End of channel */
m_data = nullptr; m_data = nullptr;
return !m_nextRegion->indexValid(); return !m_nextRegion->indexValid(m_parent.m_bigEndian);
}
else if (m_data[0] & 0x80 && m_data[1] & 0x80)
{
/* Control change */
uint8_t val = m_data[0] & 0x7f;
uint8_t ctrl = m_data[1] & 0x7f;
seq.setCtrlValue(m_midiChan, ctrl, val);
m_data += 2;
}
else if (m_data[0] & 0x80)
{
/* Program change */
uint8_t prog = m_data[0] & 0x7f;
seq.setChanProgram(m_midiChan, prog);
m_data += 2;
} }
else else
{ {