aboutsummaryrefslogtreecommitdiff
path: root/src/midi_sequencer_impl.hpp
diff options
context:
space:
mode:
authorWohlstand <admin@wohlnet.ru>2019-09-26 15:13:35 +0300
committerWohlstand <admin@wohlnet.ru>2019-09-26 15:13:35 +0300
commit6896738560200e7245904c34bfd57f578ebb99d2 (patch)
tree9a8f7f2ceba192444eb69157c39897188d728cc3 /src/midi_sequencer_impl.hpp
parent18c6c50bfbdd100f2add6c689bff5fdad52a989a (diff)
downloadlibADLMIDI-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.hpp71
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;