Merge pull request #2879 from jasp00/export
Fix freeze when finishing export
This commit is contained in:
@@ -33,6 +33,7 @@
|
||||
#define ALSA_PCM_NEW_HW_PARAMS_API
|
||||
|
||||
#include <alsa/asoundlib.h>
|
||||
#include <QThread>
|
||||
|
||||
#include "AudioDevice.h"
|
||||
|
||||
|
||||
@@ -25,17 +25,15 @@
|
||||
#ifndef AUDIO_DEVICE_H
|
||||
#define AUDIO_DEVICE_H
|
||||
|
||||
#include <QtCore/QPair>
|
||||
#include <QtCore/QMutex>
|
||||
#include <QtCore/QThread>
|
||||
#include <samplerate.h>
|
||||
|
||||
#include "lmms_basics.h"
|
||||
#include "TabWidget.h"
|
||||
|
||||
|
||||
class AudioPort;
|
||||
class Mixer;
|
||||
class QThread;
|
||||
|
||||
|
||||
class AudioDevice
|
||||
@@ -135,6 +133,8 @@ protected:
|
||||
|
||||
bool hqAudio() const;
|
||||
|
||||
static void stopProcessingThread( QThread * thread );
|
||||
|
||||
|
||||
protected:
|
||||
bool m_supportsCapture;
|
||||
|
||||
@@ -84,11 +84,7 @@ private:
|
||||
|
||||
virtual void stopProcessing()
|
||||
{
|
||||
if( isRunning() )
|
||||
{
|
||||
wait( 1000 );
|
||||
terminate();
|
||||
}
|
||||
stopProcessingThread( this );
|
||||
}
|
||||
|
||||
virtual void run()
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
|
||||
#ifdef LMMS_HAVE_OSS
|
||||
|
||||
#include <QThread>
|
||||
|
||||
#include "AudioDevice.h"
|
||||
#include "AudioDeviceSetupWidget.h"
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#ifdef LMMS_HAVE_PULSEAUDIO
|
||||
|
||||
#include <pulse/pulseaudio.h>
|
||||
#include <QThread>
|
||||
|
||||
#include "AudioDevice.h"
|
||||
#include "AudioDeviceSetupWidget.h"
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#ifdef LMMS_HAVE_SNDIO
|
||||
|
||||
#include <QThread>
|
||||
#include <sndio.h>
|
||||
|
||||
#include "AudioDevice.h"
|
||||
|
||||
@@ -331,6 +331,8 @@ private:
|
||||
|
||||
virtual void run();
|
||||
|
||||
void write( surroundSampleFrame * buffer );
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
@@ -347,6 +349,7 @@ private:
|
||||
|
||||
const surroundSampleFrame * renderNextBuffer();
|
||||
|
||||
void clearInternal();
|
||||
|
||||
void runChangesInModel();
|
||||
|
||||
@@ -403,6 +406,8 @@ private:
|
||||
|
||||
bool m_metronomeActive;
|
||||
|
||||
bool m_clearSignal;
|
||||
|
||||
bool m_changesSignal;
|
||||
bool m_waitForMixer;
|
||||
unsigned int m_changes;
|
||||
|
||||
@@ -57,6 +57,18 @@ public:
|
||||
m_reader_sem.release();
|
||||
}
|
||||
|
||||
bool tryWrite( T _element )
|
||||
{
|
||||
if( m_writer_sem.tryAcquire() )
|
||||
{
|
||||
m_buffer[m_writer_index++] = _element;
|
||||
m_writer_index %= m_size;
|
||||
m_reader_sem.release();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
T read()
|
||||
{
|
||||
m_reader_sem.acquire();
|
||||
|
||||
@@ -82,6 +82,7 @@ Mixer::Mixer( bool renderOnly ) :
|
||||
m_audioDevStartFailed( false ),
|
||||
m_profiler(),
|
||||
m_metronomeActive(false),
|
||||
m_clearSignal( false ),
|
||||
m_changesSignal( false ),
|
||||
m_waitForMixer( true ),
|
||||
m_changes( 0 ),
|
||||
@@ -234,9 +235,9 @@ void Mixer::stopProcessing()
|
||||
{
|
||||
m_fifoWriter->finish();
|
||||
m_fifoWriter->wait();
|
||||
m_audioDev->stopProcessing();
|
||||
delete m_fifoWriter;
|
||||
m_fifoWriter = NULL;
|
||||
m_audioDev->stopProcessing();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -365,6 +366,12 @@ const surroundSampleFrame * Mixer::renderNextBuffer()
|
||||
// clear new write buffer
|
||||
m_inputBufferFrames[ m_inputBufferWrite ] = 0;
|
||||
|
||||
if( m_clearSignal )
|
||||
{
|
||||
m_clearSignal = false;
|
||||
clearInternal();
|
||||
}
|
||||
|
||||
// remove all play-handles that have to be deleted and delete
|
||||
// them if they still exist...
|
||||
// maybe this algorithm could be optimized...
|
||||
@@ -469,12 +476,19 @@ const surroundSampleFrame * Mixer::renderNextBuffer()
|
||||
|
||||
|
||||
|
||||
// removes all play-handles. this is necessary, when the song is stopped ->
|
||||
// all remaining notes etc. would be played until their end
|
||||
void Mixer::clear()
|
||||
{
|
||||
m_clearSignal = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// removes all play-handles. this is necessary, when the song is stopped ->
|
||||
// all remaining notes etc. would be played until their end
|
||||
void Mixer::clearInternal()
|
||||
{
|
||||
// TODO: m_midiClient->noteOffAll();
|
||||
requestChangeInModel();
|
||||
for( PlayHandleList::Iterator it = m_playHandles.begin(); it != m_playHandles.end(); ++it )
|
||||
{
|
||||
// we must not delete instrument-play-handles as they exist
|
||||
@@ -484,7 +498,6 @@ void Mixer::clear()
|
||||
m_playHandlesToRemove.push_back( *it );
|
||||
}
|
||||
}
|
||||
doneChangeInModel();
|
||||
}
|
||||
|
||||
|
||||
@@ -1053,10 +1066,26 @@ void Mixer::fifoWriter::run()
|
||||
surroundSampleFrame * buffer = new surroundSampleFrame[frames];
|
||||
const surroundSampleFrame * b = m_mixer->renderNextBuffer();
|
||||
memcpy( buffer, b, frames * sizeof( surroundSampleFrame ) );
|
||||
m_fifo->write( buffer );
|
||||
write( buffer );
|
||||
}
|
||||
|
||||
m_fifo->write( NULL );
|
||||
write( NULL );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Mixer::fifoWriter::write( surroundSampleFrame * buffer )
|
||||
{
|
||||
while( !m_fifo->tryWrite( buffer ) )
|
||||
{
|
||||
if( m_mixer->m_changesSignal )
|
||||
{
|
||||
m_mixer->runChangesInModel();
|
||||
continue;
|
||||
}
|
||||
yieldCurrentThread();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -245,11 +245,7 @@ void AudioAlsa::startProcessing()
|
||||
|
||||
void AudioAlsa::stopProcessing()
|
||||
{
|
||||
if( isRunning() )
|
||||
{
|
||||
wait( 1000 );
|
||||
terminate();
|
||||
}
|
||||
stopProcessingThread( this );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -131,6 +131,22 @@ void AudioDevice::stopProcessing()
|
||||
|
||||
|
||||
|
||||
void AudioDevice::stopProcessingThread( QThread * thread )
|
||||
{
|
||||
if( !thread->wait( 30000 ) )
|
||||
{
|
||||
fprintf( stderr, "Terminating audio device thread\n" );
|
||||
thread->terminate();
|
||||
if( !thread->wait( 1000 ) )
|
||||
{
|
||||
fprintf( stderr, "Thread not terminated yet\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void AudioDevice::applyQualitySettings()
|
||||
{
|
||||
src_delete( m_srcState );
|
||||
|
||||
@@ -255,11 +255,7 @@ void AudioOss::startProcessing()
|
||||
|
||||
void AudioOss::stopProcessing()
|
||||
{
|
||||
if( isRunning() )
|
||||
{
|
||||
wait( 1000 );
|
||||
terminate();
|
||||
}
|
||||
stopProcessingThread( this );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -105,11 +105,7 @@ void AudioPulseAudio::startProcessing()
|
||||
|
||||
void AudioPulseAudio::stopProcessing()
|
||||
{
|
||||
if( isRunning() )
|
||||
{
|
||||
wait( 1000 );
|
||||
terminate();
|
||||
}
|
||||
stopProcessingThread( this );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -114,11 +114,7 @@ void AudioSndio::startProcessing( void )
|
||||
|
||||
void AudioSndio::stopProcessing( void )
|
||||
{
|
||||
if( isRunning() )
|
||||
{
|
||||
wait( 1000 );
|
||||
terminate();
|
||||
}
|
||||
stopProcessingThread( this );
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user