AudioPulseAudio: fixed improper shutdown + free allocated resources
There have been some problems with the threading logic in the AudioPulseAudio backend resulting in an endless loop when quitting LMMS. Furthermore allocated PulseAudio resources were not freed properly. Thanks to Armin Kazmi <armin.kazmi@tu-dortmund.de> for pointing out this issue.
This commit is contained in:
@@ -79,6 +79,7 @@ private:
|
||||
virtual void applyQualitySettings();
|
||||
virtual void run();
|
||||
|
||||
volatile bool m_quit;
|
||||
|
||||
bool m_convertEndian;
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ AudioPulseAudio::AudioPulseAudio( bool & _success_ful, mixer * _mixer ) :
|
||||
DEFAULT_CHANNELS, SURROUND_CHANNELS ),
|
||||
_mixer ),
|
||||
m_s( NULL ),
|
||||
m_quit( false ),
|
||||
m_convertEndian( false )
|
||||
{
|
||||
_success_ful = false;
|
||||
@@ -68,11 +69,6 @@ AudioPulseAudio::AudioPulseAudio( bool & _success_ful, mixer * _mixer ) :
|
||||
AudioPulseAudio::~AudioPulseAudio()
|
||||
{
|
||||
stopProcessing();
|
||||
|
||||
if( m_s != NULL )
|
||||
{
|
||||
pa_stream_unref( m_s );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -195,38 +191,45 @@ static void context_state_callback(pa_context *c, void *userdata)
|
||||
|
||||
void AudioPulseAudio::run()
|
||||
{
|
||||
pa_mainloop * m = NULL;
|
||||
|
||||
|
||||
if (!(m = pa_mainloop_new())) {
|
||||
pa_mainloop * mainLoop = pa_mainloop_new();
|
||||
if( !mainLoop )
|
||||
{
|
||||
qCritical( "pa_mainloop_new() failed.\n" );
|
||||
return;
|
||||
}
|
||||
pa_mainloop_api * mainloop_api = pa_mainloop_get_api(m);
|
||||
pa_mainloop_api * mainloop_api = pa_mainloop_get_api( mainLoop );
|
||||
|
||||
pa_context *context = pa_context_new(mainloop_api, "lmms");
|
||||
pa_context *context = pa_context_new( mainloop_api, "lmms" );
|
||||
if ( context == NULL )
|
||||
{
|
||||
qCritical( "pa_context_new() failed." );
|
||||
qCritical( "pa_context_new() failed." );
|
||||
return;
|
||||
}
|
||||
|
||||
pa_context_set_state_callback(context, context_state_callback, this );
|
||||
/* Connect the context */
|
||||
pa_context_connect(context, NULL, (pa_context_flags) 0, NULL);
|
||||
pa_context_set_state_callback( context, context_state_callback, this );
|
||||
// connect the context
|
||||
pa_context_connect( context, NULL, (pa_context_flags) 0, NULL );
|
||||
|
||||
int ret;
|
||||
/* Run the main loop */
|
||||
if (pa_mainloop_run(m, &ret) < 0)
|
||||
// run the main loop
|
||||
int ret = 0;
|
||||
m_quit = false;
|
||||
while( m_quit == false && pa_mainloop_iterate( mainLoop, 1, &ret ) >= 0 )
|
||||
{
|
||||
qCritical( "pa_mainloop_run() failed.\n" );
|
||||
}
|
||||
|
||||
pa_stream_disconnect( m_s );
|
||||
pa_stream_unref( m_s );
|
||||
|
||||
pa_context_disconnect( context );
|
||||
pa_context_unref( context );
|
||||
|
||||
pa_mainloop_free( mainLoop );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void AudioPulseAudio::streamWriteCallback(pa_stream *s, size_t length)
|
||||
void AudioPulseAudio::streamWriteCallback( pa_stream *s, size_t length )
|
||||
{
|
||||
const fpp_t fpp = getMixer()->framesPerPeriod();
|
||||
sampleFrameA * temp = CPU::allocFrames( fpp );
|
||||
@@ -234,12 +237,13 @@ void AudioPulseAudio::streamWriteCallback(pa_stream *s, size_t length)
|
||||
sizeof(Sint16) );
|
||||
|
||||
size_t fd = 0;
|
||||
while( fd < length/4 )
|
||||
while( fd < length/4 && m_quit == false )
|
||||
{
|
||||
const fpp_t frames = getNextBuffer( temp );
|
||||
if( !frames )
|
||||
{
|
||||
return;
|
||||
m_quit = true;
|
||||
break;
|
||||
}
|
||||
int bytes = CPU::convertToS16( temp,
|
||||
(intSampleFrameA *) pcmbuf,
|
||||
|
||||
Reference in New Issue
Block a user