Skip to content

Commit

Permalink
New engine event interface
Browse files Browse the repository at this point in the history
  • Loading branch information
jackoalan committed Feb 15, 2017
1 parent aff8880 commit 5c8fa2e
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 43 deletions.
16 changes: 6 additions & 10 deletions driver/amuseplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ struct AppCallback : boo::IApplicationCallback
UpdateSongDisplay();
}

void SongLoop(const amuse::SongGroupIndex& index)
void SongLoop(const amuse::SongGroupIndex& index, boo::IAudioVoiceEngine& booEngine)
{
printf(
"░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n"
Expand Down Expand Up @@ -202,7 +202,7 @@ struct AppCallback : boo::IApplicationCallback
UpdateSongDisplay();
}

m_engine->pumpEngine();
m_win->waitForRetrace(&booEngine);

size_t voxCount;
int8_t progId;
Expand Down Expand Up @@ -231,8 +231,6 @@ struct AppCallback : boo::IApplicationCallback
m_seq.reset();
break;
}

m_win->waitForRetrace();
}
}

Expand Down Expand Up @@ -260,7 +258,7 @@ struct AppCallback : boo::IApplicationCallback
UpdateSFXDisplay();
}

void SFXLoop(const amuse::SFXGroupIndex& index)
void SFXLoop(const amuse::SFXGroupIndex& index, boo::IAudioVoiceEngine& booEngine)
{
printf("<space>: keyon/keyoff, <left/right>: cycle SFX, <up/down>: volume, <Q>: quit\n");

Expand Down Expand Up @@ -306,7 +304,7 @@ struct AppCallback : boo::IApplicationCallback
UpdateSFXDisplay();
}

m_engine->pumpEngine();
m_win->waitForRetrace(&booEngine);

if (m_vox && m_vox->state() == amuse::VoiceState::Dead)
{
Expand All @@ -322,8 +320,6 @@ struct AppCallback : boo::IApplicationCallback
m_seq.reset();
break;
}

m_win->waitForRetrace();
}
}

Expand Down Expand Up @@ -876,9 +872,9 @@ struct AppCallback : boo::IApplicationCallback

/* Enter playback loop */
if (m_sfxGroup)
SFXLoop(*sfxIndex);
SFXLoop(*sfxIndex, *voxEngine);
else
SongLoop(*songIndex);
SongLoop(*songIndex, *voxEngine);

printf("\n\n");
}
Expand Down
2 changes: 1 addition & 1 deletion driver/amuserender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ int main(int argc, const boo::SystemChar** argv)
signal(SIGINT, SIGINTHandler);
do
{
engine.pumpEngine();
voxEngine->pumpAndMixVoices();
wroteFrames += voxEngine->get5MsFrames();
printf("\rFrame %" PRISize, wroteFrames);
fflush(stdout);
Expand Down
9 changes: 5 additions & 4 deletions include/amuse/BooBackend.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,22 +116,23 @@ class BooBackendMIDIReader : public IMIDIReader, public boo::IMIDIReader
};

/** Backend voice allocator implementation for boo mixer */
class BooBackendVoiceAllocator : public IBackendVoiceAllocator
class BooBackendVoiceAllocator : public IBackendVoiceAllocator, public boo::IAudioVoiceEngineCallback
{
friend class BooBackendMIDIReader;
boo::IAudioVoiceEngine& m_booEngine;
Engine* m_cbInterface = nullptr;

public:
BooBackendVoiceAllocator(boo::IAudioVoiceEngine& booEngine);
std::unique_ptr<IBackendVoice> allocateVoice(Voice& clientVox, double sampleRate, bool dynamicPitch);
std::unique_ptr<IBackendSubmix> allocateSubmix(Submix& clientSmx, bool mainOut, int busId);
std::vector<std::pair<std::string, std::string>> enumerateMIDIDevices();
std::unique_ptr<IMIDIReader> allocateMIDIReader(Engine& engine, const char* name = nullptr);
void register5MsCallback(std::function<void(double)>&& callback);
void unregister5MsCallback();
void setCallbackInterface(Engine* engine);
AudioChannelSet getAvailableSet();
void pumpAndMixVoices();
void setVolume(float vol);
void on5MsInterval(boo::IAudioVoiceEngine& engine, double dt);
void onPumpCycleComplete(boo::IAudioVoiceEngine& engine);
};
}

Expand Down
12 changes: 8 additions & 4 deletions include/amuse/Engine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ class Engine
std::list<std::shared_ptr<Sequencer>>::iterator
_destroySequencer(std::list<std::shared_ptr<Sequencer>>::iterator it);
void _bringOutYourDead();
void _5MsCallback(double dt);

public:
~Engine();
Expand All @@ -74,9 +73,6 @@ class Engine
/** Access voice backend of engine */
IBackendVoiceAllocator& getBackend() { return m_backend; }

/** Update all active audio entities and fill OS audio buffers as needed */
void pumpEngine();

/** Add audio group data pointers to engine; must remain resident! */
const AudioGroup* addAudioGroup(const AudioGroupData& data);

Expand Down Expand Up @@ -130,6 +126,14 @@ class Engine

/** Obtain list of active sequencers */
std::list<std::shared_ptr<Sequencer>>& getActiveSequencers() { return m_activeSequencers; }

/** All mixing occurs in virtual 5ms intervals;
* this is called at the start of each interval for all mixable entities */
void _on5MsInterval(IBackendVoiceAllocator& engine, double dt);

/** When a pumping cycle is complete this is called to allow the client to
* perform periodic cleanup tasks */
void _onPumpCycleComplete(IBackendVoiceAllocator& engine);
};
}

Expand Down
10 changes: 2 additions & 8 deletions include/amuse/IBackendVoiceAllocator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,11 @@ class IBackendVoiceAllocator
/** Amuse obtains speaker-configuration from the platform this way */
virtual AudioChannelSet getAvailableSet() = 0;

/** Amuse flushes voice samples to the backend this way */
virtual void pumpAndMixVoices() = 0;

/** Set volume of main mix out */
virtual void setVolume(float vol) = 0;

/** Amuse may request callbacks 200-updates-per-second virtually */
virtual void register5MsCallback(std::function<void(double dt)>&& callback) = 0;

/** This is important to ensure orderly cleanup */
virtual void unregister5MsCallback() = 0;
/** Amuse registers for key callback events from the mixing engine this way */
virtual void setCallbackInterface(Engine* engine) = 0;
};
}

Expand Down
29 changes: 19 additions & 10 deletions lib/BooBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,11 @@ void BooBackendMIDIReader::stopSeq() {}

void BooBackendMIDIReader::reset() {}

BooBackendVoiceAllocator::BooBackendVoiceAllocator(boo::IAudioVoiceEngine& booEngine) : m_booEngine(booEngine) {}
BooBackendVoiceAllocator::BooBackendVoiceAllocator(boo::IAudioVoiceEngine& booEngine)
: m_booEngine(booEngine)
{
booEngine.setCallbackInterface(this);
}

std::unique_ptr<IBackendVoice> BooBackendVoiceAllocator::allocateVoice(Voice& clientVox, double sampleRate,
bool dynamicPitch)
Expand All @@ -280,19 +284,24 @@ std::unique_ptr<IMIDIReader> BooBackendVoiceAllocator::allocateMIDIReader(Engine
return ret;
}

void BooBackendVoiceAllocator::register5MsCallback(std::function<void(double)>&& callback)
{
m_booEngine.register5MsCallback(std::move(callback));
}

void BooBackendVoiceAllocator::unregister5MsCallback()
void BooBackendVoiceAllocator::setCallbackInterface(Engine* engine)
{
m_booEngine.unregister5MsCallback();
m_cbInterface = engine;
}

AudioChannelSet BooBackendVoiceAllocator::getAvailableSet() { return AudioChannelSet(m_booEngine.getAvailableSet()); }

void BooBackendVoiceAllocator::pumpAndMixVoices() { m_booEngine.pumpAndMixVoices(); }

void BooBackendVoiceAllocator::setVolume(float vol) { m_booEngine.setVolume(vol); }

void BooBackendVoiceAllocator::on5MsInterval(boo::IAudioVoiceEngine& engine, double dt)
{
if (m_cbInterface)
m_cbInterface->_on5MsInterval(*this, dt);
}

void BooBackendVoiceAllocator::onPumpCycleComplete(boo::IAudioVoiceEngine& engine)
{
if (m_cbInterface)
m_cbInterface->_onPumpCycleComplete(*this);
}
}
10 changes: 4 additions & 6 deletions lib/Engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ static const float FullLevels[8] = {1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f};

Engine::~Engine()
{
m_backend.unregister5MsCallback();
m_backend.setCallbackInterface(nullptr);
for (std::shared_ptr<Sequencer>& seq : m_activeSequencers)
if (!seq->m_destroyed)
seq->_destroy();
Expand All @@ -31,7 +31,7 @@ Engine::Engine(IBackendVoiceAllocator& backend, AmplitudeMode ampMode)
m_defaultStudio->getAuxA().makeReverbStd(0.5f, 0.8f, 3.0f, 0.5f, 0.1f);
m_defaultStudio->getAuxB().makeChorus(15, 0, 500);
m_defaultStudioReady = true;
backend.register5MsCallback(std::bind(&Engine::_5MsCallback, this, std::placeholders::_1));
m_backend.setCallbackInterface(this);
m_midiReader = backend.allocateMIDIReader(*this);
}

Expand Down Expand Up @@ -172,18 +172,16 @@ void Engine::_bringOutYourDead()
}
}

void Engine::_5MsCallback(double dt)
void Engine::_on5MsInterval(IBackendVoiceAllocator& engine, double dt)
{
if (m_midiReader)
m_midiReader->pumpReader(dt);
for (std::shared_ptr<Sequencer>& seq : m_activeSequencers)
seq->advance(dt);
}

/** Update all active audio entities and fill OS audio buffers as needed */
void Engine::pumpEngine()
void Engine::_onPumpCycleComplete(IBackendVoiceAllocator& engine)
{
m_backend.pumpAndMixVoices();
_bringOutYourDead();

/* Determine lowest available free vid */
Expand Down

0 comments on commit 5c8fa2e

Please sign in to comment.