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<Sequencer>>::iterator _destroySequencer(Sequencer* sequencer);
|
||||
std::list<Submix>::iterator _destroySubmix(Submix* smx);
|
||||
std::list<Submix>::iterator _removeSubmix(Submix* smx);
|
||||
void _bringOutYourDead();
|
||||
public:
|
||||
~Engine();
|
||||
|
|
|
@ -30,8 +30,8 @@ class Entity
|
|||
* but shared_ptrs are issued to the client so it can safely track state */
|
||||
friend class Engine;
|
||||
friend class SoundMacroState;
|
||||
bool m_destroyed = false;
|
||||
protected:
|
||||
bool m_destroyed = false;
|
||||
void _destroy()
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
|
|
|
@ -26,9 +26,6 @@ class Submix
|
|||
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::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 */
|
||||
bool m_destroyed = false;
|
||||
void _destroy();
|
||||
|
|
|
@ -11,7 +11,17 @@
|
|||
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)
|
||||
: m_backend(backend)
|
||||
|
@ -75,6 +85,8 @@ std::list<std::shared_ptr<Voice>>::iterator Engine::_destroyVoice(Voice* voice)
|
|||
#ifndef NDEBUG
|
||||
assert(this == &voice->getEngine());
|
||||
#endif
|
||||
if (voice->m_destroyed)
|
||||
return m_activeVoices.begin();
|
||||
voice->_destroy();
|
||||
return m_activeVoices.erase(voice->m_engineIt);
|
||||
}
|
||||
|
@ -84,6 +96,8 @@ std::list<std::shared_ptr<Sequencer>>::iterator Engine::_destroySequencer(Sequen
|
|||
#ifndef NDEBUG
|
||||
assert(this == &sequencer->getEngine());
|
||||
#endif
|
||||
if (sequencer->m_destroyed)
|
||||
return m_activeSequencers.begin();
|
||||
sequencer->_destroy();
|
||||
return m_activeSequencers.erase(sequencer->m_engineIt);
|
||||
}
|
||||
|
@ -93,6 +107,8 @@ std::list<Submix>::iterator Engine::_destroySubmix(Submix* smx)
|
|||
#ifndef NDEBUG
|
||||
assert(this == &smx->getEngine());
|
||||
#endif
|
||||
if (smx->m_destroyed)
|
||||
return m_activeSubmixes.begin();
|
||||
smx->_destroy();
|
||||
return m_activeSubmixes.erase(smx->m_engineIt);
|
||||
}
|
||||
|
@ -234,8 +250,7 @@ Submix* Engine::addSubmix(Submix* smx)
|
|||
return _allocateSubmix(smx);
|
||||
}
|
||||
|
||||
/** Remove Submix and deallocate */
|
||||
void Engine::removeSubmix(Submix* smx)
|
||||
std::list<Submix>::iterator Engine::_removeSubmix(Submix* smx)
|
||||
{
|
||||
/* Delete all voices bound to submix */
|
||||
for (auto it = m_activeVoices.begin() ; it != m_activeVoices.end() ;)
|
||||
|
@ -243,7 +258,7 @@ void Engine::removeSubmix(Submix* smx)
|
|||
Voice* vox = it->get();
|
||||
|
||||
Submix* vsmx = vox->getSubmix();
|
||||
if (vsmx && vsmx == smx)
|
||||
if (vsmx == smx)
|
||||
{
|
||||
vox->_destroy();
|
||||
it = m_activeVoices.erase(it);
|
||||
|
@ -258,7 +273,7 @@ void Engine::removeSubmix(Submix* smx)
|
|||
Sequencer* seq = it->get();
|
||||
|
||||
Submix* ssmx = seq->getSubmix();
|
||||
if (ssmx && ssmx == smx)
|
||||
if (ssmx == smx)
|
||||
{
|
||||
seq->_destroy();
|
||||
it = m_activeSequencers.erase(it);
|
||||
|
@ -271,17 +286,24 @@ void Engine::removeSubmix(Submix* smx)
|
|||
for (auto it = m_activeSubmixes.begin() ; it != m_activeSubmixes.end() ;)
|
||||
{
|
||||
Submix* ssmx = it->getParentSubmix();
|
||||
if (ssmx && ssmx == smx)
|
||||
if (ssmx == smx)
|
||||
{
|
||||
it->_destroy();
|
||||
it = m_activeSubmixes.erase(it);
|
||||
it = _removeSubmix(&*it);
|
||||
continue;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
|
|
|
@ -46,7 +46,20 @@ void Sequencer::_destroy()
|
|||
{
|
||||
Entity::_destroy();
|
||||
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() {}
|
||||
|
@ -58,8 +71,6 @@ Sequencer::Sequencer(Engine& engine, const AudioGroup& group, int groupId,
|
|||
auto it = m_songGroup.m_midiSetups.find(setupId);
|
||||
if (it != m_songGroup.m_midiSetups.cend())
|
||||
m_midiSetup = it->second->data();
|
||||
if (m_submix)
|
||||
m_submix->m_activeSequencers.insert(this);
|
||||
}
|
||||
|
||||
Sequencer::ChannelState::~ChannelState()
|
||||
|
|
|
@ -6,16 +6,11 @@ namespace amuse
|
|||
void Submix::_destroy()
|
||||
{
|
||||
m_destroyed = true;
|
||||
if (m_submix)
|
||||
m_submix->m_activeSubmixes.erase(this);
|
||||
}
|
||||
|
||||
Submix::Submix(Engine& engine, 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)
|
||||
{
|
||||
|
|
|
@ -15,8 +15,6 @@ namespace amuse
|
|||
void Voice::_destroy()
|
||||
{
|
||||
Entity::_destroy();
|
||||
if (m_submix)
|
||||
m_submix->m_activeVoices.erase(this);
|
||||
|
||||
for (std::shared_ptr<Voice>& vox : m_childVoices)
|
||||
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)
|
||||
{
|
||||
//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)
|
||||
: Entity(engine, group, groupId, oid), m_vid(vid), m_emitter(emitter), m_submix(smx)
|
||||
{
|
||||
//fprintf(stderr, "ALLOC %d\n", m_vid);
|
||||
if (m_submix)
|
||||
m_submix->m_activeVoices.insert(this);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (voice->m_destroyed)
|
||||
return m_childVoices.begin();
|
||||
|
||||
voice->_destroy();
|
||||
return m_childVoices.erase(voice->m_engineIt);
|
||||
}
|
||||
|
@ -644,16 +641,22 @@ void Voice::stopSample()
|
|||
void Voice::setVolume(float vol)
|
||||
{
|
||||
m_userVol = clamp(0.f, vol, 1.f);
|
||||
for (std::shared_ptr<Voice>& vox : m_childVoices)
|
||||
vox->setVolume(vol);
|
||||
}
|
||||
|
||||
void Voice::setPan(float pan)
|
||||
{
|
||||
m_curPan = clamp(-1.f, pan, 1.f);
|
||||
for (std::shared_ptr<Voice>& vox : m_childVoices)
|
||||
vox->setPan(pan);
|
||||
}
|
||||
|
||||
void Voice::setSurroundPan(float span)
|
||||
{
|
||||
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)
|
||||
|
@ -794,6 +797,9 @@ void Voice::setPitchWheel(float pitchWheel)
|
|||
else
|
||||
m_pitchWheelVal = 0;
|
||||
m_pitchDirty = true;
|
||||
|
||||
for (std::shared_ptr<Voice>& vox : m_childVoices)
|
||||
vox->setPitchWheel(pitchWheel);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
m_curAftertouch = aftertouch;
|
||||
for (std::shared_ptr<Voice>& vox : m_childVoices)
|
||||
vox->setAftertouch(aftertouch);
|
||||
}
|
||||
|
||||
void Voice::notifyCtrlChange(uint8_t ctrl, int8_t val)
|
||||
|
@ -817,6 +825,9 @@ void Voice::notifyCtrlChange(uint8_t ctrl, int8_t val)
|
|||
else
|
||||
setPedal(false);
|
||||
}
|
||||
|
||||
for (std::shared_ptr<Voice>& vox : m_childVoices)
|
||||
vox->notifyCtrlChange(ctrl, val);
|
||||
}
|
||||
|
||||
size_t Voice::getTotalVoices() const
|
||||
|
|
Loading…
Reference in New Issue