From ee631ad210eb2178b621908304af02ef190f57ba Mon Sep 17 00:00:00 2001 From: Tobias Doerffel Date: Fri, 22 Aug 2008 17:31:45 +0000 Subject: [PATCH] fixed crashes when automating start- and end-point in AudioFileProcessor (closes #2048125) git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@1461 0778d3d1-df1d-0410-868b-ea421aaaa00d --- ChangeLog | 10 +++ include/sample_buffer.h | 20 ++++-- .../audio_file_processor.cpp | 61 +++++-------------- .../audio_file_processor.h | 3 +- src/core/sample_buffer.cpp | 56 +++++++++-------- 5 files changed, 72 insertions(+), 78 deletions(-) diff --git a/ChangeLog b/ChangeLog index 597eb6e1b..0632d4534 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ 2008-08-22 Tobias Doerffel + * plugins/audio_file_processor/audio_file_processor.cpp: + * plugins/audio_file_processor/audio_file_processor.h: + * include/sample_buffer.h: + * src/core/sample_buffer.cpp: + fixed crashes when automating start- and end-point in + AudioFileProcessor (closes #2048125) + + * include/oscillator.h: + made oscillator::userWaveSample() const + * include/instrument_track.h: * src/gui/file_browser.cpp: * src/tracks/instrument_track.cpp: diff --git a/include/sample_buffer.h b/include/sample_buffer.h index a59ff5fc8..8218459bc 100644 --- a/include/sample_buffer.h +++ b/include/sample_buffer.h @@ -26,6 +26,7 @@ #ifndef _SAMPLE_BUFFER_H #define _SAMPLE_BUFFER_H +#include #include #include @@ -75,7 +76,7 @@ public: bool play( sampleFrame * _ab, handleState * _state, const fpp_t _frames, const float _freq, - const bool _looped = FALSE ) const; + const bool _looped = FALSE ); void visualize( QPainter & _p, const QRect & _dr, const QRect & _clip ); inline void visualize( QPainter & _p, const QRect & _dr ) @@ -100,12 +101,16 @@ public: void setLoopStartFrame( f_cnt_t _start ) { - m_loop_startFrame = _start; + m_varLock.lock(); + m_loopStartFrame = _start; + m_varLock.unlock(); } void setLoopEndFrame( f_cnt_t _end ) { - m_loop_endFrame = _end; + m_varLock.lock(); + m_loopEndFrame = _end; + m_varLock.unlock(); } inline f_cnt_t frames( void ) const @@ -130,12 +135,16 @@ public: inline void setFrequency( float _freq ) { + m_varLock.lock(); m_frequency = _freq; + m_varLock.unlock(); } inline void setSampleRate( sample_rate_t _rate ) { + m_varLock.lock(); m_sampleRate = _rate; + m_varLock.unlock(); } inline const sampleFrame * data( void ) const @@ -219,11 +228,12 @@ private: sampleFrame * m_origData; f_cnt_t m_origFrames; sampleFrame * m_data; + QMutex m_varLock; f_cnt_t m_frames; f_cnt_t m_startFrame; f_cnt_t m_endFrame; - f_cnt_t m_loop_startFrame; - f_cnt_t m_loop_endFrame; + f_cnt_t m_loopStartFrame; + f_cnt_t m_loopEndFrame; float m_amplification; bool m_reversed; float m_frequency; diff --git a/plugins/audio_file_processor/audio_file_processor.cpp b/plugins/audio_file_processor/audio_file_processor.cpp index c8adb77f2..b69b63adf 100644 --- a/plugins/audio_file_processor/audio_file_processor.cpp +++ b/plugins/audio_file_processor/audio_file_processor.cpp @@ -83,9 +83,9 @@ audioFileProcessor::audioFileProcessor( instrumentTrack * _instrument_track ) : connect( &m_ampModel, SIGNAL( dataChanged() ), this, SLOT( ampModelChanged() ) ); connect( &m_startPointModel, SIGNAL( dataChanged() ), - this, SLOT( startPointModelChanged() ) ); + this, SLOT( loopPointChanged() ) ); connect( &m_endPointModel, SIGNAL( dataChanged() ), - this, SLOT( endPointModelChanged() ) ); + this, SLOT( loopPointChanged() ) ); } @@ -166,8 +166,7 @@ void audioFileProcessor::loadSettings( const QDomElement & _this ) m_startPointModel.loadSettings( _this, "sframe" ); m_endPointModel.loadSettings( _this, "eframe" ); - startPointModelChanged(); - endPointModelChanged(); + loopPointChanged(); } @@ -235,8 +234,7 @@ void audioFileProcessor::setAudioFile( const QString & _audio_file, // else we don't touch the track-name, because the user named it self m_sampleBuffer.setAudioFile( _audio_file ); - startPointModelChanged(); - endPointModelChanged(); + loopPointChanged(); } @@ -258,43 +256,14 @@ void audioFileProcessor::ampModelChanged( void ) -void audioFileProcessor::startPointModelChanged( void ) +void audioFileProcessor::loopPointChanged( void ) { - if( m_startPointModel.value() < m_endPointModel.value() ) - { - m_sampleBuffer.setStartFrame( static_cast( - m_startPointModel.value() * - m_sampleBuffer.frames() ) ); - } - else - { - m_startPointModel.setValue( m_endPointModel.value() - 0.01f ); - } - emit dataChanged(); -} - - - - -void audioFileProcessor::endPointModelChanged( void ) -{ - if( m_endPointModel.value() > m_startPointModel.value() ) - { - if( m_endPointModel.value() * m_sampleBuffer.frames() >= 1.0f ) - { - m_sampleBuffer.setEndFrame( static_cast( - m_endPointModel.value() * - m_sampleBuffer.frames() ) - 1 ); - } - else - { - m_sampleBuffer.setEndFrame( 0 ); - } - } - else - { - m_endPointModel.setValue( m_startPointModel.value() + 0.01f ); - } + const f_cnt_t f1 = static_cast( m_startPointModel.value() * + ( m_sampleBuffer.frames()-1 ) ); + const f_cnt_t f2 = static_cast( m_endPointModel.value() * + ( m_sampleBuffer.frames()-1 ) ); + m_sampleBuffer.setStartFrame( tMin( f1, f2 ) ); + m_sampleBuffer.setEndFrame( tMax( f1, f2 ) ); emit dataChanged(); } @@ -507,7 +476,7 @@ void audioFileProcessorView::paintEvent( QPaintEvent * ) audioFileProcessor * a = castModel(); QString file_name = ""; - Uint16 idx = a->m_sampleBuffer.audioFile().length(); + int idx = a->m_sampleBuffer.audioFile().length(); p.setFont( pointSize<8>( font() ) ); @@ -536,10 +505,10 @@ void audioFileProcessorView::paintEvent( QPaintEvent * ) const QRect graph_rect( 4, 174, 241, 70 ); const f_cnt_t frames = tMax( a->m_sampleBuffer.frames(), static_cast( 1 ) ); - const Uint16 start_frame_x = a->m_sampleBuffer.startFrame() * + const int start_frame_x = a->m_sampleBuffer.startFrame() * + graph_rect.width() / frames; + const int end_frame_x = a->m_sampleBuffer.endFrame() * graph_rect.width() / frames; - const Uint16 end_frame_x = a->m_sampleBuffer.endFrame() * - ( graph_rect.width() - 1 ) / frames; p.drawLine( start_frame_x + graph_rect.x(), graph_rect.y(), start_frame_x + graph_rect.x(), diff --git a/plugins/audio_file_processor/audio_file_processor.h b/plugins/audio_file_processor/audio_file_processor.h index 35fe7cf6f..9a939cbc1 100644 --- a/plugins/audio_file_processor/audio_file_processor.h +++ b/plugins/audio_file_processor/audio_file_processor.h @@ -84,8 +84,7 @@ public slots: private slots: void reverseModelChanged( void ); void ampModelChanged( void ); - void startPointModelChanged( void ); - void endPointModelChanged( void ); + void loopPointChanged( void ); private: diff --git a/src/core/sample_buffer.cpp b/src/core/sample_buffer.cpp index 041e75893..0271fcd75 100644 --- a/src/core/sample_buffer.cpp +++ b/src/core/sample_buffer.cpp @@ -74,8 +74,8 @@ sampleBuffer::sampleBuffer( const QString & _audio_file, m_frames( 0 ), m_startFrame( 0 ), m_endFrame( 0 ), - m_loop_startFrame( 0 ), - m_loop_endFrame( 0 ), + m_loopStartFrame( 0 ), + m_loopEndFrame( 0 ), m_amplification( 1.0f ), m_reversed( FALSE ), m_frequency( BaseFreq ), @@ -99,8 +99,8 @@ sampleBuffer::sampleBuffer( const sampleFrame * _data, const f_cnt_t _frames ) : m_frames( 0 ), m_startFrame( 0 ), m_endFrame( 0 ), - m_loop_startFrame( 0 ), - m_loop_endFrame( 0 ), + m_loopStartFrame( 0 ), + m_loopEndFrame( 0 ), m_amplification( 1.0f ), m_reversed( FALSE ), m_frequency( BaseFreq ), @@ -126,8 +126,8 @@ sampleBuffer::sampleBuffer( const f_cnt_t _frames ) : m_frames( 0 ), m_startFrame( 0 ), m_endFrame( 0 ), - m_loop_startFrame( 0 ), - m_loop_endFrame( 0 ), + m_loopStartFrame( 0 ), + m_loopEndFrame( 0 ), m_amplification( 1.0f ), m_reversed( FALSE ), m_frequency( BaseFreq ), @@ -174,8 +174,8 @@ void sampleBuffer::update( bool _keep_settings ) if( _keep_settings == FALSE ) { m_frames = m_origFrames; - m_loop_startFrame = m_startFrame = 0; - m_loop_endFrame = m_endFrame = m_frames; + m_loopStartFrame = m_startFrame = 0; + m_loopEndFrame = m_endFrame = m_frames; } } else if( m_audioFile != "" ) @@ -258,8 +258,8 @@ m_data[frame][chnl] = buf[idx] * fac; m_data = new sampleFrame[1]; memset( m_data, 0, sizeof( *m_data ) ); m_frames = 1; - m_loop_startFrame = m_startFrame = 0; - m_loop_endFrame = m_endFrame = 1; + m_loopStartFrame = m_startFrame = 0; + m_loopEndFrame = m_endFrame = 1; } } else @@ -269,8 +269,8 @@ m_data[frame][chnl] = buf[idx] * fac; m_data = new sampleFrame[1]; memset( m_data, 0, sizeof( *m_data ) ); m_frames = 1; - m_loop_startFrame = m_startFrame = 0; - m_loop_endFrame = m_endFrame = 1; + m_loopStartFrame = m_startFrame = 0; + m_loopEndFrame = m_endFrame = 1; } if( lock ) @@ -303,8 +303,8 @@ void sampleBuffer::normalizeSampleRate( const sample_rate_t _src_sr, if( _keep_settings == FALSE ) { // update frame-variables - m_loop_startFrame = m_startFrame = 0; - m_loop_endFrame = m_endFrame = m_frames; + m_loopStartFrame = m_startFrame = 0; + m_loopEndFrame = m_endFrame = m_frames; } } @@ -506,8 +506,10 @@ f_cnt_t sampleBuffer::decodeSampleDS( const char * _f, bool sampleBuffer::play( sampleFrame * _ab, handleState * _state, const fpp_t _frames, const float _freq, - const bool _looped ) const + const bool _looped ) { + QMutexLocker ml( &m_varLock ); + engine::getMixer()->clearAudioBuffer( _ab, _frames ); if( m_endFrame == 0 || _frames == 0 ) @@ -540,7 +542,7 @@ bool sampleBuffer::play( sampleFrame * _ab, handleState * _state, { play_frame = getLoopedIndex( play_frame ); frames_for_loop = static_cast( - ( m_loop_endFrame - play_frame ) / + ( m_loopEndFrame - play_frame ) / freq_factor ); } else @@ -628,7 +630,7 @@ sampleFrame * sampleBuffer::getSampleFragment( f_cnt_t _start, { if( _looped ) { - if( _start + _frames <= m_loop_endFrame ) + if( _start + _frames <= m_loopEndFrame ) { return( m_data + _start ); } @@ -645,13 +647,13 @@ sampleFrame * sampleBuffer::getSampleFragment( f_cnt_t _start, if( _looped ) { - f_cnt_t copied = m_loop_endFrame - _start; + f_cnt_t copied = m_loopEndFrame - _start; memcpy( *_tmp, m_data + _start, copied * BYTES_PER_FRAME ); - f_cnt_t loop_frames = m_loop_endFrame - m_loop_startFrame; + f_cnt_t loop_frames = m_loopEndFrame - m_loopStartFrame; while( _frames - copied > 0 ) { f_cnt_t todo = tMin( _frames - copied, loop_frames ); - memcpy( *_tmp + copied, m_data + m_loop_startFrame, + memcpy( *_tmp + copied, m_data + m_loopStartFrame, todo * BYTES_PER_FRAME ); copied += todo; } @@ -672,12 +674,12 @@ sampleFrame * sampleBuffer::getSampleFragment( f_cnt_t _start, f_cnt_t sampleBuffer::getLoopedIndex( f_cnt_t _index ) const { - if( _index < m_loop_endFrame ) + if( _index < m_loopEndFrame ) { return( _index ); } - return( m_loop_startFrame + ( _index - m_loop_startFrame ) - % ( m_loop_endFrame - m_loop_startFrame ) ); + return( m_loopStartFrame + ( _index - m_loopStartFrame ) + % ( m_loopEndFrame - m_loopStartFrame ) ); } @@ -1095,7 +1097,9 @@ void sampleBuffer::loadFromBase64( const QString & _data ) void sampleBuffer::setStartFrame( const f_cnt_t _s ) { - m_loop_startFrame = m_startFrame = _s; + m_varLock.lock(); + m_loopStartFrame = m_startFrame = _s; + m_varLock.unlock(); } @@ -1103,7 +1107,9 @@ void sampleBuffer::setStartFrame( const f_cnt_t _s ) void sampleBuffer::setEndFrame( const f_cnt_t _e ) { - m_loop_endFrame = m_endFrame = _e; + m_varLock.lock(); + m_loopEndFrame = m_endFrame = _e; + m_varLock.unlock(); }