aboutsummaryrefslogtreecommitdiff
path: root/src/midi_sequencer_impl.hpp
diff options
context:
space:
mode:
authorWohlstand <admin@wohlnet.ru>2022-10-17 18:39:08 +0300
committerWohlstand <admin@wohlnet.ru>2022-10-17 18:39:08 +0300
commit9fbaa58e87a63749ff1694bdb9f4d1241db98689 (patch)
treee876a7ea5bed72a36836137f8915eed1fe84edd2 /src/midi_sequencer_impl.hpp
parente27764edeb24936ce50da6229a781006e7ebdc75 (diff)
downloadlibADLMIDI-9fbaa58e87a63749ff1694bdb9f4d1241db98689.tar.gz
libADLMIDI-9fbaa58e87a63749ff1694bdb9f4d1241db98689.tar.bz2
libADLMIDI-9fbaa58e87a63749ff1694bdb9f4d1241db98689.zip
Improved the multi-song XMI support
- Allow selecting every individual song of the XMI file - Allow dynamic song switch without re-opening of a file - Fixed XMI2MID converter with adding an ability to export every individual song - Added hooks for loop start and end events - Added an option to immediately stop the song processing on loop end reaching (needed to perform dynamic song switch at the loop end point)
Diffstat (limited to 'src/midi_sequencer_impl.hpp')
-rw-r--r--src/midi_sequencer_impl.hpp71
1 files changed, 63 insertions, 8 deletions
diff --git a/src/midi_sequencer_impl.hpp b/src/midi_sequencer_impl.hpp
index bfd7c40..3c94968 100644
--- a/src/midi_sequencer_impl.hpp
+++ b/src/midi_sequencer_impl.hpp
@@ -315,6 +315,7 @@ BW_MidiSequencer::BW_MidiSequencer() :
m_tempoMultiplier(1.0),
m_atEnd(false),
m_loopCount(-1),
+ m_loadTrackNumber(0),
m_trackSolo(~static_cast<size_t>(0)),
m_triggerHandler(NULL),
m_triggerUserData(NULL)
@@ -450,6 +451,37 @@ void BW_MidiSequencer::setSoloTrack(size_t track)
m_trackSolo = track;
}
+void BW_MidiSequencer::setLoadTrack(int track)
+{
+ m_loadTrackNumber = track;
+
+ if(!m_rawSongsData.empty() && m_format == Format_XMIDI) // Reload the song
+ {
+ if(m_loadTrackNumber >= (int)m_rawSongsData.size())
+ m_loadTrackNumber = m_rawSongsData.size() - 1;
+
+ if(m_interface && m_interface->rt_controllerChange)
+ {
+ for(int i = 0; i < 15; i++)
+ m_interface->rt_controllerChange(m_interface->rtUserData, i, 123, 0);
+ }
+
+ m_atEnd = false;
+ m_loop.fullReset();
+ m_loop.caughtStart = true;
+
+ m_smfFormat = 0;
+
+ FileAndMemReader fr;
+ fr.openData(m_rawSongsData[m_loadTrackNumber].data(),
+ m_rawSongsData[m_loadTrackNumber].size());
+ parseSMF(fr);
+
+ m_format = Format_XMIDI;
+ }
+}
+
+
void BW_MidiSequencer::setTriggerHandler(TriggerHandler handler, void *userData)
{
m_triggerHandler = handler;
@@ -2285,6 +2317,7 @@ bool BW_MidiSequencer::loadMIDI(FileAndMemReader &fr)
m_smfFormat = 0;
m_cmfInstruments.clear();
+ m_rawSongsData.clear();
const size_t headerSize = 4 + 4 + 2 + 2 + 2; // 14
char headerBuf[headerSize] = "";
@@ -2888,7 +2921,12 @@ bool BW_MidiSequencer::parseXMI(FileAndMemReader &fr)
const size_t headerSize = 14;
char headerBuf[headerSize] = "";
size_t fsize = 0;
- BufferGuard<uint8_t> cvt_buf;
+// BufferGuard<uint8_t> cvt_buf;
+ std::vector<uint8_t *> song_buf;
+ std::vector<uint32_t> song_size;
+ bool ret;
+
+ (void)Convert_xmi2midi; /* Shut up the warning */
fsize = fr.read(headerBuf, 1, headerSize);
if(fsize < headerSize)
@@ -2931,24 +2969,41 @@ bool BW_MidiSequencer::parseXMI(FileAndMemReader &fr)
// Close source stream
fr.close();
- uint8_t *mid = NULL;
- uint32_t mid_len = 0;
- int m2mret = Convert_xmi2midi(mus, static_cast<uint32_t>(mus_len + 20),
- &mid, &mid_len, XMIDI_CONVERT_NOCONVERSION);
+// uint8_t *mid = NULL;
+// uint32_t mid_len = 0;
+ int m2mret = Convert_xmi2midi_multi(mus, static_cast<uint32_t>(mus_len + 20),
+ song_buf, song_size, XMIDI_CONVERT_NOCONVERSION);
if(mus)
free(mus);
if(m2mret < 0)
{
+ for(size_t i = 0; i < song_buf.size(); ++i)
+ std::free(song_buf[i]);
m_errorString = "Invalid XMI data format!";
return false;
}
- cvt_buf.set(mid);
+ if(m_loadTrackNumber >= (int)song_buf.size())
+ m_loadTrackNumber = song_buf.size() - 1;
+
+ for(size_t i = 0; i < song_buf.size(); ++i)
+ {
+ m_rawSongsData.push_back(std::vector<uint8_t >(song_buf[i], song_buf[i] + song_size[i]));
+ std::free(song_buf[i]);
+ }
+
+ song_buf.clear();
+ song_size.clear();
+
+ // cvt_buf.set(mid);
// Open converted MIDI file
- fr.openData(mid, static_cast<size_t>(mid_len));
+ fr.openData(m_rawSongsData[m_loadTrackNumber].data(),
+ m_rawSongsData[m_loadTrackNumber].size());
// Set format as XMIDI
m_format = Format_XMIDI;
- return parseSMF(fr);
+ ret = parseSMF(fr);
+
+ return ret;
}
#endif