Skip to content

Commit

Permalink
Add sequencer fade times
Browse files Browse the repository at this point in the history
  • Loading branch information
jackoalan committed Feb 27, 2017
1 parent 5c8fa2e commit a23af16
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 12 deletions.
2 changes: 1 addition & 1 deletion driver/amuseplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ struct AppCallback : boo::IApplicationCallback
m_setupId = setupId;
if (m_seq)
{
m_seq->stopSong(true);
m_seq->stopSong(0.f, true);
m_seq->kill();
}
m_seq = m_engine->seqPlay(m_groupId, setupId, nullptr);
Expand Down
9 changes: 7 additions & 2 deletions include/amuse/Sequencer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ class Sequencer : public Entity
bool m_dieOnEnd = false; /**< Sequencer will be killed when current arrangement completes */

float m_curVol = 1.f; /**< Current volume of sequencer */
float m_volFadeTime = 0.f;
float m_volFadeTarget = 0.f;
float m_volFadeStart = 0.f;
float m_stopFadeTime = 0.f;
float m_stopFadeBeginVol = 0.f;

/** State of a single MIDI channel */
struct ChannelState
Expand Down Expand Up @@ -135,10 +140,10 @@ class Sequencer : public Entity
void playSong(const unsigned char* arrData, bool dieOnEnd = true);

/** Stop current MIDI arrangement */
void stopSong(bool now = false);
void stopSong(float fadeTime = 0.f, bool now = false);

/** Set total volume of sequencer */
void setVolume(float vol);
void setVolume(float vol, float fadeTime = 0.f);

/** Get current program number of channel */
int8_t getChanProgram(int8_t chanId) const;
Expand Down
68 changes: 59 additions & 9 deletions lib/Sequencer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,12 +149,45 @@ Sequencer::ChannelState::ChannelState(Sequencer& parent, uint8_t chanId) : m_par
void Sequencer::advance(double dt)
{
if (m_state == SequencerState::Playing)
{
if (m_stopFadeTime)
{
float step = dt / m_stopFadeTime * m_stopFadeBeginVol;
float vol = std::max(0.f, m_curVol - step);
if (vol == 0.f)
{
m_arrData = nullptr;
m_state = SequencerState::Interactive;
allOff(true);
m_stopFadeTime = 0.f;
return;
}
else
{
setVolume(vol);
}
}
else if (m_volFadeTime)
{
float step = dt / m_volFadeTime * std::fabsf(m_volFadeTarget - m_volFadeStart);
float vol;
if (m_curVol < m_volFadeTarget)
vol = std::min(m_volFadeTarget, m_curVol + step);
else if (m_curVol >= m_volFadeTarget)
vol = std::max(m_volFadeTarget, m_curVol - step);
if (vol == m_volFadeTarget)
m_volFadeTime = 0.f;
else
setVolume(vol);
}

if (m_songState.advance(*this, dt))
{
m_arrData = nullptr;
m_state = SequencerState::Interactive;
allOff();
}
}
}

size_t Sequencer::ChannelState::getVoiceCount() const
Expand Down Expand Up @@ -536,11 +569,19 @@ void Sequencer::playSong(const unsigned char* arrData, bool dieOnEnd)
m_state = SequencerState::Playing;
}

void Sequencer::stopSong(bool now)
void Sequencer::stopSong(float fadeTime, bool now)
{
allOff(now);
m_arrData = nullptr;
m_state = SequencerState::Interactive;
if (fadeTime == 0.f)
{
allOff(now);
m_arrData = nullptr;
m_state = SequencerState::Interactive;
}
else
{
m_stopFadeTime = fadeTime;
m_stopFadeBeginVol = m_curVol;
}
}

void Sequencer::ChannelState::setVolume(float vol)
Expand Down Expand Up @@ -574,12 +615,21 @@ void Sequencer::ChannelState::setPan(float pan)
}
}

void Sequencer::setVolume(float vol)
void Sequencer::setVolume(float vol, float fadeTime)
{
m_curVol = vol;
for (auto& chan : m_chanStates)
if (chan)
chan->setVolume(chan->m_curVol);
if (fadeTime == 0.f)
{
m_curVol = vol;
for (auto& chan : m_chanStates)
if (chan)
chan->setVolume(chan->m_curVol);
}
else
{
m_volFadeTime = fadeTime;
m_volFadeTarget = vol;
m_volFadeStart = m_curVol;
}
}

int8_t Sequencer::getChanProgram(int8_t chanId) const
Expand Down

0 comments on commit a23af16

Please sign in to comment.