Makes LFO sync with the timeline of the song

This commit is contained in:
Wong Cho Ching
2014-01-31 12:04:02 +08:00
parent c484ee8345
commit 37dd8fc5ac
3 changed files with 34 additions and 58 deletions

View File

@@ -78,17 +78,14 @@ LfoController::~LfoController()
// definately be optimized.
// The code should probably be integrated with the oscillator class. But I
// don't know how to use oscillator because it is so confusing
float LfoController::value( int _offset )
{
int frame = runningFrames() + _offset + m_phaseCorrection;
// Recalculate speed each period
// Actually, _offset != only if HQ, and we may want to recalc in that case,
// so this statement may be unrequired
if (_offset == 0) {
// The new duration in frames
//If the song is playing, sync the value with the time of the song.
if( engine::getSong()->isPlaying() )
{
// The new duration in frames
// (Samples/Second) / (periods/second) = (Samples/cycle)
float newDurationF =
engine::mixer()->processingSampleRate() *
@@ -107,39 +104,17 @@ float LfoController::value( int _offset )
default:
break;
}
m_phaseOffset = qRound(
m_phaseModel.value() * newDurationF / 360.0 );
m_phaseModel.value() * newDurationF / 360.0 );
int newDuration = static_cast<int>( newDurationF );
m_phaseCorrection = static_cast<int>(engine::getSong()->getTicks()*engine::framesPerTick())%newDuration
+ m_phaseOffset;
if (newDuration != m_duration) {
// frame offset
// (Samples - Samples) = Samples
float oldFramePhase = float(frame % m_duration);
// Phase between 0 and 1
// (Samples/Samples) = factor
float phase = oldFramePhase / m_duration;
// where we SHOULD be according to new frequency
// (factor*Samples) = Samples
int newFrameOffset = static_cast<int>( phase * newDuration );
// recalc
// (Samples - (Samples-Samples)) = Samples
// Go back to beginning of last natural period
m_phaseCorrection = -(runningFrames()%newDuration);
// newFrameOffset has old phaseCorrection built-in
m_phaseCorrection += newFrameOffset;
// re-run the first calculation again
frame = runningFrames() + m_phaseCorrection;
m_duration = newDuration;
}
// re-run the first calculation again
frame = m_phaseCorrection + _offset;
}
// speedModel 0..1 fast..slow 0ms..20000ms

View File

@@ -284,27 +284,27 @@ void song::savePos()
if( tl != NULL )
{
switch( tl->behaviourAtStop() )
{
case timeLine::BackToZero:
m_playPos[m_playMode].setTicks( 0 );
m_elapsedMilliSeconds = 0;
break;
switch( tl->behaviourAtStop() )
{
case timeLine::BackToZero:
m_playPos[m_playMode].setTicks( 0 );
m_elapsedMilliSeconds = 0;
break;
case timeLine::BackToStart:
if( tl->savedPos() >= 0 )
{
m_playPos[m_playMode].setTicks(
tl->savedPos().getTicks() );
m_elapsedMilliSeconds = (((tl->savedPos().getTicks())*60*1000/48)/getTempo());
tl->savePos( -1 );
}
break;
case timeLine::BackToStart:
if( tl->savedPos() >= 0 )
{
m_playPos[m_playMode].setTicks(
tl->savedPos().getTicks() );
m_elapsedMilliSeconds = (((tl->savedPos().getTicks())*60*1000/48)/getTempo());
tl->savePos( -1 );
}
break;
case timeLine::KeepStopPosition:
default:
break;
}
case timeLine::KeepStopPosition:
default:
break;
}
}
else
@@ -636,7 +636,7 @@ bool song::realTimeTask() const
void song::playSong()
void song::playSong()
{
m_recording = false;
@@ -648,7 +648,6 @@ void song::playSong()
m_playMode = Mode_PlaySong;
m_playing = true;
m_paused = false;
m_actions.push_front( ActionPlaySong );
savePos();
if(QApplication::type() != QApplication::Tty) {

View File

@@ -711,6 +711,8 @@ static inline void animateScroll( QScrollBar *scrollBar, int newVal, bool smooth
}
void songEditor::updatePosition( const MidiTime & _t )
{
int widgetWidth, trackOpWidth;