Skip to content

Commit

Permalink
Cope with zero-duration effects (#11)
Browse files Browse the repository at this point in the history
* Cope with zero-duration effects.

Closes microbit-foundation/codal-microbit#149

* Use same code path for zero and positive duration
  • Loading branch information
microbit-matt-hillsdon committed Nov 2, 2020
1 parent b040865 commit bea9f66
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 11 deletions.
3 changes: 2 additions & 1 deletion inc/SoundEmojiSynthesizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,9 @@ namespace codal

/**
* Schedules the next sound effect as defined in the effectBuffer, if available.
* @return true if we've just completed a buffer of effects, false otherwise.
*/
void nextSoundEffect();
bool nextSoundEffect();

/**
* Schedules playout of the given sound effect.
Expand Down
23 changes: 13 additions & 10 deletions source/SoundEmojiSynthesizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,17 @@ void SoundEmojiSynthesizer::stop() {

/**
* Schedules the next sound effect as defined in the effectBuffer, if available.
* @return true if we've just completed a buffer of effects, false otherwise.
*/
void SoundEmojiSynthesizer::nextSoundEffect()
bool SoundEmojiSynthesizer::nextSoundEffect()
{
const bool hadEffect = effect != NULL;
if (status & EMOJI_SYNTHESIZER_STATUS_STOPPING)
{
effect = NULL;
effectBuffer = emptyBuffer;
}

// If a sequence of SoundEffects are being played, attempt to move on to the next.
// If not, select the first in the buffer.
if (effect)
Expand All @@ -149,14 +157,14 @@ void SoundEmojiSynthesizer::nextSoundEffect()
// if we have an effect with a negative duration, reset the buffer (unless there is an update pending)
effect = (SoundEffect *) &effectBuffer[0];

if (effect->duration > 0 || lock.getWaitCount() > 0)
if (effect->duration >= 0 || lock.getWaitCount() > 0)
{
effect = NULL;
effectBuffer = emptyBuffer;
samplesWritten = 0;
samplesToWrite = 0;
position = 0.0f;
return;
return hadEffect;
}
}

Expand All @@ -173,6 +181,7 @@ void SoundEmojiSynthesizer::nextSoundEffect()
effect->effects[i].steps = max(effect->effects[i].steps, 1);
samplesPerStep[i] = (float) samplesToWrite / (float) effect->effects[i].steps;
}
return false;
}

/**
Expand All @@ -190,13 +199,7 @@ ManagedBuffer SoundEmojiSynthesizer::pull()
{
if (samplesWritten == samplesToWrite || status & EMOJI_SYNTHESIZER_STATUS_STOPPING)
{
bool renderComplete = samplesWritten > 0;
if (status & EMOJI_SYNTHESIZER_STATUS_STOPPING)
{
effect = NULL;
effectBuffer = emptyBuffer;
}
nextSoundEffect();
bool renderComplete = nextSoundEffect();

// If we have just completed active playout of an effect, and there are no more effects scheduled,
// unblock any fibers that may be waiting to play a sound effect.
Expand Down

0 comments on commit bea9f66

Please sign in to comment.