Defer updates to SampleBuffer

Removed global lock from the Mixer
This commit is contained in:
Javier Serrano Polo
2016-06-18 05:29:21 +02:00
parent ecf9db66bd
commit 5606a04ad7
16 changed files with 65 additions and 93 deletions

View File

@@ -122,9 +122,9 @@ void EffectChain::loadSettings( const QDomElement & _this )
void EffectChain::appendEffect( Effect * _effect )
{
Engine::mixer()->lock();
Engine::mixer()->requestChangeInModel();
m_effects.append( _effect );
Engine::mixer()->unlock();
Engine::mixer()->doneChangeInModel();
emit dataChanged();
}
@@ -134,21 +134,18 @@ void EffectChain::appendEffect( Effect * _effect )
void EffectChain::removeEffect( Effect * _effect )
{
Engine::mixer()->lock();
Engine::mixer()->requestChangeInModel();
Effect ** found = qFind( m_effects.begin(), m_effects.end(), _effect );
if( found == m_effects.end() )
{
goto fail;
Engine::mixer()->doneChangeInModel();
return;
}
m_effects.erase( found );
Engine::mixer()->unlock();
Engine::mixer()->doneChangeInModel();
emit dataChanged();
return;
fail:
Engine::mixer()->unlock();
}
@@ -252,7 +249,7 @@ void EffectChain::clear()
{
emit aboutToClear();
Engine::mixer()->lock();
Engine::mixer()->requestChangeInModel();
m_enabledModel.setValue( false );
for( int i = 0; i < m_effects.count(); ++i )
@@ -261,5 +258,5 @@ void EffectChain::clear()
}
m_effects.clear();
Engine::mixer()->unlock();
Engine::mixer()->doneChangeInModel();
}

View File

@@ -285,8 +285,8 @@ void FxMixer::toggledSolo()
void FxMixer::deleteChannel( int index )
{
// lock the mixer so channel deletion is performed between mixer rounds
Engine::mixer()->lock();
// channel deletion is performed between mixer rounds
Engine::mixer()->requestChangeInModel();
FxChannel * ch = m_fxChannels[index];
@@ -347,7 +347,7 @@ void FxMixer::deleteChannel( int index )
}
}
Engine::mixer()->unlock();
Engine::mixer()->doneChangeInModel();
}

View File

@@ -75,7 +75,6 @@ Mixer::Mixer( bool renderOnly ) :
m_audioDev( NULL ),
m_oldAudioDev( NULL ),
m_audioDevStartFailed( false ),
m_globalMutex( QMutex::Recursive ),
m_profiler(),
m_metronomeActive(false),
m_changesSignal( false ),
@@ -386,10 +385,6 @@ const surroundSampleFrame * Mixer::renderNextBuffer()
}
unlockPlayHandleRemoval();
// now we have to make sure no other thread does anything bad
// while we're acting...
lock();
// rotate buffers
m_writeBuffer = ( m_writeBuffer + 1 ) % m_poolDepth;
m_readBuffer = ( m_readBuffer + 1 ) % m_poolDepth;
@@ -453,8 +448,6 @@ const surroundSampleFrame * Mixer::renderNextBuffer()
// STAGE 3: do master mix in FX mixer
fxMixer->masterMix( m_writeBuf );
unlock();
emit nextAudioBuffer( m_readBuf );
@@ -481,7 +474,6 @@ const surroundSampleFrame * Mixer::renderNextBuffer()
void Mixer::clear()
{
// TODO: m_midiClient->noteOffAll();
lock();
lockPlayHandleRemoval();
for( PlayHandleList::Iterator it = m_playHandles.begin(); it != m_playHandles.end(); ++it )
{
@@ -493,7 +485,6 @@ void Mixer::clear()
}
}
unlockPlayHandleRemoval();
unlock();
}
@@ -620,9 +611,7 @@ void Mixer::removeAudioPort( AudioPort * _port )
_port );
if( it != m_audioPorts.end() )
{
lock();
m_audioPorts.erase( it );
unlock();
}
}
@@ -650,7 +639,7 @@ bool Mixer::addPlayHandle( PlayHandle* handle )
void Mixer::removePlayHandle( PlayHandle * _ph )
{
lockPlayHandleRemoval();
requestChangeInModel();
// check thread affinity as we must not delete play-handles
// which were created in a thread different than mixer thread
if( _ph->affinityMatters() &&
@@ -694,7 +683,7 @@ void Mixer::removePlayHandle( PlayHandle * _ph )
{
m_playHandlesToRemove.push_back( _ph );
}
unlockPlayHandleRemoval();
doneChangeInModel();
}
@@ -702,7 +691,7 @@ void Mixer::removePlayHandle( PlayHandle * _ph )
void Mixer::removePlayHandlesOfTypes( Track * _track, const quint8 types )
{
lockPlayHandleRemoval();
requestChangeInModel();
PlayHandleList::Iterator it = m_playHandles.begin();
while( it != m_playHandles.end() )
{
@@ -721,7 +710,7 @@ void Mixer::removePlayHandlesOfTypes( Track * _track, const quint8 types )
++it;
}
}
unlockPlayHandleRemoval();
doneChangeInModel();
}
@@ -729,18 +718,13 @@ void Mixer::removePlayHandlesOfTypes( Track * _track, const quint8 types )
bool Mixer::hasNotePlayHandles()
{
lock();
for( PlayHandleList::Iterator it = m_playHandles.begin(); it != m_playHandles.end(); ++it )
{
if( (*it)->type() == PlayHandle::TypeNotePlayHandle )
{
unlock();
return true;
}
}
unlock();
return false;
}

