Skip to content

Commit

Permalink
Protect reads to SampleBuffer with read locks
Browse files Browse the repository at this point in the history
  • Loading branch information
Javier Serrano Polo committed Jun 11, 2016
1 parent 1abbbc2 commit abe61f2
Show file tree
Hide file tree
Showing 13 changed files with 73 additions and 30 deletions.
4 changes: 2 additions & 2 deletions include/Oscillator.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class EXPORT Oscillator
}


inline void setUserWave( const SampleBuffer * _wave )
inline void setUserWave( SampleBuffer * _wave )
{
m_userWave = _wave;
}
Expand Down Expand Up @@ -164,7 +164,7 @@ class EXPORT Oscillator
Oscillator * m_subOsc;
float m_phaseOffset;
float m_phase;
const SampleBuffer * m_userWave;
SampleBuffer * m_userWave;


void updateNoSub( sampleFrame * _ab, const fpp_t _frames,
Expand Down
38 changes: 22 additions & 16 deletions include/SampleBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,31 +225,37 @@ class EXPORT SampleBuffer : public QObject, public sharedObject
QString & toBase64( QString & _dst ) const;


static SampleBuffer * resample( sampleFrame * _data,
const f_cnt_t _frames,
const sample_rate_t _src_sr,
const sample_rate_t _dst_sr );

static inline SampleBuffer * resample( SampleBuffer * _buf,
const sample_rate_t _src_sr,
const sample_rate_t _dst_sr )
{
return resample( _buf->m_data, _buf->m_frames, _src_sr,
_dst_sr );
}
// set lock to false if a lock has been acquired already
SampleBuffer * resample( const sample_rate_t _src_sr,
const sample_rate_t _dst_sr,
bool lock );

void normalizeSampleRate( const sample_rate_t _src_sr,
bool _keep_settings = false );

// protect calls to this function with dataReadLock() and dataUnlock(),
// out of loops for efficiency
inline sample_t userWaveSample( const float _sample ) const
{
const float frame = _sample * m_frames;
f_cnt_t f1 = static_cast<f_cnt_t>( frame ) % m_frames;
f_cnt_t frames = m_frames;
sampleFrame * data = m_data;
const float frame = _sample * frames;
f_cnt_t f1 = static_cast<f_cnt_t>( frame ) % frames;
if( f1 < 0 )
{
f1 += m_frames;
f1 += frames;
}
return linearInterpolate( m_data[f1][0], m_data[ (f1 + 1) % m_frames ][0], fraction( frame ) );
return linearInterpolate( data[f1][0], data[ (f1 + 1) % frames ][0], fraction( frame ) );
}

void dataReadLock()
{
m_varLock.lockForRead();
}

void dataUnlock()
{
m_varLock.unlock();
}

static QString tryToMakeRelative( const QString & _file );
Expand Down
2 changes: 1 addition & 1 deletion include/SampleRecordHandle.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@
#include <QtCore/QPair>

#include "Mixer.h"
#include "SampleBuffer.h"

class BBTrack;
class SampleBuffer;
class SampleTCO;
class Track;

Expand Down
1 change: 1 addition & 0 deletions plugins/GigPlayer/GigPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include "InstrumentPlayHandle.h"
#include "NotePlayHandle.h"
#include "Knob.h"
#include "SampleBuffer.h"
#include "Song.h"
#include "ConfigManager.h"
#include "endian_handling.h"
Expand Down
2 changes: 1 addition & 1 deletion plugins/GigPlayer/GigPlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@
#include <QList>
#include <QMutex>
#include <QMutexLocker>
#include <samplerate.h>

#include "Instrument.h"
#include "PixmapButton.h"
#include "InstrumentView.h"
#include "Knob.h"
#include "LcdSpinBox.h"
#include "LedCheckbox.h"
#include "SampleBuffer.h"
#include "MemoryManager.h"
#include "gig.h"

Expand Down
1 change: 1 addition & 0 deletions plugins/sf2_player/sf2_player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "InstrumentPlayHandle.h"
#include "NotePlayHandle.h"
#include "Knob.h"
#include "SampleBuffer.h"
#include "Song.h"

#include "patches_dialog.h"
Expand Down
2 changes: 1 addition & 1 deletion plugins/sf2_player/sf2_player.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#define SF2_PLAYER_H

#include <QMutex>
#include <samplerate.h>

#include "Instrument.h"
#include "PixmapButton.h"
Expand All @@ -36,7 +37,6 @@
#include "LcdSpinBox.h"
#include "LedCheckbox.h"
#include "fluidsynth.h"
#include "SampleBuffer.h"
#include "MemoryManager.h"

class sf2InstrumentView;
Expand Down
3 changes: 3 additions & 0 deletions src/core/EnvelopeAndLfoParameters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,11 +241,14 @@ inline sample_t EnvelopeAndLfoParameters::lfoShapeSample( fpp_t _frame_offset )

void EnvelopeAndLfoParameters::updateLfoShapeData()
{
// userWaveSample() may be used, called out of loop for efficiency
m_userWave.dataReadLock();
const fpp_t frames = Engine::mixer()->framesPerPeriod();
for( fpp_t offset = 0; offset < frames; ++offset )
{
m_lfoShapeData[offset] = lfoShapeSample( offset );
}
m_userWave.dataUnlock();
m_bad_lfoShapeData = false;
}

Expand Down
2 changes: 2 additions & 0 deletions src/core/LfoController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ void LfoController::updateValueBuffer()
int amountInc = amountBuffer ? 1 : 0;
float *amountPtr = amountBuffer ? &(amountBuffer->values()[ 0 ] ) : &amount;

m_userDefSampleBuffer->dataReadLock();
for( int i = 0; i < m_valueBuffer.length(); i++ )
{
const float currentSample = m_sampleFunction != NULL
Expand All @@ -114,6 +115,7 @@ void LfoController::updateValueBuffer()
phase += 1.0 / m_duration;
amountPtr += amountInc;
}
m_userDefSampleBuffer->dataUnlock();

m_currentPhase = absFraction( phase - m_phaseOffset );
}
Expand Down
12 changes: 12 additions & 0 deletions src/core/Oscillator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,9 @@ void Oscillator::updateNoSub( sampleFrame * _ab, const fpp_t _frames,
updateNoSub<WhiteNoise>( _ab, _frames, _chnl );
break;
case UserDefinedWave:
m_userWave->dataReadLock();
updateNoSub<UserDefinedWave>( _ab, _frames, _chnl );
m_userWave->dataUnlock();
break;
}
}
Expand Down Expand Up @@ -155,7 +157,9 @@ void Oscillator::updatePM( sampleFrame * _ab, const fpp_t _frames,
updatePM<WhiteNoise>( _ab, _frames, _chnl );
break;
case UserDefinedWave:
m_userWave->dataReadLock();
updatePM<UserDefinedWave>( _ab, _frames, _chnl );
m_userWave->dataUnlock();
break;
}
}
Expand Down Expand Up @@ -191,7 +195,9 @@ void Oscillator::updateAM( sampleFrame * _ab, const fpp_t _frames,
updateAM<WhiteNoise>( _ab, _frames, _chnl );
break;
case UserDefinedWave:
m_userWave->dataReadLock();
updateAM<UserDefinedWave>( _ab, _frames, _chnl );
m_userWave->dataUnlock();
break;
}
}
Expand Down Expand Up @@ -227,7 +233,9 @@ void Oscillator::updateMix( sampleFrame * _ab, const fpp_t _frames,
updateMix<WhiteNoise>( _ab, _frames, _chnl );
break;
case UserDefinedWave:
m_userWave->dataReadLock();
updateMix<UserDefinedWave>( _ab, _frames, _chnl );
m_userWave->dataUnlock();
break;
}
}
Expand Down Expand Up @@ -263,7 +271,9 @@ void Oscillator::updateSync( sampleFrame * _ab, const fpp_t _frames,
updateSync<WhiteNoise>( _ab, _frames, _chnl );
break;
case UserDefinedWave:
m_userWave->dataReadLock();
updateSync<UserDefinedWave>( _ab, _frames, _chnl );
m_userWave->dataUnlock();
break;
}
}
Expand Down Expand Up @@ -299,7 +309,9 @@ void Oscillator::updateFM( sampleFrame * _ab, const fpp_t _frames,
updateFM<WhiteNoise>( _ab, _frames, _chnl );
break;
case UserDefinedWave:
m_userWave->dataReadLock();
updateFM<UserDefinedWave>( _ab, _frames, _chnl );
m_userWave->dataUnlock();
break;
}
}
Expand Down
31 changes: 22 additions & 9 deletions src/core/SampleBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -353,8 +353,9 @@ void SampleBuffer::normalizeSampleRate( const sample_rate_t _src_sr,
// do samplerate-conversion to our default-samplerate
if( _src_sr != Engine::mixer()->baseSampleRate() )
{
SampleBuffer * resampled = resample( this, _src_sr,
Engine::mixer()->baseSampleRate() );
SampleBuffer * resampled = resample( _src_sr,
Engine::mixer()->baseSampleRate(),
false );
MM_FREE( m_data );
m_frames = resampled->frames();
m_data = MM_ALLOC( sampleFrame, m_frames );
Expand Down Expand Up @@ -1146,12 +1147,18 @@ QString & SampleBuffer::toBase64( QString & _dst ) const



SampleBuffer * SampleBuffer::resample( sampleFrame * _data,
const f_cnt_t _frames,
const sample_rate_t _src_sr,
const sample_rate_t _dst_sr )
SampleBuffer * SampleBuffer::resample( const sample_rate_t _src_sr,
const sample_rate_t _dst_sr,
bool lock )
{
const f_cnt_t dst_frames = static_cast<f_cnt_t>( _frames /
if( lock )
{
m_varLock.lockForRead();
}

sampleFrame * data = m_data;
const f_cnt_t frames = m_frames;
const f_cnt_t dst_frames = static_cast<f_cnt_t>( frames /
(float) _src_sr * (float) _dst_sr );
SampleBuffer * dst_sb = new SampleBuffer( dst_frames );
sampleFrame * dst_buf = dst_sb->m_origData;
Expand All @@ -1164,9 +1171,9 @@ SampleBuffer * SampleBuffer::resample( sampleFrame * _data,
{
SRC_DATA src_data;
src_data.end_of_input = 1;
src_data.data_in = _data[0];
src_data.data_in = data[0];
src_data.data_out = dst_buf[0];
src_data.input_frames = _frames;
src_data.input_frames = frames;
src_data.output_frames = dst_frames;
src_data.src_ratio = (double) _dst_sr / _src_sr;
if( ( error = src_process( state, &src_data ) ) )
Expand All @@ -1180,6 +1187,12 @@ SampleBuffer * SampleBuffer::resample( sampleFrame * _data,
{
printf( "Error: src_new() failed in sample_buffer.cpp!\n" );
}

if( lock )
{
m_varLock.unlock();
}

dst_sb->update();
return dst_sb;
}
Expand Down
3 changes: 3 additions & 0 deletions src/gui/widgets/EnvelopeAndLfoView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,8 @@ void EnvelopeAndLfoView::paintEvent( QPaintEvent * )
osc_frames *= 100.0f;
}

// userWaveSample() may be used, called out of loop for efficiency
m_params->m_userWave.dataReadLock();
float old_y = 0;
for( int x = 0; x <= LFO_GRAPH_W; ++x )
{
Expand Down Expand Up @@ -558,6 +560,7 @@ void EnvelopeAndLfoView::paintEvent( QPaintEvent * )
graph_y_base + cur_y ) );
old_y = cur_y;
}
m_params->m_userWave.dataUnlock();

p.setPen( QColor( 201, 201, 225 ) );
int ms_per_osc = static_cast<int>( SECS_PER_LFO_OSCILLATION *
Expand Down
2 changes: 2 additions & 0 deletions src/gui/widgets/Graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -585,11 +585,13 @@ QString graphModel::setWaveToUser()
QString fileName = sampleBuffer->openAndSetWaveformFile();
if( fileName.isEmpty() == false )
{
sampleBuffer->dataReadLock();
for( int i = 0; i < length(); i++ )
{
m_samples[i] = sampleBuffer->userWaveSample(
i / static_cast<float>( length() ) );
}
sampleBuffer->dataUnlock();
}

sharedObject::unref( sampleBuffer );
Expand Down

0 comments on commit abe61f2

Please sign in to comment.