mirror of https://github.com/AxioDL/amuse.git
Emitter: Use std::array where applicable
Makes the data more strongly-typed and prevents implicit array->pointer decay
This commit is contained in:
parent
0be0ca2911
commit
29e7d8bc1e
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <list>
|
||||
|
@ -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<float, 8>& coefs, bool slew) override;
|
||||
void setPitchRatio(double ratio, bool slew) override;
|
||||
void start() override;
|
||||
void stop() override;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cfloat>
|
||||
#include <cmath>
|
||||
|
||||
|
@ -10,9 +11,9 @@
|
|||
namespace amuse {
|
||||
class Listener;
|
||||
|
||||
using Vector3f = float[3];
|
||||
using Vector3f = std::array<float, 3>;
|
||||
|
||||
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 */
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <array>
|
||||
|
||||
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<float, 8>& 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;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <list>
|
||||
|
@ -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<float, 2> m_lfoPeriods{}; /**< time-periods for LFO1 and LFO2 */
|
||||
std::unique_ptr<int8_t[]> 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<Voice> _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<float, 8> _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<float, 8>& 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<float, 8>& coefs);
|
||||
|
||||
/** Start volume envelope to specified level */
|
||||
void startEnvelope(double dur, float vol, const Curve* envCurve);
|
||||
|
|
|
@ -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<BooBackendSubmix*>(submix);
|
||||
m_booVoice->setMonoChannelLevels(smx.m_booSubmix.get(), coefs, slew);
|
||||
void BooBackendVoice::setChannelLevels(IBackendSubmix* submix, const std::array<float, 8>& coefs, bool slew) {
|
||||
auto& smx = *static_cast<BooBackendSubmix*>(submix);
|
||||
m_booVoice->setMonoChannelLevels(smx.m_booSubmix.get(), coefs.data(), slew);
|
||||
}
|
||||
|
||||
void BooBackendVoice::setPitchRatio(double ratio, bool slew) { m_booVoice->setPitchRatio(ratio, slew); }
|
||||
|
|
|
@ -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<Voice> vox, float maxDist, float minVol,
|
||||
float falloff, bool doppler)
|
||||
|
@ -54,12 +51,11 @@ void Emitter::_update() {
|
|||
return;
|
||||
}
|
||||
|
||||
float coefs[8] = {};
|
||||
std::array<float, 8> 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,29 +70,27 @@ 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<float, 8> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_engine.m_activeListeners.size() != 0) {
|
||||
m_vox->setChannelCoefs(coefs);
|
||||
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "amuse/Engine.hpp"
|
||||
|
||||
#include <array>
|
||||
|
||||
#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<float, 8> FullLevels{1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f};
|
||||
|
||||
Engine::~Engine() {
|
||||
m_backend.setCallbackInterface(nullptr);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -155,10 +155,11 @@ ObjToken<Voice> Voice::_findVoice(int vid, ObjToken<Voice> thisPtr) {
|
|||
}
|
||||
|
||||
std::unique_ptr<int8_t[]>& 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<int8_t[]>(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<float, 8> Voice::_panLaw(float frontPan, float backPan, float totalSpan) const {
|
||||
std::array<float, 8> 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<float, 8>& 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<float, 8>& coefs) {
|
||||
if (m_destroyed)
|
||||
return;
|
||||
|
||||
|
|
Loading…
Reference in New Issue