mirror of https://github.com/AxioDL/amuse.git
Deallocation fixes and simplification
This commit is contained in:
parent
531961be78
commit
2192d45da1
|
@ -48,6 +48,7 @@ class Engine
|
||||||
std::list<std::shared_ptr<Voice>>::iterator _destroyVoice(Voice* voice);
|
std::list<std::shared_ptr<Voice>>::iterator _destroyVoice(Voice* voice);
|
||||||
std::list<std::shared_ptr<Sequencer>>::iterator _destroySequencer(Sequencer* sequencer);
|
std::list<std::shared_ptr<Sequencer>>::iterator _destroySequencer(Sequencer* sequencer);
|
||||||
std::list<Submix>::iterator _destroySubmix(Submix* smx);
|
std::list<Submix>::iterator _destroySubmix(Submix* smx);
|
||||||
|
std::list<Submix>::iterator _removeSubmix(Submix* smx);
|
||||||
void _bringOutYourDead();
|
void _bringOutYourDead();
|
||||||
public:
|
public:
|
||||||
~Engine();
|
~Engine();
|
||||||
|
|
|
@ -30,8 +30,8 @@ class Entity
|
||||||
* but shared_ptrs are issued to the client so it can safely track state */
|
* but shared_ptrs are issued to the client so it can safely track state */
|
||||||
friend class Engine;
|
friend class Engine;
|
||||||
friend class SoundMacroState;
|
friend class SoundMacroState;
|
||||||
bool m_destroyed = false;
|
|
||||||
protected:
|
protected:
|
||||||
|
bool m_destroyed = false;
|
||||||
void _destroy()
|
void _destroy()
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
|
|
@ -26,9 +26,6 @@ class Submix
|
||||||
Submix* m_submix = nullptr; /**< Parent submix of this submix (or NULL if mixing to main output) */
|
Submix* m_submix = nullptr; /**< Parent submix of this submix (or NULL if mixing to main output) */
|
||||||
std::list<Submix>::iterator m_engineIt; /**< Iterator to self within Engine's list for quick deletion */
|
std::list<Submix>::iterator m_engineIt; /**< Iterator to self within Engine's list for quick deletion */
|
||||||
std::unique_ptr<IBackendSubmix> m_backendSubmix; /**< Handle to client-implemented backend submix */
|
std::unique_ptr<IBackendSubmix> m_backendSubmix; /**< Handle to client-implemented backend submix */
|
||||||
std::unordered_set<Voice*> m_activeVoices; /**< Secondary index of Voices within Submix */
|
|
||||||
std::unordered_set<Sequencer*> m_activeSequencers; /**< Secondary index of Sequencers within Submix */
|
|
||||||
std::unordered_set<Submix*> m_activeSubmixes; /**< Secondary index of Submixes within Submix */
|
|
||||||
std::vector<std::unique_ptr<EffectBaseTypeless>> m_effectStack; /**< Ordered list of effects to apply to submix */
|
std::vector<std::unique_ptr<EffectBaseTypeless>> m_effectStack; /**< Ordered list of effects to apply to submix */
|
||||||
bool m_destroyed = false;
|
bool m_destroyed = false;
|
||||||
void _destroy();
|
void _destroy();
|
||||||
|
|
|
@ -11,7 +11,17 @@
|
||||||
namespace amuse
|
namespace amuse
|
||||||
{
|
{
|
||||||
|
|
||||||
Engine::~Engine() {}
|
Engine::~Engine()
|
||||||
|
{
|
||||||
|
while (m_activeSubmixes.size())
|
||||||
|
removeSubmix(&m_activeSubmixes.front());
|
||||||
|
for (std::shared_ptr<Emitter>& emitter : m_activeEmitters)
|
||||||
|
emitter->_destroy();
|
||||||
|
for (std::shared_ptr<Voice>& vox : m_activeVoices)
|
||||||
|
vox->_destroy();
|
||||||
|
for (std::shared_ptr<Sequencer>& seq : m_activeSequencers)
|
||||||
|
seq->_destroy();
|
||||||
|
}
|
||||||
|
|
||||||
Engine::Engine(IBackendVoiceAllocator& backend)
|
Engine::Engine(IBackendVoiceAllocator& backend)
|
||||||
: m_backend(backend)
|
: m_backend(backend)
|
||||||
|
@ -75,6 +85,8 @@ std::list<std::shared_ptr<Voice>>::iterator Engine::_destroyVoice(Voice* voice)
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
assert(this == &voice->getEngine());
|
assert(this == &voice->getEngine());
|
||||||
#endif
|
#endif
|
||||||
|
if (voice->m_destroyed)
|
||||||
|
return m_activeVoices.begin();
|
||||||
voice->_destroy();
|
voice->_destroy();
|
||||||
return m_activeVoices.erase(voice->m_engineIt);
|
return m_activeVoices.erase(voice->m_engineIt);
|
||||||
}
|
}
|
||||||
|
@ -84,6 +96,8 @@ std::list<std::shared_ptr<Sequencer>>::iterator Engine::_destroySequencer(Sequen
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
assert(this == &sequencer->getEngine());
|
assert(this == &sequencer->getEngine());
|
||||||
#endif
|
#endif
|
||||||
|
if (sequencer->m_destroyed)
|
||||||
|
return m_activeSequencers.begin();
|
||||||
sequencer->_destroy();
|
sequencer->_destroy();
|
||||||
return m_activeSequencers.erase(sequencer->m_engineIt);
|
return m_activeSequencers.erase(sequencer->m_engineIt);
|
||||||
}
|
}
|
||||||
|
@ -93,6 +107,8 @@ std::list<Submix>::iterator Engine::_destroySubmix(Submix* smx)
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
assert(this == &smx->getEngine());
|
assert(this == &smx->getEngine());
|
||||||
#endif
|
#endif
|
||||||
|
if (smx->m_destroyed)
|
||||||
|
return m_activeSubmixes.begin();
|
||||||
smx->_destroy();
|
smx->_destroy();
|
||||||
return m_activeSubmixes.erase(smx->m_engineIt);
|
return m_activeSubmixes.erase(smx->m_engineIt);
|
||||||
}
|
}
|
||||||
|
@ -234,8 +250,7 @@ Submix* Engine::addSubmix(Submix* smx)
|
||||||
return _allocateSubmix(smx);
|
return _allocateSubmix(smx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Remove Submix and deallocate */
|
std::list<Submix>::iterator Engine::_removeSubmix(Submix* smx)
|
||||||
void Engine::removeSubmix(Submix* smx)
|
|
||||||
{
|
{
|
||||||
/* Delete all voices bound to submix */
|
/* Delete all voices bound to submix */
|
||||||
for (auto it = m_activeVoices.begin() ; it != m_activeVoices.end() ;)
|
for (auto it = m_activeVoices.begin() ; it != m_activeVoices.end() ;)
|
||||||
|
@ -243,7 +258,7 @@ void Engine::removeSubmix(Submix* smx)
|
||||||
Voice* vox = it->get();
|
Voice* vox = it->get();
|
||||||
|
|
||||||
Submix* vsmx = vox->getSubmix();
|
Submix* vsmx = vox->getSubmix();
|
||||||
if (vsmx && vsmx == smx)
|
if (vsmx == smx)
|
||||||
{
|
{
|
||||||
vox->_destroy();
|
vox->_destroy();
|
||||||
it = m_activeVoices.erase(it);
|
it = m_activeVoices.erase(it);
|
||||||
|
@ -258,7 +273,7 @@ void Engine::removeSubmix(Submix* smx)
|
||||||
Sequencer* seq = it->get();
|
Sequencer* seq = it->get();
|
||||||
|
|
||||||
Submix* ssmx = seq->getSubmix();
|
Submix* ssmx = seq->getSubmix();
|
||||||
if (ssmx && ssmx == smx)
|
if (ssmx == smx)
|
||||||
{
|
{
|
||||||
seq->_destroy();
|
seq->_destroy();
|
||||||
it = m_activeSequencers.erase(it);
|
it = m_activeSequencers.erase(it);
|
||||||
|
@ -271,17 +286,24 @@ void Engine::removeSubmix(Submix* smx)
|
||||||
for (auto it = m_activeSubmixes.begin() ; it != m_activeSubmixes.end() ;)
|
for (auto it = m_activeSubmixes.begin() ; it != m_activeSubmixes.end() ;)
|
||||||
{
|
{
|
||||||
Submix* ssmx = it->getParentSubmix();
|
Submix* ssmx = it->getParentSubmix();
|
||||||
if (ssmx && ssmx == smx)
|
if (ssmx == smx)
|
||||||
{
|
{
|
||||||
it->_destroy();
|
it = _removeSubmix(&*it);
|
||||||
it = m_activeSubmixes.erase(it);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete submix */
|
/* Delete submix */
|
||||||
_destroySubmix(smx);
|
return _destroySubmix(smx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Remove Submix and deallocate */
|
||||||
|
void Engine::removeSubmix(Submix* smx)
|
||||||
|
{
|
||||||
|
if (!smx)
|
||||||
|
return;
|
||||||
|
_removeSubmix(smx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Start soundFX playing from loaded audio groups */
|
/** Start soundFX playing from loaded audio groups */
|
||||||
|
|
|
@ -46,7 +46,20 @@ void Sequencer::_destroy()
|
||||||
{
|
{
|
||||||
Entity::_destroy();
|
Entity::_destroy();
|
||||||
if (m_submix)
|
if (m_submix)
|
||||||
m_submix->m_activeSequencers.erase(this);
|
{
|
||||||
|
m_engine.removeSubmix(m_submix);
|
||||||
|
m_submix = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& chan : m_chanStates)
|
||||||
|
{
|
||||||
|
ChannelState& st = *chan.second;
|
||||||
|
if (st.m_submix)
|
||||||
|
{
|
||||||
|
m_engine.removeSubmix(st.m_submix);
|
||||||
|
st.m_submix = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Sequencer::~Sequencer() {}
|
Sequencer::~Sequencer() {}
|
||||||
|
@ -58,8 +71,6 @@ Sequencer::Sequencer(Engine& engine, const AudioGroup& group, int groupId,
|
||||||
auto it = m_songGroup.m_midiSetups.find(setupId);
|
auto it = m_songGroup.m_midiSetups.find(setupId);
|
||||||
if (it != m_songGroup.m_midiSetups.cend())
|
if (it != m_songGroup.m_midiSetups.cend())
|
||||||
m_midiSetup = it->second->data();
|
m_midiSetup = it->second->data();
|
||||||
if (m_submix)
|
|
||||||
m_submix->m_activeSequencers.insert(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Sequencer::ChannelState::~ChannelState()
|
Sequencer::ChannelState::~ChannelState()
|
||||||
|
|
|
@ -6,16 +6,11 @@ namespace amuse
|
||||||
void Submix::_destroy()
|
void Submix::_destroy()
|
||||||
{
|
{
|
||||||
m_destroyed = true;
|
m_destroyed = true;
|
||||||
if (m_submix)
|
|
||||||
m_submix->m_activeSubmixes.erase(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Submix::Submix(Engine& engine, Submix* smx)
|
Submix::Submix(Engine& engine, Submix* smx)
|
||||||
: m_root(engine), m_submix(smx)
|
: m_root(engine), m_submix(smx)
|
||||||
{
|
{}
|
||||||
if (m_submix)
|
|
||||||
m_submix->m_activeSubmixes.insert(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
EffectChorus& Submix::makeChorus(uint32_t baseDelay, uint32_t variation, uint32_t period)
|
EffectChorus& Submix::makeChorus(uint32_t baseDelay, uint32_t variation, uint32_t period)
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,8 +15,6 @@ namespace amuse
|
||||||
void Voice::_destroy()
|
void Voice::_destroy()
|
||||||
{
|
{
|
||||||
Entity::_destroy();
|
Entity::_destroy();
|
||||||
if (m_submix)
|
|
||||||
m_submix->m_activeVoices.erase(this);
|
|
||||||
|
|
||||||
for (std::shared_ptr<Voice>& vox : m_childVoices)
|
for (std::shared_ptr<Voice>& vox : m_childVoices)
|
||||||
vox->_destroy();
|
vox->_destroy();
|
||||||
|
@ -31,16 +29,12 @@ Voice::Voice(Engine& engine, const AudioGroup& group, int groupId, int vid, bool
|
||||||
: Entity(engine, group, groupId), m_vid(vid), m_emitter(emitter), m_submix(smx)
|
: Entity(engine, group, groupId), m_vid(vid), m_emitter(emitter), m_submix(smx)
|
||||||
{
|
{
|
||||||
//fprintf(stderr, "ALLOC %d\n", m_vid);
|
//fprintf(stderr, "ALLOC %d\n", m_vid);
|
||||||
if (m_submix)
|
|
||||||
m_submix->m_activeVoices.insert(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Voice::Voice(Engine& engine, const AudioGroup& group, int groupId, ObjectId oid, int vid, bool emitter, Submix* smx)
|
Voice::Voice(Engine& engine, const AudioGroup& group, int groupId, ObjectId oid, int vid, bool emitter, Submix* smx)
|
||||||
: Entity(engine, group, groupId, oid), m_vid(vid), m_emitter(emitter), m_submix(smx)
|
: Entity(engine, group, groupId, oid), m_vid(vid), m_emitter(emitter), m_submix(smx)
|
||||||
{
|
{
|
||||||
//fprintf(stderr, "ALLOC %d\n", m_vid);
|
//fprintf(stderr, "ALLOC %d\n", m_vid);
|
||||||
if (m_submix)
|
|
||||||
m_submix->m_activeVoices.insert(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Voice::_reset()
|
void Voice::_reset()
|
||||||
|
@ -197,6 +191,9 @@ std::shared_ptr<Voice> Voice::_allocateVoice(double sampleRate, bool dynamicPitc
|
||||||
|
|
||||||
std::list<std::shared_ptr<Voice>>::iterator Voice::_destroyVoice(Voice* voice)
|
std::list<std::shared_ptr<Voice>>::iterator Voice::_destroyVoice(Voice* voice)
|
||||||
{
|
{
|
||||||
|
if (voice->m_destroyed)
|
||||||
|
return m_childVoices.begin();
|
||||||
|
|
||||||
voice->_destroy();
|
voice->_destroy();
|
||||||
return m_childVoices.erase(voice->m_engineIt);
|
return m_childVoices.erase(voice->m_engineIt);
|
||||||
}
|
}
|
||||||
|
@ -644,16 +641,22 @@ void Voice::stopSample()
|
||||||
void Voice::setVolume(float vol)
|
void Voice::setVolume(float vol)
|
||||||
{
|
{
|
||||||
m_userVol = clamp(0.f, vol, 1.f);
|
m_userVol = clamp(0.f, vol, 1.f);
|
||||||
|
for (std::shared_ptr<Voice>& vox : m_childVoices)
|
||||||
|
vox->setVolume(vol);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Voice::setPan(float pan)
|
void Voice::setPan(float pan)
|
||||||
{
|
{
|
||||||
m_curPan = clamp(-1.f, pan, 1.f);
|
m_curPan = clamp(-1.f, pan, 1.f);
|
||||||
|
for (std::shared_ptr<Voice>& vox : m_childVoices)
|
||||||
|
vox->setPan(pan);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Voice::setSurroundPan(float span)
|
void Voice::setSurroundPan(float span)
|
||||||
{
|
{
|
||||||
m_curSpan = clamp(-1.f, span, 1.f);
|
m_curSpan = clamp(-1.f, span, 1.f);
|
||||||
|
for (std::shared_ptr<Voice>& vox : m_childVoices)
|
||||||
|
vox->setSurroundPan(span);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Voice::startEnvelope(double dur, float vol, const Curve* envCurve)
|
void Voice::startEnvelope(double dur, float vol, const Curve* envCurve)
|
||||||
|
@ -794,6 +797,9 @@ void Voice::setPitchWheel(float pitchWheel)
|
||||||
else
|
else
|
||||||
m_pitchWheelVal = 0;
|
m_pitchWheelVal = 0;
|
||||||
m_pitchDirty = true;
|
m_pitchDirty = true;
|
||||||
|
|
||||||
|
for (std::shared_ptr<Voice>& vox : m_childVoices)
|
||||||
|
vox->setPitchWheel(pitchWheel);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Voice::setPitchWheelRange(int8_t up, int8_t down)
|
void Voice::setPitchWheelRange(int8_t up, int8_t down)
|
||||||
|
@ -806,6 +812,8 @@ void Voice::setPitchWheelRange(int8_t up, int8_t down)
|
||||||
void Voice::setAftertouch(uint8_t aftertouch)
|
void Voice::setAftertouch(uint8_t aftertouch)
|
||||||
{
|
{
|
||||||
m_curAftertouch = aftertouch;
|
m_curAftertouch = aftertouch;
|
||||||
|
for (std::shared_ptr<Voice>& vox : m_childVoices)
|
||||||
|
vox->setAftertouch(aftertouch);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Voice::notifyCtrlChange(uint8_t ctrl, int8_t val)
|
void Voice::notifyCtrlChange(uint8_t ctrl, int8_t val)
|
||||||
|
@ -817,6 +825,9 @@ void Voice::notifyCtrlChange(uint8_t ctrl, int8_t val)
|
||||||
else
|
else
|
||||||
setPedal(false);
|
setPedal(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (std::shared_ptr<Voice>& vox : m_childVoices)
|
||||||
|
vox->notifyCtrlChange(ctrl, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Voice::getTotalVoices() const
|
size_t Voice::getTotalVoices() const
|
||||||
|
|
Loading…
Reference in New Issue