diff --git a/AudioUnit/CMakeLists.txt b/AudioUnit/CMakeLists.txt index 2293c23..4a4d951 100644 --- a/AudioUnit/CMakeLists.txt +++ b/AudioUnit/CMakeLists.txt @@ -103,7 +103,7 @@ if (APPLE AND (NOT CMAKE_OSX_DEPLOYMENT_TARGET OR CMAKE_OSX_DEPLOYMENT_TARGET VE ) else() - message(WARNING "Unable to find developer provision profile; skipping Amuse-AU") + message(WARNING "Unable to find developer provisioning profile; skipping Amuse-AU") endif() endif() endif() diff --git a/include/amuse/SoundMacroState.hpp b/include/amuse/SoundMacroState.hpp index 8b7c4d3..8e0345f 100644 --- a/include/amuse/SoundMacroState.hpp +++ b/include/amuse/SoundMacroState.hpp @@ -5,6 +5,7 @@ #include #include #include "Entity.hpp" +#include "Common.hpp" namespace amuse { @@ -119,6 +120,17 @@ class SoundMacroState /** 'program counter' stack for the active SoundMacro */ std::vector> m_pc; + static int _assertPC(int pc, uint32_t size); + static int _assertPC(int pc, uint32_t size, bool swapSize) + { + return _assertPC(pc, swapSize ? SBig(size) : size); + } + + void _setPC(int pc) + { + m_pc.back().second = _assertPC(pc, m_header.m_size); + } + double m_ticksPerSec; /**< ratio for resolving ticks in commands that use them */ uint8_t m_initVel; /**< Velocity played for this macro invocation */ uint8_t m_initMod; /**< Modulation played for this macro invocation */ diff --git a/lib/SoundMacroState.cpp b/lib/SoundMacroState.cpp index 7055bef..9d3019a 100644 --- a/lib/SoundMacroState.cpp +++ b/lib/SoundMacroState.cpp @@ -13,6 +13,19 @@ namespace amuse { +int SoundMacroState::_assertPC(int pc, uint32_t size) +{ + if (pc == -1) + return -1; + int cmdCount = (size - sizeof(Header)) / sizeof(Command); + if (pc >= cmdCount) + { + fprintf(stderr, "SoundMacro PC bounds exceeded [%d/%d]\n", pc, cmdCount); + abort(); + } + return pc; +} + void SoundMacroState::Header::swapBig() { m_size = SBig(m_size); @@ -133,7 +146,8 @@ void SoundMacroState::initialize(const unsigned char* ptr, int step, double tick m_curMod = midiMod; m_curPitch = midiKey * 100; m_pc.clear(); - m_pc.push_back({ptr, step}); + const Header& header = reinterpret_cast(ptr); + m_pc.push_back({ptr, _assertPC(step, header.m_size, swapData)}); m_inWait = false; m_execTime = 0.f; m_keyoff = false; @@ -143,7 +157,7 @@ void SoundMacroState::initialize(const unsigned char* ptr, int step, double tick m_useAdsrControllers = false; m_portamentoMode = 2; m_portamentoTime = 0.5f; - m_header = *reinterpret_cast(ptr); + m_header = header; if (swapData) m_header.swapBig(); } @@ -180,6 +194,7 @@ bool SoundMacroState::advance(Voice& vox, double dt) /* Load next command based on counter */ const Command* commands = reinterpret_cast(m_pc.back().first + sizeof(Header)); + _assertPC(m_pc.back().second, m_header.m_size); Command cmd = commands[m_pc.back().second++]; if (vox.getAudioGroup().getDataFormat() != DataFormat::PC) cmd.swapBig(); @@ -189,7 +204,7 @@ bool SoundMacroState::advance(Voice& vox, double dt) { case Op::End: case Op::Stop: - m_pc.back().second = -1; + _setPC(-1); return true; case Op::SplitKey: { @@ -201,7 +216,7 @@ bool SoundMacroState::advance(Voice& vox, double dt) { /* Do Branch */ if (macroId == m_header.m_macroId) - m_pc.back().second = macroStep; + _setPC(macroStep); else vox.loadSoundObject(macroId, macroStep, m_ticksPerSec, m_initKey, m_initVel, m_initMod); } @@ -218,7 +233,7 @@ bool SoundMacroState::advance(Voice& vox, double dt) { /* Do Branch */ if (macroId == m_header.m_macroId) - m_pc.back().second = macroStep; + _setPC(macroStep); else vox.loadSoundObject(macroId, macroStep, m_ticksPerSec, m_initKey, m_initVel, m_initMod); } @@ -287,7 +302,7 @@ bool SoundMacroState::advance(Voice& vox, double dt) { /* Loop back to step */ --m_loopCountdown; - m_pc.back().second = step; + _setPC(step); } else /* Break out of loop */ m_loopCountdown = -1; @@ -301,7 +316,7 @@ bool SoundMacroState::advance(Voice& vox, double dt) /* Do Branch */ if (macroId == m_header.m_macroId) - m_pc.back().second = macroStep; + _setPC(macroStep); else vox.loadSoundObject(macroId, macroStep, m_ticksPerSec, m_initKey, m_initVel, m_initMod); @@ -389,7 +404,7 @@ bool SoundMacroState::advance(Voice& vox, double dt) { /* Do Branch */ if (macroId == m_header.m_macroId) - m_pc.back().second = macroStep; + _setPC(macroStep); else vox.loadSoundObject(macroId, macroStep, m_ticksPerSec, m_initKey, m_initVel, m_initMod); } @@ -511,7 +526,7 @@ bool SoundMacroState::advance(Voice& vox, double dt) { /* Do branch */ if (macroId == m_header.m_macroId) - m_pc.back().second = macroStep; + _setPC(macroStep); else vox.loadSoundObject(macroId, macroStep, m_ticksPerSec, m_initKey, m_initVel, m_initMod); } @@ -776,7 +791,7 @@ bool SoundMacroState::advance(Voice& vox, double dt) int16_t macroStep = *reinterpret_cast(&cmd.m_data[3]); if (macroId == m_header.m_macroId) - m_pc.push_back({m_pc.back().first, macroStep}); + m_pc.push_back({m_pc.back().first, _assertPC(macroStep, m_header.m_size)}); else vox.loadSoundObject(macroId, macroStep, m_ticksPerSec, m_initKey, m_initVel, m_initMod, true); @@ -1205,7 +1220,7 @@ bool SoundMacroState::advance(Voice& vox, double dt) b = m_variables[b]; if ((a == b) ^ lnot) - m_pc.back().second = macroStep; + _setPC(macroStep); break; } @@ -1229,7 +1244,7 @@ bool SoundMacroState::advance(Voice& vox, double dt) b = m_variables[b]; if ((a < b) ^ lnot) - m_pc.back().second = macroStep; + _setPC(macroStep); break; } diff --git a/lib/Voice.cpp b/lib/Voice.cpp index 0e425ba..177f5ea 100644 --- a/lib/Voice.cpp +++ b/lib/Voice.cpp @@ -46,7 +46,8 @@ void Voice::_macroSampleEnd() { if (m_sampleEndTrap.macroId == m_state.m_header.m_macroId) { - m_state.m_pc.back().second = m_sampleEndTrap.macroStep; + m_state.m_pc.back().second = SoundMacroState::_assertPC(m_sampleEndTrap.macroStep, + m_state.m_header.m_size); m_state.m_inWait = false; } else @@ -751,9 +752,11 @@ bool Voice::_loadSoundMacro(const unsigned char* macroData, int macroStep, doubl { if (!pushPc) m_state.m_pc.clear(); - m_state.m_pc.push_back({macroData, macroStep}); - m_state.m_header = *reinterpret_cast(macroData); - if (m_audioGroup.getDataFormat() != DataFormat::PC) + const SoundMacroState::Header& header = reinterpret_cast(macroData); + const bool swapData = m_audioGroup.getDataFormat() != DataFormat::PC; + m_state.m_pc.push_back({macroData, SoundMacroState::_assertPC(macroStep, header.m_size, swapData)}); + m_state.m_header = header; + if (swapData) m_state.m_header.swapBig(); } @@ -846,7 +849,8 @@ void Voice::keyOff() { if (m_keyoffTrap.macroId == m_state.m_header.m_macroId) { - m_state.m_pc.back().second = m_keyoffTrap.macroStep; + m_state.m_pc.back().second = SoundMacroState::_assertPC(m_keyoffTrap.macroStep, + m_state.m_header.m_size); m_state.m_inWait = false; } else @@ -867,7 +871,8 @@ void Voice::message(int32_t val) if (m_messageTrap.macroId != 0xffff) { if (m_messageTrap.macroId == m_state.m_header.m_macroId) - m_state.m_pc.back().second = m_messageTrap.macroStep; + m_state.m_pc.back().second = SoundMacroState::_assertPC(m_messageTrap.macroStep, + m_state.m_header.m_size); else loadSoundObject(m_messageTrap.macroId, m_messageTrap.macroStep, m_state.m_ticksPerSec, m_state.m_initKey, m_state.m_initVel, m_state.m_initMod);