View File

@@ -170,6 +170,7 @@ void SampleBuffer::update( bool _keep_settings )
const bool lock = ( m_data != NULL );
if( lock )
{
Engine::mixer()->requestChangeInModel();
m_varLock.lockForWrite();
MM_FREE( m_data );
}
@@ -270,6 +271,7 @@ void SampleBuffer::update( bool _keep_settings )
if( lock )
{
m_varLock.unlock();
Engine::mixer()->doneChangeInModel();
}
emit sampleUpdated();
@@ -354,7 +356,7 @@ 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,
SampleBuffer * resampled = resample( _src_sr,
Engine::mixer()->baseSampleRate() );
MM_FREE( m_data );
m_frames = resampled->frames();
@@ -597,8 +599,6 @@ bool SampleBuffer::play( sampleFrame * _ab, handleState * _state,
const float _freq,
const LoopMode _loopmode )
{
QReadLocker readLocker(&m_varLock);
f_cnt_t startFrame = m_startFrame;
f_cnt_t endFrame = m_endFrame;
f_cnt_t loopStartFrame = m_loopStartFrame;
@@ -1147,12 +1147,12 @@ QString & SampleBuffer::toBase64( QString & _dst ) const
SampleBuffer * SampleBuffer::resample( sampleFrame * _data,
const f_cnt_t _frames,
const sample_rate_t _src_sr,
SampleBuffer * SampleBuffer::resample( const sample_rate_t _src_sr,
const sample_rate_t _dst_sr )
{
const f_cnt_t dst_frames = static_cast<f_cnt_t>( _frames /
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;
@@ -1165,9 +1165,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 ) ) )
@@ -1355,7 +1355,6 @@ void SampleBuffer::loadFromBase64( const QString & _data )
void SampleBuffer::setStartFrame( const f_cnt_t _s )
{
QWriteLocker writeLocker(&m_varLock);
m_startFrame = _s;
}
@@ -1364,7 +1363,6 @@ void SampleBuffer::setStartFrame( const f_cnt_t _s )
void SampleBuffer::setEndFrame( const f_cnt_t _e )
{
QWriteLocker writeLocker(&m_varLock);
m_endFrame = _e;
}

View File

@@ -790,7 +790,7 @@ void Song::clearProject()
}
Engine::mixer()->lock();
Engine::mixer()->requestChangeInModel();
if( gui && gui->getBBEditor() )
{
@@ -831,7 +831,7 @@ void Song::clearProject()
AutomationPattern::globalAutomationPattern( &m_masterPitchModel )->
clear();
Engine::mixer()->unlock();
Engine::mixer()->doneChangeInModel();
if( gui && gui->getProjectNotes() )
{
@@ -963,7 +963,7 @@ void Song::loadProject( const QString & fileName )
DataFile::LocaleHelper localeHelper( DataFile::LocaleHelper::ModeLoad );
Engine::mixer()->lock();
Engine::mixer()->requestChangeInModel();
// get the header information from the DOM
m_tempoModel.loadSettings( dataFile.head(), "bpm" );
@@ -1050,7 +1050,7 @@ void Song::loadProject( const QString & fileName )
AutomationPattern::resolveAllIDs();
Engine::mixer()->unlock();
Engine::mixer()->doneChangeInModel();
ConfigManager::inst()->addRecentlyOpenedProject( fileName );

View File

@@ -534,7 +534,7 @@ void FileBrowserTreeWidget::mouseReleaseEvent(QMouseEvent * me )
void FileBrowserTreeWidget::handleFile(FileItem * f, InstrumentTrack * it )
{
Engine::mixer()->lock();
Engine::mixer()->requestChangeInModel();
switch( f->handling() )
{
case FileItem::LoadAsProject:
@@ -582,7 +582,7 @@ void FileBrowserTreeWidget::handleFile(FileItem * f, InstrumentTrack * it )
break;
}
Engine::mixer()->unlock();
Engine::mixer()->doneChangeInModel();
}
@@ -604,12 +604,10 @@ void FileBrowserTreeWidget::activateListItem(QTreeWidgetItem * item,
}
else if( f->handling() != FileItem::NotSupported )
{
// engine::mixer()->lock();
InstrumentTrack * it = dynamic_cast<InstrumentTrack *>(
Track::create( Track::InstrumentTrack,
Engine::getBBTrackContainer() ) );
handleFile( f, it );
// engine::mixer()->unlock();
}
}
@@ -621,11 +619,9 @@ void FileBrowserTreeWidget::openInNewInstrumentTrack( TrackContainer* tc )
if( m_contextMenuItem->handling() == FileItem::LoadAsPreset ||
m_contextMenuItem->handling() == FileItem::LoadByPlugin )
{
// engine::mixer()->lock();
InstrumentTrack * it = dynamic_cast<InstrumentTrack *>(
Track::create( Track::InstrumentTrack, tc ) );
handleFile( m_contextMenuItem, it );
// engine::mixer()->unlock();
}
}

View File

@@ -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 )
{
@@ -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 *

View File

@@ -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 );