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:
Tobias Doerffel
2009-11-20 22:28:47 +01:00
parent 58f53d9f5b
commit 168805745e
2 changed files with 27 additions and 22 deletions

View File

@@ -79,6 +79,7 @@ private:
virtual void applyQualitySettings();
virtual void run();
volatile bool m_quit;
bool m_convertEndian;

View File

@@ -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,