From afa1275af991ec0b57d3e20cb889a06a3a625355 Mon Sep 17 00:00:00 2001 From: Vesa Date: Fri, 4 Apr 2014 02:48:04 +0300 Subject: [PATCH] SampleBuffer: fix a segfault when moving a loop point while playing a note, also do some sptring cleanup (some unused/redundant variables removed) Also, some codepath optimization: add a method to SampleBuffer for setting all loop/start/endpoints at once, so we don't have to wait for mutex unlocks 4 times in a row. Then make AFP utilize this method. --- include/SampleBuffer.h | 14 +++- .../audio_file_processor.cpp | 10 +-- src/core/SampleBuffer.cpp | 74 +++++++------------ 3 files changed, 41 insertions(+), 57 deletions(-) diff --git a/include/SampleBuffer.h b/include/SampleBuffer.h index eeda62991..e53e4ab8c 100644 --- a/include/SampleBuffer.h +++ b/include/SampleBuffer.h @@ -71,7 +71,7 @@ public: { return m_isBackwards; } - + inline void setBackwards( bool _backwards ) { m_isBackwards = _backwards; @@ -81,7 +81,7 @@ public: private: f_cnt_t m_frameIndex; const bool m_varyingPitch; - bool m_isBackwards; + bool m_isBackwards; SRC_STATE * m_resamplingData; friend class SampleBuffer; @@ -148,6 +148,16 @@ public: m_varLock.unlock(); } + void setAllPointFrames( f_cnt_t _start, f_cnt_t _end, f_cnt_t _loopstart, f_cnt_t _loopend ) + { + m_varLock.lock(); + m_startFrame = _start; + m_endFrame = _end; + m_loopStartFrame = _loopstart; + m_loopEndFrame = _loopend; + m_varLock.unlock(); + } + inline f_cnt_t frames() const { return m_frames; diff --git a/plugins/audio_file_processor/audio_file_processor.cpp b/plugins/audio_file_processor/audio_file_processor.cpp index d285b4eaa..0988a60be 100644 --- a/plugins/audio_file_processor/audio_file_processor.cpp +++ b/plugins/audio_file_processor/audio_file_processor.cpp @@ -356,10 +356,7 @@ void audioFileProcessor::loopPointChanged( void ) m_nextPlayStartPoint = f_start; m_nextPlayBackwards = false; - m_sampleBuffer.setStartFrame( f_start ); - m_sampleBuffer.setEndFrame( f_end ); - m_sampleBuffer.setLoopStartFrame( f_loop ); - m_sampleBuffer.setLoopEndFrame( f_end ); + m_sampleBuffer.setAllPointFrames( f_start, f_end, f_loop, f_end ); emit dataChanged(); } @@ -735,11 +732,6 @@ void AudioFileProcessorWaveView::mousePressEvent( QMouseEvent * _me ) if( start_dist < loop_dist ) { dt = sample_start; md = start_dist; } else if( end_dist < loop_dist ) { dt = sample_end; md = end_dist; } -/* qDebug( "x %d", x ); - qDebug( "loopframex %d", m_loopFrameX ); - qDebug( "dt %d", dt ); - qDebug( "md %d", md );*/ - if( md < 4 ) { m_draggingType = dt; diff --git a/src/core/SampleBuffer.cpp b/src/core/SampleBuffer.cpp index 9ef094e0f..4fa587668 100644 --- a/src/core/SampleBuffer.cpp +++ b/src/core/SampleBuffer.cpp @@ -611,16 +611,14 @@ bool SampleBuffer::play( sampleFrame * _ab, handleState * _state, const fpp_t _frames, const float _freq, const LoopMode _loopmode ) -{ +{ QMutexLocker ml( &m_varLock ); - + f_cnt_t startFrame = m_startFrame; f_cnt_t endFrame = m_endFrame; f_cnt_t loopStartFrame = m_loopStartFrame; f_cnt_t loopEndFrame = m_loopEndFrame; - engine::mixer()->clearAudioBuffer( _ab, _frames ); - if( endFrame == 0 || _frames == 0 ) { return false; @@ -651,38 +649,26 @@ bool SampleBuffer::play( sampleFrame * _ab, handleState * _state, play_frame = startFrame; } - // this holds the number of remaining frames in current loop - f_cnt_t frames_for_loop; - if( _loopmode == LoopOn ) - { - play_frame = getLoopedIndex( play_frame, loopStartFrame, loopEndFrame ); - frames_for_loop = static_cast( ( loopEndFrame - play_frame ) / freq_factor ); - } - - else if( _loopmode == LoopPingPong ) - { - play_frame = getPingPongIndex( play_frame, loopStartFrame, loopEndFrame ); - if( is_backwards ) - frames_for_loop = static_cast( ( play_frame - loopStartFrame ) / freq_factor ); - else - frames_for_loop = static_cast( ( loopEndFrame - play_frame ) / freq_factor ); - } - - else + if( _loopmode == LoopOff ) { if( play_frame >= endFrame ) { return false; } - frames_for_loop = static_cast( ( endFrame - play_frame ) / freq_factor ); - - if( frames_for_loop == 0 ) - { - return false; - } + if( ( endFrame - play_frame ) / freq_factor == 0 ) return false; } - + + else if( _loopmode == LoopOn ) + { + play_frame = getLoopedIndex( play_frame, loopStartFrame, loopEndFrame ); + } + + else + { + play_frame = getPingPongIndex( play_frame, loopStartFrame, loopEndFrame ); + } + sampleFrame * tmp = NULL; @@ -693,7 +679,7 @@ bool SampleBuffer::play( sampleFrame * _ab, handleState * _state, // Generate output const f_cnt_t margin = 64; f_cnt_t fragment_size = (f_cnt_t)( _frames * freq_factor ) + margin; - src_data.data_in = + src_data.data_in = getSampleFragment( play_frame, fragment_size, _loopmode, &tmp, &is_backwards, loopStartFrame, loopEndFrame, endFrame )[0]; src_data.data_out = _ab[0]; @@ -749,7 +735,7 @@ bool SampleBuffer::play( sampleFrame * _ab, handleState * _state, // Generate output memcpy( _ab, - getSampleFragment( play_frame, _frames, _loopmode, &tmp, &is_backwards, + getSampleFragment( play_frame, _frames, _loopmode, &tmp, &is_backwards, loopStartFrame, loopEndFrame, endFrame ), _frames * BYTES_PER_FRAME ); // Advance @@ -782,7 +768,7 @@ bool SampleBuffer::play( sampleFrame * _ab, handleState * _state, } } - delete[] tmp; + if( tmp != NULL ) delete[] tmp; _state->setBackwards( is_backwards ); _state->setFrameIndex( play_frame ); @@ -795,10 +781,10 @@ bool SampleBuffer::play( sampleFrame * _ab, handleState * _state, sampleFrame * SampleBuffer::getSampleFragment( f_cnt_t _index, - f_cnt_t _frames, LoopMode _loopmode, sampleFrame * * _tmp, bool * _backwards, + f_cnt_t _frames, LoopMode _loopmode, sampleFrame * * _tmp, bool * _backwards, f_cnt_t _loopstart, f_cnt_t _loopend, f_cnt_t _end ) const { - + if( _loopmode == LoopOff ) { if( _index + _frames <= _end ) @@ -843,15 +829,17 @@ sampleFrame * SampleBuffer::getSampleFragment( f_cnt_t _index, else { f_cnt_t pos = _index; - bool backwards = *_backwards; + bool backwards = pos < _loopstart + ? false + : *_backwards; f_cnt_t copied = 0; + if( backwards ) { copied = qMin( _frames, pos - _loopstart ); for( int i=0; i < copied; i++ ) { - //memcpy( *_tmp + i, m_data + pos - i, BYTES_PER_FRAME ); (*_tmp)[i][0] = m_data[ pos - i ][0]; (*_tmp)[i][1] = m_data[ pos - i ][1]; } @@ -868,23 +856,17 @@ sampleFrame * SampleBuffer::getSampleFragment( f_cnt_t _index, while( copied < _frames ) { - if( pos >= _loopend ) backwards = true; - if( pos <= _loopstart ) backwards = false; - pos = qBound( _loopstart, pos, _loopend ); - /*qDebug( backwards ? "backwards" : "forwards" ); - qDebug( "pos %d", pos );*/ if( backwards ) { f_cnt_t todo = qMin( _frames - copied, pos - _loopstart ); for ( int i=0; i < todo; i++ ) { - //memcpy( *_tmp + ( copied + i ), m_data + ( pos - i ), BYTES_PER_FRAME ); (*_tmp)[ copied + i ][0] = m_data[ pos - i ][0]; (*_tmp)[ copied + i ][1] = m_data[ pos - i ][1]; } pos -= todo; copied += todo; - if( pos == _loopstart ) backwards = false; + if( pos <= _loopstart ) backwards = false; } else { @@ -892,7 +874,7 @@ sampleFrame * SampleBuffer::getSampleFragment( f_cnt_t _index, memcpy( *_tmp + copied, m_data + pos, todo * BYTES_PER_FRAME ); pos += todo; copied += todo; - if( pos == _loopend ) backwards = true; + if( pos >= _loopend ) backwards = true; } } *_backwards = backwards; @@ -924,8 +906,8 @@ f_cnt_t SampleBuffer::getPingPongIndex( f_cnt_t _index, f_cnt_t _startf, f_cnt_t const f_cnt_t looplen = _endf - _startf; const f_cnt_t looppos = ( _index - _endf ) % ( looplen*2 ); - return ( looppos < looplen ) - ? _endf - looppos + return ( looppos < looplen ) + ? _endf - looppos : _startf + ( looppos - looplen ); }