aboutsummaryrefslogtreecommitdiff
path: root/utils/midiplay
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 /utils/midiplay
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 'utils/midiplay')
-rw-r--r--utils/midiplay/adlmidiplay.cpp64
1 files changed, 64 insertions, 0 deletions
diff --git a/utils/midiplay/adlmidiplay.cpp b/utils/midiplay/adlmidiplay.cpp
index dafad8a..8620446 100644
--- a/utils/midiplay/adlmidiplay.cpp
+++ b/utils/midiplay/adlmidiplay.cpp
@@ -283,6 +283,26 @@ static void sighandler(int dum)
}
#endif
+//#define DEBUG_SONG_CHANGE
+//#define DEBUG_SONG_CHANGE_BY_HOOK
+
+#ifdef DEBUG_SONG_CHANGE_BY_HOOK
+static bool gotXmiTrigger = false;
+
+static void xmiTriggerCallback(void *, unsigned trigger, size_t track)
+{
+ std::fprintf(stdout, " - Trigger hook: trigger %u, track: %u\n", trigger, (unsigned)track);
+ flushout(stdout);
+ gotXmiTrigger = true;
+}
+
+static void loopEndCallback(void *)
+{
+ std::fprintf(stdout, " - Loop End hook: trigger\n");
+ flushout(stdout);
+ gotXmiTrigger = true;
+}
+#endif
static void debugPrint(void * /*userdata*/, const char *fmt, ...)
{
@@ -422,6 +442,7 @@ int main(int argc, char **argv)
" will be combined into one\n"
" --solo <track> Selects a solo track to play\n"
" --only <track1,...,trackN> Selects a subset of tracks to play\n"
+ " --song <song ID 0...N-1> Selects a song to play (if XMI)\n"
" -ea Enable the auto-arpeggio\n"
#ifndef HARDWARE_OPL3
" -fp Enables full-panning stereo support\n"
@@ -512,6 +533,7 @@ int main(int argc, char **argv)
int volumeModel = ADLMIDI_VolumeModel_AUTO;
size_t soloTrack = ~(size_t)0;
+ int songNumLoad = -1;
std::vector<size_t> onlyTracks;
#if !defined(HARDWARE_OPL3) && !defined(OUTPUT_WAVE_ONLY)
@@ -636,6 +658,16 @@ int main(int argc, char **argv)
soloTrack = std::strtoul(argv[3], NULL, 10);
had_option = true;
}
+ else if(!std::strcmp("--song", argv[2]))
+ {
+ if(argc <= 3)
+ {
+ printError("The option --song requires an argument!\n");
+ return 1;
+ }
+ songNumLoad = std::strtol(argv[3], NULL, 10);
+ had_option = true;
+ }
else if(!std::strcmp("--only", argv[2]))
{
if(argc <= 3)
@@ -847,6 +879,14 @@ int main(int argc, char **argv)
}
}
+#if defined(DEBUG_SONG_CHANGE_BY_HOOK)
+ adl_setTriggerHandler(myDevice, xmiTriggerCallback, NULL);
+ adl_setLoopEndHook(myDevice, loopEndCallback, NULL);
+ adl_setLoopHooksOnly(myDevice, 1);
+#endif
+ if(songNumLoad >= 0)
+ adl_selectSongNum(myDevice, songNumLoad);
+
std::string musPath = argv[1];
//Open MIDI file to play
if(adl_openFile(myDevice, musPath.c_str()) != 0)
@@ -860,6 +900,8 @@ int main(int argc, char **argv)
std::fprintf(stdout, " - Track count: %lu\n", static_cast<unsigned long>(adl_trackCount(myDevice)));
std::fprintf(stdout, " - Volume model: %s\n", volume_model_to_str(adl_getVolumeRangeModel(myDevice)));
std::fprintf(stdout, " - Channel allocation mode: %s\n", chanalloc_to_str(adl_getChannelAllocMode(myDevice)));
+ if(songNumLoad >= 0)
+ std::fprintf(stdout, " - Attempt to load song number: %d\n", songNumLoad);
if(soloTrack != ~static_cast<size_t>(0))
{
@@ -949,6 +991,12 @@ int main(int argc, char **argv)
audio_start();
# endif
+# ifdef DEBUG_SONG_CHANGE
+ int delayBeforeSongChange = 50;
+ std::fprintf(stdout, "DEBUG: === Random song set test is active! ===\n");
+ flushout(stdout);
+# endif
+
# ifdef DEBUG_SEEKING_TEST
int delayBeforeSeek = 50;
std::fprintf(stdout, "DEBUG: === Random position set test is active! ===\n");
@@ -1030,6 +1078,22 @@ int main(int argc, char **argv)
}
# endif
+# ifdef DEBUG_SONG_CHANGE
+ if(delayBeforeSongChange-- <= 0)
+ {
+ delayBeforeSongChange = rand() % 100;
+ adl_selectSongNum(myDevice, rand() % 10);
+ }
+# endif
+
+# ifdef DEBUG_SONG_CHANGE_BY_HOOK
+ if(gotXmiTrigger)
+ {
+ gotXmiTrigger = false;
+ adl_selectSongNum(myDevice, (rand() % 10) + 1);
+ }
+# endif
+
# else//HARDWARE_OPL3
const double mindelay = 1.0 / newTimerFreq;