Skip to content
Snippets Groups Projects
Commit 7d03a6e0 authored by pierre-luc's avatar pierre-luc
Browse files

[#1805] Replaced the old and unreliable mecanism that was was waiting for

a state variable to reach the count of 2 in closeLayer. closeLayer is now
waiting for a PA_STREAM_TERMINATED signal from a callback in the
threaded_mainloop before disconnecting the pa_context.
parent 09859ec5
No related branches found
No related tags found
No related merge requests found
......@@ -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_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);
......
......@@ -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;
};
......
......@@ -48,9 +48,6 @@ PulseLayer::PulseLayer (ManagerImpl* manager)
PulseLayer::~PulseLayer (void)
{
closeLayer ();
// pa_context_disconnect( context );
// pa_context_unref( context );
}
bool
......@@ -61,16 +58,15 @@ PulseLayer::closeLayer (void)
playback->disconnectStream();
record->disconnectStream();
while (PulseLayer::streamState != 2);
PulseLayer::streamState = 0;
//TODO Remove this ugly hack
sleep (2);
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);
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 (c, CAPTURE_STREAM, CAPTURE_STREAM_NAME , _manager->getMicVolume());
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);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment