diff --git a/include/amuse/BooBackend.hpp b/include/amuse/BooBackend.hpp index 6ceb3cf..2b09676 100644 --- a/include/amuse/BooBackend.hpp +++ b/include/amuse/BooBackend.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -39,7 +40,7 @@ public: void resetSampleRate(double sampleRate) override; void resetChannelLevels() override; - void setChannelLevels(IBackendSubmix* submix, const float coefs[8], bool slew) override; + void setChannelLevels(IBackendSubmix* submix, const std::array& coefs, bool slew) override; void setPitchRatio(double ratio, bool slew) override; void start() override; void stop() override; diff --git a/include/amuse/Emitter.hpp b/include/amuse/Emitter.hpp index 6499dc9..ac10e05 100644 --- a/include/amuse/Emitter.hpp +++ b/include/amuse/Emitter.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -10,9 +11,9 @@ namespace amuse { class Listener; -using Vector3f = float[3]; +using Vector3f = std::array; -inline float Dot(const Vector3f& a, const Vector3f& b) { return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; } +constexpr float Dot(const Vector3f& a, const Vector3f& b) { return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; } inline float Length(const Vector3f& a) { if (std::fabs(a[0]) <= FLT_EPSILON && std::fabs(a[1]) <= FLT_EPSILON && std::fabs(a[2]) <= FLT_EPSILON) @@ -20,14 +21,14 @@ inline float Length(const Vector3f& a) { return std::sqrt(Dot(a, a)); } -inline float Normalize(Vector3f& out) { - float dist = Length(out); - if (dist == 0.f) - return 0.f; - out[0] /= dist; - out[1] /= dist; - out[2] /= dist; - return dist; +inline Vector3f Normalize(const Vector3f& in) { + const float dist = Length(in); + + if (dist == 0.f) { + return {}; + } + + return {in[0] / dist, in[1] / dist, in[2] / dist}; } /** Voice wrapper with positional-3D level control */ diff --git a/include/amuse/IBackendVoice.hpp b/include/amuse/IBackendVoice.hpp index 02df76c..a18c30b 100644 --- a/include/amuse/IBackendVoice.hpp +++ b/include/amuse/IBackendVoice.hpp @@ -1,5 +1,7 @@ #pragma once +#include + namespace amuse { class IBackendSubmix; @@ -34,7 +36,7 @@ public: virtual void resetChannelLevels() = 0; /** Set channel-gains for audio source (AudioChannel enum for array index) */ - virtual void setChannelLevels(IBackendSubmix* submix, const float coefs[8], bool slew) = 0; + virtual void setChannelLevels(IBackendSubmix* submix, const std::array& coefs, bool slew) = 0; /** Called by client to dynamically adjust the pitch of voices with dynamic pitch enabled */ virtual void setPitchRatio(double ratio, bool slew) = 0; diff --git a/include/amuse/Voice.hpp b/include/amuse/Voice.hpp index ebdfb27..f3b035e 100644 --- a/include/amuse/Voice.hpp +++ b/include/amuse/Voice.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -146,7 +147,7 @@ class Voice : public Entity { float m_tremoloScale = 0.f; /**< minimum volume factor produced via LFO */ float m_tremoloModScale = 0.f; /**< minimum volume factor produced via LFO, scaled via mod wheel */ - float m_lfoPeriods[2] = {}; /**< time-periods for LFO1 and LFO2 */ + std::array m_lfoPeriods{}; /**< time-periods for LFO1 and LFO2 */ std::unique_ptr m_ctrlValsSelf; /**< Self-owned MIDI Controller values */ int8_t* m_extCtrlVals = nullptr; /**< MIDI Controller values (external storage) */ @@ -186,10 +187,10 @@ class Voice : public Entity { ObjToken _startChildMacro(ObjectId macroId, int macroStep, double ticksPerSec, uint8_t midiKey, uint8_t midiVel, uint8_t midiMod, bool pushPc = false); - void _panLaw(float coefsOut[8], float frontPan, float backPan, float totalSpan) const; + std::array _panLaw(float frontPan, float backPan, float totalSpan) const; void _setPan(float pan); void _setSurroundPan(float span); - void _setChannelCoefs(const float coefs[8]); + void _setChannelCoefs(const std::array& coefs); void _setPitchWheel(float pitchWheel); void _notifyCtrlChange(uint8_t ctrl, int8_t val); @@ -261,7 +262,7 @@ public: void setSurroundPan(float span); /** Set current voice channel coefficients immediately */ - void setChannelCoefs(const float coefs[8]); + void setChannelCoefs(const std::array& coefs); /** Start volume envelope to specified level */ void startEnvelope(double dur, float vol, const Curve* envCurve); diff --git a/lib/BooBackend.cpp b/lib/BooBackend.cpp index 54e5132..14e3833 100644 --- a/lib/BooBackend.cpp +++ b/lib/BooBackend.cpp @@ -36,9 +36,9 @@ void BooBackendVoice::resetSampleRate(double sampleRate) { m_booVoice->resetSamp void BooBackendVoice::resetChannelLevels() { m_booVoice->resetChannelLevels(); } -void BooBackendVoice::setChannelLevels(IBackendSubmix* submix, const float coefs[8], bool slew) { - BooBackendSubmix& smx = *reinterpret_cast(submix); - m_booVoice->setMonoChannelLevels(smx.m_booSubmix.get(), coefs, slew); +void BooBackendVoice::setChannelLevels(IBackendSubmix* submix, const std::array& coefs, bool slew) { + auto& smx = *static_cast(submix); + m_booVoice->setMonoChannelLevels(smx.m_booSubmix.get(), coefs.data(), slew); } void BooBackendVoice::setPitchRatio(double ratio, bool slew) { m_booVoice->setPitchRatio(ratio, slew); } diff --git a/lib/Emitter.cpp b/lib/Emitter.cpp index f189d7c..a07fff8 100644 --- a/lib/Emitter.cpp +++ b/lib/Emitter.cpp @@ -5,14 +5,11 @@ #include "amuse/Voice.hpp" namespace amuse { - -static void Delta(Vector3f& out, const Vector3f& a, const Vector3f& b) { - out[0] = a[0] - b[0]; - out[1] = a[1] - b[1]; - out[2] = a[2] - b[2]; +static constexpr Vector3f Delta(const Vector3f& a, const Vector3f& b) { + return {a[0] - b[0], a[1] - b[1], a[2] - b[2]}; } -Emitter::~Emitter() {} +Emitter::~Emitter() = default; Emitter::Emitter(Engine& engine, const AudioGroup& group, ObjToken vox, float maxDist, float minVol, float falloff, bool doppler) @@ -54,12 +51,11 @@ void Emitter::_update() { return; } - float coefs[8] = {}; + std::array coefs{}; double avgDopplerRatio = 0.0; for (auto& listener : m_engine.m_activeListeners) { - Vector3f listenerToEmitter; - Delta(listenerToEmitter, m_pos, listener->m_pos); + const Vector3f listenerToEmitter = Delta(m_pos, listener->m_pos); const float dist = Length(listenerToEmitter); const float panDist = Dot(listenerToEmitter, listener->m_right); const float frontPan = std::clamp(panDist / listener->m_frontDiff, -1.f, 1.f); @@ -74,27 +70,25 @@ void Emitter::_update() { att = m_attCache.getVolume(att, false); if (att > FLT_EPSILON) { /* Apply pan law */ - float thisCoefs[8] = {}; - m_vox->_panLaw(thisCoefs, frontPan, backPan, span); + const std::array thisCoefs = m_vox->_panLaw(frontPan, backPan, span); /* Take maximum coefficient across listeners */ - for (int i = 0; i < 8; ++i) + for (size_t i = 0; i < coefs.size(); ++i) { coefs[i] = std::max(coefs[i], thisCoefs[i] * att * listener->m_volume); + } } /* Calculate doppler */ if (m_doppler) { /* Positive values indicate emitter and listener closing in */ - Vector3f dirDelta; - Delta(dirDelta, m_dir, listener->m_dir); - Vector3f posDelta; - Delta(posDelta, listener->m_pos, m_pos); - Normalize(posDelta); - float deltaSpeed = Dot(dirDelta, posDelta); - if (listener->m_soundSpeed != 0.f) + const Vector3f dirDelta = Delta(m_dir, listener->m_dir); + const Vector3f posDelta = Normalize(Delta(listener->m_pos, m_pos)); + const float deltaSpeed = Dot(dirDelta, posDelta); + if (listener->m_soundSpeed != 0.f) { avgDopplerRatio += 1.0 + deltaSpeed / listener->m_soundSpeed; - else + } else { avgDopplerRatio += 1.0; + } } } @@ -110,7 +104,7 @@ void Emitter::_update() { } void Emitter::setVectors(const float* pos, const float* dir) { - for (int i = 0; i < 3; ++i) { + for (size_t i = 0; i < m_pos.size(); ++i) { m_pos[i] = pos[i]; m_dir[i] = dir[i]; } diff --git a/lib/Engine.cpp b/lib/Engine.cpp index 5828454..1165f61 100644 --- a/lib/Engine.cpp +++ b/lib/Engine.cpp @@ -1,5 +1,7 @@ #include "amuse/Engine.hpp" +#include + #include "amuse/AudioGroup.hpp" #include "amuse/AudioGroupData.hpp" #include "amuse/Common.hpp" @@ -11,7 +13,7 @@ namespace amuse { -static const float FullLevels[8] = {1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f}; +constexpr std::array FullLevels{1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f}; Engine::~Engine() { m_backend.setCallbackInterface(nullptr); diff --git a/lib/Listener.cpp b/lib/Listener.cpp index 7507f5a..c948837 100644 --- a/lib/Listener.cpp +++ b/lib/Listener.cpp @@ -2,10 +2,12 @@ namespace amuse { -static void Cross(Vector3f& out, const Vector3f& a, const Vector3f& b) { - out[0] = a[1] * b[2] - a[2] * b[1]; - out[1] = a[2] * b[0] - a[0] * b[2]; - out[2] = a[0] * b[1] - a[1] * b[0]; +static constexpr Vector3f Cross(const Vector3f& a, const Vector3f& b) { + return { + a[1] * b[2] - a[2] * b[1], + a[2] * b[0] - a[0] * b[2], + a[0] * b[1] - a[1] * b[0], + }; } void Listener::setVectors(const float* pos, const float* dir, const float* heading, const float* up) { @@ -16,11 +18,9 @@ void Listener::setVectors(const float* pos, const float* dir, const float* headi m_up[i] = up[i]; } - Normalize(m_heading); - Normalize(m_up); - Cross(m_right, m_heading, m_up); - Normalize(m_right); - + m_heading = Normalize(m_heading); + m_up = Normalize(m_up); + m_right = Normalize(Cross(m_heading, m_up)); m_dirty = true; } diff --git a/lib/Voice.cpp b/lib/Voice.cpp index 2a80088..6e2febc 100644 --- a/lib/Voice.cpp +++ b/lib/Voice.cpp @@ -155,10 +155,11 @@ ObjToken Voice::_findVoice(int vid, ObjToken thisPtr) { } std::unique_ptr& Voice::_ensureCtrlVals() { - if (m_ctrlValsSelf) + if (m_ctrlValsSelf) { return m_ctrlValsSelf; - m_ctrlValsSelf.reset(new int8_t[128]); - memset(m_ctrlValsSelf.get(), 0, 128); + } + + m_ctrlValsSelf = std::make_unique(128); return m_ctrlValsSelf; } @@ -902,7 +903,9 @@ void Voice::setVolume(float vol) { vox->setVolume(vol); } -void Voice::_panLaw(float coefs[8], float frontPan, float backPan, float totalSpan) const { +std::array Voice::_panLaw(float frontPan, float backPan, float totalSpan) const { + std::array coefs{}; + /* -3dB panning law for various channel configs */ switch (m_engine.m_channelSet) { case AudioChannelSet::Stereo: @@ -1010,6 +1013,8 @@ void Voice::_panLaw(float coefs[8], float frontPan, float backPan, float totalSp break; } + + return coefs; } void Voice::_setPan(float pan) { @@ -1020,8 +1025,7 @@ void Voice::_setPan(float pan) { m_curPan = std::clamp(pan, -1.f, 1.f); const float totalPan = std::clamp(m_curPan, -1.f, 1.f); const float totalSpan = std::clamp(m_curSpan, -1.f, 1.f); - float coefs[8] = {}; - _panLaw(coefs, totalPan, totalPan, totalSpan); + const auto coefs = _panLaw(totalPan, totalPan, totalSpan); _setChannelCoefs(coefs); } @@ -1048,13 +1052,13 @@ void Voice::setSurroundPan(float span) { vox->setSurroundPan(span); } -void Voice::_setChannelCoefs(const float coefs[8]) { +void Voice::_setChannelCoefs(const std::array& coefs) { m_backendVoice->setChannelLevels(m_studio->getMaster().m_backendSubmix.get(), coefs, true); m_backendVoice->setChannelLevels(m_studio->getAuxA().m_backendSubmix.get(), coefs, true); m_backendVoice->setChannelLevels(m_studio->getAuxB().m_backendSubmix.get(), coefs, true); } -void Voice::setChannelCoefs(const float coefs[8]) { +void Voice::setChannelCoefs(const std::array& coefs) { if (m_destroyed) return;