diff options
author | Wohlstand <admin@wohlnet.ru> | 2019-09-26 15:13:35 +0300 |
---|---|---|
committer | Wohlstand <admin@wohlnet.ru> | 2019-09-26 15:13:35 +0300 |
commit | 6896738560200e7245904c34bfd57f578ebb99d2 (patch) | |
tree | 9a8f7f2ceba192444eb69157c39897188d728cc3 /src/midi_sequencer_impl.hpp | |
parent | 18c6c50bfbdd100f2add6c689bff5fdad52a989a (diff) | |
download | libADLMIDI-6896738560200e7245904c34bfd57f578ebb99d2.tar.gz libADLMIDI-6896738560200e7245904c34bfd57f578ebb99d2.tar.bz2 libADLMIDI-6896738560200e7245904c34bfd57f578ebb99d2.zip |
Update MIDI Sequencer with latest copy from libOPNMIDI
Diffstat (limited to 'src/midi_sequencer_impl.hpp')
-rw-r--r-- | src/midi_sequencer_impl.hpp | 71 |
1 files changed, 64 insertions, 7 deletions
diff --git a/src/midi_sequencer_impl.hpp b/src/midi_sequencer_impl.hpp index 2af80ea..bfa8503 100644 --- a/src/midi_sequencer_impl.hpp +++ b/src/midi_sequencer_impl.hpp @@ -48,6 +48,36 @@ typedef int32_t ssize_t; # endif #endif +#if defined(_MSC_VER) && _MSC_VER < 1900 + +#define snprintf c99_snprintf +#define vsnprintf c99_vsnprintf + +__inline int c99_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap) +{ + int count = -1; + + if (size != 0) + count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap); + if (count == -1) + count = _vscprintf(format, ap); + + return count; +} + +__inline int c99_snprintf(char *outBuf, size_t size, const char *format, ...) +{ + int count; + va_list ap; + + va_start(ap, format); + count = c99_vsnprintf(outBuf, size, format, ap); + va_end(ap); + + return count; +} +#endif + #ifndef BWMIDI_DISABLE_MUS_SUPPORT #include "cvt_mus2mid.hpp" #endif//MUS @@ -272,13 +302,14 @@ BW_MidiSequencer::BW_MidiSequencer() : m_smfFormat(0), m_loopFormat(Loop_Default), m_loopEnabled(false), + m_loopHooksOnly(false), m_fullSongTimeLength(0.0), m_postSongWaitDelay(1.0), m_loopStartTime(-1.0), m_loopEndTime(-1.0), m_tempoMultiplier(1.0), m_atEnd(false), - m_trackSolo(~(size_t)0), + m_trackSolo(~static_cast<size_t>(0)), m_triggerHandler(NULL), m_triggerUserData(NULL) { @@ -364,6 +395,11 @@ void BW_MidiSequencer::setLoopEnabled(bool enabled) m_loopEnabled = enabled; } +void BW_MidiSequencer::setLoopHooksOnly(bool enabled) +{ + m_loopHooksOnly = enabled; +} + const std::string &BW_MidiSequencer::getMusicTitle() { return m_musTitle; @@ -951,6 +987,7 @@ bool BW_MidiSequencer::processEvents(bool isSeek) unsigned caughLoopStart = 0; unsigned caughLoopStackStart = 0; unsigned caughLoopStackEnds = 0; + double caughLoopStackEndsTime = 0.0; unsigned caughLoopStackBreaks = 0; #ifdef DEBUG_TIME_CALCULATION @@ -983,12 +1020,18 @@ bool BW_MidiSequencer::processEvents(bool isSeek) if(m_loop.caughtStart) { + if(m_interface->onloopStart)//Loop Start hook + m_interface->onloopStart(m_interface->onloopStart_userData); + caughLoopStart++; m_loop.caughtStart = false; } if(m_loop.caughtStackStart) { + if(m_interface->onloopStart && (m_loopStartTime >= track.pos->time))//Loop Start hook + m_interface->onloopStart(m_interface->onloopStart_userData); + caughLoopStackStart++; m_loop.caughtStackStart = false; } @@ -1005,6 +1048,7 @@ bool BW_MidiSequencer::processEvents(bool isSeek) { m_loop.caughtStackEnd = false; caughLoopStackEnds++; + caughLoopStackEndsTime = track.pos->time; } doLoopJump = true; break;//Stop event handling on catching loopEnd event! @@ -1094,6 +1138,15 @@ bool BW_MidiSequencer::processEvents(bool isSeek) LoopStackEntry &s = m_loop.getCurStack(); if(s.infinity) { + if(m_interface->onloopEnd && (m_loopEndTime >= caughLoopStackEndsTime))//Loop End hook + { + m_interface->onloopEnd(m_interface->onloopEnd_userData); + if(m_loopHooksOnly)//Stop song on reaching loop end + { + m_atEnd = true; //Don't handle events anymore + m_currentPosition.wait += m_postSongWaitDelay;//One second delay until stop playing + } + } m_currentPosition = s.startPosition; m_loop.skipStackStart = true; return true; @@ -1127,10 +1180,14 @@ bool BW_MidiSequencer::processEvents(bool isSeek) if(shortest_no || m_loop.caughtEnd) { + if(m_interface->onloopEnd)//Loop End hook + m_interface->onloopEnd(m_interface->onloopEnd_userData); + //Loop if song end or loop end point has reached m_loop.caughtEnd = false; shortest = 0; - if(!m_loopEnabled) + + if(!m_loopEnabled || m_loopHooksOnly) { m_atEnd = true; //Don't handle events anymore m_currentPosition.wait += m_postSongWaitDelay;//One second delay until stop playing @@ -1545,7 +1602,7 @@ void BW_MidiSequencer::handleEvent(size_t track, const BW_MidiSequencer::MidiEve } else { - if(m_trackSolo != ~(size_t)0 && track != m_trackSolo) + if(m_trackSolo != ~static_cast<size_t>(0) && track != m_trackSolo) return; if(m_trackDisable[track]) return; @@ -1576,8 +1633,8 @@ void BW_MidiSequencer::handleEvent(size_t track, const BW_MidiSequencer::MidiEve { // Special event FF uint8_t evtype = evt.subtype; - uint64_t length = (uint64_t)evt.data.size(); - const char *data(length ? (const char *)evt.data.data() : ""); + uint64_t length = static_cast<uint64_t>(evt.data.size()); + const char *data(length ? reinterpret_cast<const char *>(evt.data.data()) : ""); if(evtype == MidiEvent::ST_ENDTRACK)//End Of Track { @@ -1628,8 +1685,8 @@ void BW_MidiSequencer::handleEvent(size_t track, const BW_MidiSequencer::MidiEve m_loop.skipStackStart = false; return; } - LoopStackEntry &s = m_loop.stack[(m_loop.stackLevel + 1)]; - s.loops = (int)data[0]; + LoopStackEntry &s = m_loop.stack[static_cast<size_t>(m_loop.stackLevel + 1)]; + s.loops = static_cast<int>(data[0]); s.infinity = (data[0] == 0); m_loop.caughtStackStart = true; return; |