Skip to content
Snippets Groups Projects
Commit 837b8a68 authored by Alexandre Savard's avatar Alexandre Savard
Browse files

[#2308] Implement two different callbacks for capture/playback in pulseaudio

So that we can now initialize capture/playback audiostream using different
pa_buffer_attr values which have great effect on latency, and callback frequency
parent 517f7355
No related branches found
No related tags found
No related merge requests found
...@@ -182,12 +182,14 @@ AudioStream::createStream (pa_context* c) ...@@ -182,12 +182,14 @@ AudioStream::createStream (pa_context* c)
assert (s); assert (s);
// parameters are defined as number of bytes
// 2048 bytes (1024 int16) is 20 ms at 44100 Hz
if (_streamType == PLAYBACK_STREAM) { if (_streamType == PLAYBACK_STREAM) {
attributes->maxlength = 60000; attributes->maxlength = 16000;
attributes->tlength = 4096; attributes->tlength = 2048;
attributes->prebuf = 4096; attributes->prebuf = 1024;
attributes->minreq = 940; attributes->minreq = 1024;
attributes->fragsize = 4096; attributes->fragsize = 1024;
pa_stream_connect_playback( s , NULL , attributes, PA_STREAM_INTERPOLATE_TIMING, &_volume, NULL); pa_stream_connect_playback( s , NULL , attributes, PA_STREAM_INTERPOLATE_TIMING, &_volume, NULL);
// pa_stream_connect_playback (s , NULL , attributes, PA_STREAM_START_CORKED, &_volume, NULL); // pa_stream_connect_playback (s , NULL , attributes, PA_STREAM_START_CORKED, &_volume, NULL);
} else if (_streamType == CAPTURE_STREAM) { } else if (_streamType == CAPTURE_STREAM) {
...@@ -195,11 +197,11 @@ AudioStream::createStream (pa_context* c) ...@@ -195,11 +197,11 @@ AudioStream::createStream (pa_context* c)
// attributes->maxlength = 66500; // attributes->maxlength = 66500;
// attributes->fragsize = (uint32_t)-1; // attributes->fragsize = (uint32_t)-1;
attributes->maxlength = 60000; attributes->maxlength = 16000;
attributes->tlength = 4096; attributes->tlength = 1024;
attributes->prebuf = 4096; attributes->prebuf = 1024;
attributes->minreq = 940; attributes->minreq = 512;
attributes->fragsize = 4096; attributes->fragsize = 1024;
// pa_stream_connect_record (s , NULL , attributes , PA_STREAM_START_CORKED); // pa_stream_connect_record (s , NULL , attributes , PA_STREAM_START_CORKED);
pa_stream_connect_record( s , NULL , attributes , PA_STREAM_INTERPOLATE_TIMING ); pa_stream_connect_record( s , NULL , attributes , PA_STREAM_INTERPOLATE_TIMING );
......
...@@ -23,11 +23,22 @@ ...@@ -23,11 +23,22 @@
int framesPerBuffer = 2048; int framesPerBuffer = 2048;
static void audioCallback (pa_stream* s, size_t bytes, void* userdata) static void playback_callback (pa_stream* s, size_t bytes, void* userdata)
{ {
_debug("playback_callback\n");
assert (s && bytes);
assert (bytes > 0);
static_cast<PulseLayer*> (userdata)->processPlaybackData();
}
static void capture_callback (pa_stream* s, size_t bytes, void* userdata)
{
// _debug("capture_callback\n");
assert(s && bytes); assert(s && bytes);
assert(bytes > 0); assert(bytes > 0);
static_cast<PulseLayer*> (userdata)->processData(); static_cast<PulseLayer*> (userdata)->processCaptureData();
} }
...@@ -138,7 +149,7 @@ PulseLayer::connectPulseAudioServer (void) ...@@ -138,7 +149,7 @@ PulseLayer::connectPulseAudioServer (void)
if (pa_context_get_state (context) != PA_CONTEXT_READY) { if (pa_context_get_state (context) != PA_CONTEXT_READY) {
_debug ("Error connecting to pulse audio server\n"); _debug ("Error connecting to pulse audio server\n");
pa_threaded_mainloop_unlock (m); // pa_threaded_mainloop_unlock (m);
} }
pa_threaded_mainloop_unlock (m); pa_threaded_mainloop_unlock (m);
...@@ -212,9 +223,9 @@ bool PulseLayer::createStreams (pa_context* c) ...@@ -212,9 +223,9 @@ bool PulseLayer::createStreams (pa_context* c)
playback = new AudioStream (playbackParam); playback = new AudioStream (playbackParam);
playback->connectStream(); playback->connectStream();
pa_stream_set_write_callback(playback->pulseStream(), audioCallback, this); pa_stream_set_write_callback(playback->pulseStream(), playback_callback, this);
pa_stream_set_overflow_callback(playback->pulseStream(), playback_overflow_callback, this); pa_stream_set_overflow_callback(playback->pulseStream(), playback_overflow_callback, this);
// pa_stream_set_underflow_callback(playback->pulseStream(), playback_underflow_callback, this); pa_stream_set_underflow_callback(playback->pulseStream(), playback_underflow_callback, this);
// pa_stream_set_suspended_callback(playback->pulseStream(), stream_suspended_callback, this); // pa_stream_set_suspended_callback(playback->pulseStream(), stream_suspended_callback, this);
// pa_stream_set_moved_callback(playback->pulseStream(), stream_moved_callback, this); // pa_stream_set_moved_callback(playback->pulseStream(), stream_moved_callback, this);
delete playbackParam; delete playbackParam;
...@@ -228,7 +239,7 @@ bool PulseLayer::createStreams (pa_context* c) ...@@ -228,7 +239,7 @@ bool PulseLayer::createStreams (pa_context* c)
record = new AudioStream (recordParam); record = new AudioStream (recordParam);
record->connectStream(); record->connectStream();
pa_stream_set_read_callback (record->pulseStream() , audioCallback, this); pa_stream_set_read_callback (record->pulseStream() , capture_callback, this);
// pa_stream_set_suspended_callback(record->pulseStream(), stream_suspended_callback, this); // pa_stream_set_suspended_callback(record->pulseStream(), stream_suspended_callback, this);
// pa_stream_set_moved_callback(record->pulseStream(), stream_moved_callback, this); // pa_stream_set_moved_callback(record->pulseStream(), stream_moved_callback, this);
delete recordParam; delete recordParam;
...@@ -412,7 +423,7 @@ void PulseLayer::overflow (pa_stream* s, void* userdata UNUSED) ...@@ -412,7 +423,7 @@ void PulseLayer::overflow (pa_stream* s, void* userdata UNUSED)
} }
void PulseLayer::processData (void) void PulseLayer::processPlaybackData (void)
{ {
// Handle the data for the speakers // Handle the data for the speakers
if ( playback &&(playback->pulseStream()) && (pa_stream_get_state (playback->pulseStream()) == PA_STREAM_READY)) { if ( playback &&(playback->pulseStream()) && (pa_stream_get_state (playback->pulseStream()) == PA_STREAM_READY)) {
...@@ -424,13 +435,17 @@ void PulseLayer::processData (void) ...@@ -424,13 +435,17 @@ void PulseLayer::processData (void)
writeToSpeaker(); writeToSpeaker();
} }
}
void PulseLayer::processCaptureData(void)
{
// Handle the mic // Handle the mic
// We check if the stream is ready // We check if the stream is ready
if ( record &&(record->pulseStream()) && (pa_stream_get_state (record->pulseStream()) == PA_STREAM_READY)) if ( record &&(record->pulseStream()) && (pa_stream_get_state (record->pulseStream()) == PA_STREAM_READY))
readFromMic(); readFromMic();
} }
void PulseLayer::writeToSpeaker (void) void PulseLayer::writeToSpeaker (void)
...@@ -534,7 +549,10 @@ void PulseLayer::writeToSpeaker (void) ...@@ -534,7 +549,10 @@ void PulseLayer::writeToSpeaker (void)
} else { } else {
_debug("send zeros......................\n");
bzero (out, maxNbBytesToGet); bzero (out, maxNbBytesToGet);
pa_stream_write (playback->pulseStream(), out, maxNbBytesToGet, NULL, 0, PA_SEEK_RELATIVE);
} }
_urgentRingBuffer.Discard(toGet); _urgentRingBuffer.Discard(toGet);
......
...@@ -130,7 +130,9 @@ class PulseLayer : public AudioLayer { ...@@ -130,7 +130,9 @@ class PulseLayer : public AudioLayer {
int getMicVolume( void ) { return micVolume; } int getMicVolume( void ) { return micVolume; }
void setMicVolume( int value ) { micVolume = value; } void setMicVolume( int value ) { micVolume = value; }
void processData( void ); void processPlaybackData( void );
void processCaptureData( void );
private: private:
// Copy Constructor // Copy Constructor
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment