Skip to content

Instantly share code, notes, and snippets.

@elliotwoods
Created January 6, 2016 11:16
Show Gist options
  • Save elliotwoods/4382780f68c46ae631af to your computer and use it in GitHub Desktop.
Save elliotwoods/4382780f68c46ae631af to your computer and use it in GitHub Desktop.
#include "SoundEffects.h"
//----------
void SoundEffects::audioOut(ofSoundBuffer & out) {
auto numFrames = out.getNumFrames();
const auto interval = this->getInterval();
const auto intervalFrames = 44100 * interval;
for(int i=0; i<numFrames; i++) {
out[i * 2 + 0] = 0.0f;
out[i * 2 + 1] = 0.0f;
if(this->enabled && !this->idling) {
//check if this frame we start a tick
if(this->framesUntilNextTick <= 0) {
//select the tick sound
auto isBigTick = this->tickIndex++ % 6 == 0;
auto & tickSound = isBigTick ? ofxAssets::sound("tick_big") : ofxAssets::sound("tick_small");
//add it to the active sounds
this->play(tickSound.buffer);
//set the next tick sound
this->framesUntilNextTick = intervalFrames;
}
//check interval doesn't go too long
if(this->framesUntilNextTick > intervalFrames) {
//e.g. this might happen at next buffer fill
this->framesUntilNextTick = intervalFrames;
}
this->framesUntilNextTick--;
}
if(this->idling) {
if(this->framesUntilNextIdleSound <= 0) {
auto & idlingSound = ofxAssets::sound("idle").buffer;
this->play(idlingSound);
this->framesUntilNextIdleSound = idlingSound.getNumFrames();
}
this->framesUntilNextIdleSound--;
}
//delete all dead sounds and play active ones
this->activeSoundsLock.lock();
for(auto it = this->activeSounds.begin(); it != this->activeSounds.end(); ) {
auto & activeSound = *it;
//check if needs deleting
if(activeSound.frameIndex >= activeSound.sound->getNumFrames()) {
it = this->activeSounds.erase(it);
continue; // skip to next sound
} else {
it++;
}
//play it otherwise
out[i * 2 + 0] += activeSound.sound->getSample(activeSound.frameIndex, 0);
out[i * 2 + 1] += activeSound.sound->getSample(activeSound.frameIndex, 1);
//progress the playhead
activeSound.frameIndex++;
}
this->activeSoundsLock.unlock();
}
}
//----------
void SoundEffects::begin() {
auto & beginSound = ofxAssets::sound("begin").buffer;
this->play(beginSound);
this->framesUntilNextIdleSound = beginSound.getNumFrames() + 44100;
this->idling = true;
}
//----------
void SoundEffects::end(bool success) {
this->idling = false;
//stop any existing playing idling sounds
this->activeSoundsLock.lock();
{
auto searchingFor = & ofxAssets::sound("idle").buffer;
for(auto it = this->activeSounds.begin(); it != this->activeSounds.end(); it++) {
if(it->sound == searchingFor) {
this->activeSounds.erase(it);
break;
}
}
}
this->activeSoundsLock.unlock();
if(success) {
this->play(ofxAssets::sound("end").buffer);
} else {
this->play(ofxAssets::sound("endFail").buffer);
}
}
//----------
void SoundEffects::setContinuousValue(float value) {
this->value = value;
}
//----------
void SoundEffects::setContinuousEnabled(bool enabled) {
this->enabled = enabled;
}
//----------
float SoundEffects::getInterval() const {
return 1.0f / pow (2.0f, this->value / 0.12f);
}
//----------
void SoundEffects::play(ofSoundBuffer & soundBuffer) {
ActiveSound sound = {
& soundBuffer, 0
};
this->activeSoundsLock.lock();
this->activeSounds.push_back(sound);
this->activeSoundsLock.unlock();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment