diff --git a/sflphone-common/src/audio/audiostream.cpp b/sflphone-common/src/audio/audiostream.cpp index 8054c1e10ea9bb01056a214127dec0eb77b40029..4af1e26c0416bed42f3663bb3ef61f19d7446578 100644 --- a/sflphone-common/src/audio/audiostream.cpp +++ b/sflphone-common/src/audio/audiostream.cpp @@ -23,18 +23,21 @@ static pa_channel_map channel_map ; -AudioStream::AudioStream (pa_context* context, int type, std::string desc, double vol UNUSED) - : _audiostream (NULL), _streamType (type), _streamDescription (desc), flag (PA_STREAM_AUTO_TIMING_UPDATE), sample_spec(), _volume() +AudioStream::AudioStream (PulseLayerType * driver) + : _audiostream (NULL), + _context (driver->context), + _streamType (driver->type), + _streamDescription (driver->description), + _volume(), + _mainloop(driver->mainloop), + flag (PA_STREAM_AUTO_TIMING_UPDATE), + sample_spec() { sample_spec.format = PA_SAMPLE_S16LE; sample_spec.rate = 44100; sample_spec.channels = 1; channel_map.channels = 1; pa_cvolume_set (&_volume , 1 , PA_VOLUME_NORM) ; // * vol / 100 ; - - _context = context; - - // connectStream(); } AudioStream::~AudioStream() @@ -59,10 +62,14 @@ AudioStream::disconnectStream (void) ost::MutexLock guard (_mutex); _debug ("Destroy audio streams\n"); - pa_stream_disconnect (_audiostream); - pa_stream_unref (_audiostream); - - _audiostream = NULL; + + pa_threaded_mainloop_lock(_mainloop); + if(_audiostream) { + pa_stream_disconnect (_audiostream); + pa_stream_unref (_audiostream); + _audiostream = NULL; + } + pa_threaded_mainloop_unlock(_mainloop); return true; } @@ -70,13 +77,16 @@ AudioStream::disconnectStream (void) void -AudioStream::stream_state_callback (pa_stream* s, void* user_data UNUSED) +AudioStream::stream_state_callback (pa_stream* s, void* user_data) { - - + pa_threaded_mainloop *m; + _debug ("AudioStream::stream_state_callback :: The state of the stream changed\n"); assert (s); + m = (pa_threaded_mainloop*) user_data; + assert(m); + switch (pa_stream_get_state (s)) { case PA_STREAM_CREATING: @@ -85,7 +95,7 @@ AudioStream::stream_state_callback (pa_stream* s, void* user_data UNUSED) case PA_STREAM_TERMINATED: _debug ("Stream is terminating...\n"); - PulseLayer::streamState++; + pa_threaded_mainloop_signal(m, 0); break; case PA_STREAM_READY: @@ -162,7 +172,7 @@ AudioStream::createStream (pa_context* c) _debug ("Stream type unknown \n"); } - pa_stream_set_state_callback (s , stream_state_callback, NULL); + pa_stream_set_state_callback (s , stream_state_callback, _mainloop); free (attributes); diff --git a/sflphone-common/src/audio/audiostream.h b/sflphone-common/src/audio/audiostream.h index f21e4b0d27654a5efa5f28e919de6817de075d0b..2314d31670ac28fede04fb0036e9b605210e1a57 100644 --- a/sflphone-common/src/audio/audiostream.h +++ b/sflphone-common/src/audio/audiostream.h @@ -27,6 +27,7 @@ #include "ringbuffer.h" #include "audioloop.h" + #include <cc++/thread.h> /** @@ -38,16 +39,23 @@ enum STREAM_TYPE { UPLOAD_STREAM }; +struct PulseLayerType { + pa_context * context; + pa_threaded_mainloop * mainloop; + + std::string description; + + int type; + double volume; +}; class AudioStream { public: /** * Constructor - * @param context The pulseaudio context - * @param type The type of audio stream - * @param desc The stream name + * @param context The PulseLayerType structure containing various information. */ - AudioStream(pa_context* context , int type, std::string desc, double vol); + AudioStream(PulseLayerType * driver); /** * Destructor @@ -166,6 +174,8 @@ class AudioStream { pa_sample_spec sample_spec ; pa_cvolume _volume; + pa_threaded_mainloop * _mainloop; + ost::Mutex _mutex; }; diff --git a/sflphone-common/src/audio/pulselayer.cpp b/sflphone-common/src/audio/pulselayer.cpp index 9d586d2041301be4440f6631b55335459a95c87c..ed8b4317774b5b4c1c512ac2ca66434b2278c6ac 100644 --- a/sflphone-common/src/audio/pulselayer.cpp +++ b/sflphone-common/src/audio/pulselayer.cpp @@ -48,9 +48,6 @@ PulseLayer::PulseLayer (ManagerImpl* manager) PulseLayer::~PulseLayer (void) { closeLayer (); - - // pa_context_disconnect( context ); - // pa_context_unref( context ); } bool @@ -61,17 +58,16 @@ PulseLayer::closeLayer (void) playback->disconnectStream(); record->disconnectStream(); - while (PulseLayer::streamState != 2); - - PulseLayer::streamState = 0; - - //TODO Remove this ugly hack - sleep (2); - - pa_context_disconnect (context); - - pa_context_unref (context); - + pa_threaded_mainloop_lock (m); + pa_threaded_mainloop_wait(m); + if(m) { + pa_context_disconnect (context); + pa_context_unref (context); + } + pa_threaded_mainloop_unlock (m); + + pa_threaded_mainloop_free (m); + return true; } @@ -167,18 +163,29 @@ bool PulseLayer::createStreams (pa_context* c) { _debug ("PulseLayer::createStreams \n"); - playback = new AudioStream (c, PLAYBACK_STREAM, PLAYBACK_STREAM_NAME, _manager->getSpkrVolume()); + PulseLayerType * playbackParam = new PulseLayerType(); + playbackParam->context = c; + playbackParam->type = PLAYBACK_STREAM; + playbackParam->description = PLAYBACK_STREAM_NAME; + playbackParam->volume = _manager->getSpkrVolume(); + playbackParam->mainloop = m; + + playback = new AudioStream (playbackParam); playback->connectStream(); pa_stream_set_write_callback (playback->pulseStream(), audioCallback, this); - // pa_stream_set_overflow_callback( playback->pulseStream() , overflow , this); - // pa_stream_set_suspended_callback( playback->pulseStream(), stream_suspended_callback, this); - - record = new AudioStream (c, CAPTURE_STREAM, CAPTURE_STREAM_NAME , _manager->getMicVolume()); + delete playbackParam; + + PulseLayerType * recordParam = new PulseLayerType(); + recordParam->context = c; + recordParam->type = CAPTURE_STREAM; + recordParam->description = CAPTURE_STREAM_NAME; + recordParam->volume = _manager->getMicVolume(); + recordParam->mainloop = m; + + record = new AudioStream (recordParam); record->connectStream(); pa_stream_set_read_callback (record->pulseStream() , audioCallback, this); - // pa_stream_set_underflow_callback( record->pulseStream() , underflow , this); - // pa_stream_set_suspended_callback(record->pulseStream(), stream_suspended_callback, this); - + delete recordParam; pa_threaded_mainloop_signal (m , 0);