diff --git a/sflphone-client-gnome/src/config/accountconfigdialog.c b/sflphone-client-gnome/src/config/accountconfigdialog.c index 999141002ae75ec149c4692afe5ef8fe9b833874..6ad988afee76a721baacdcc5dfb8283467586b5d 100644 --- a/sflphone-client-gnome/src/config/accountconfigdialog.c +++ b/sflphone-client-gnome/src/config/accountconfigdialog.c @@ -790,6 +790,8 @@ GtkWidget * create_advanced_tab(account_t **a) gtk_entry_set_text(GTK_ENTRY(stunServerEntry), stun_server); gtk_table_attach_defaults(GTK_TABLE(table), stunServerEntry, 1, 2, 8, 9); + use_stun_cb (GTK_WIDGET (useStunRadioButton), NULL); + // This will trigger a signal, and the above two // widgets need to be instanciated before that. g_signal_connect(useStunRadioButton, "toggled", G_CALLBACK(use_stun_cb), useStunRadioButton); diff --git a/sflphone-client-gnome/src/mainwindow.c b/sflphone-client-gnome/src/mainwindow.c index 2697a2c12ddc12d4287a2b6002662371aea703e8..22e34cfb840926edaba1dc6fddc2e06d6a10ffea 100644 --- a/sflphone-client-gnome/src/mainwindow.c +++ b/sflphone-client-gnome/src/mainwindow.c @@ -198,6 +198,7 @@ create_main_window () gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE /*expand*/, TRUE /*fill*/, 0 /*padding*/); widget = create_toolbar_actions (ui_manager); + gtk_toolbar_set_style (GTK_TOOLBAR (widget), GTK_TOOLBAR_BOTH); gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE /*expand*/, TRUE /*fill*/, 0 /*padding*/); gtk_box_pack_start (GTK_BOX (vbox), current_calls->tree, TRUE /*expand*/, TRUE /*fill*/, 0 /*padding*/); diff --git a/sflphone-common/src/audio/pulseaudio/audiostream.cpp b/sflphone-common/src/audio/pulseaudio/audiostream.cpp index bd138140250c679b6b407913f5fec3308e35905c..e30f40f78b200cdf0845cc5394b8c709a2a7af6e 100644 --- a/sflphone-common/src/audio/pulseaudio/audiostream.cpp +++ b/sflphone-common/src/audio/pulseaudio/audiostream.cpp @@ -182,12 +182,14 @@ AudioStream::createStream (pa_context* c) assert (s); + // parameters are defined as number of bytes + // 2048 bytes (1024 int16) is 20 ms at 44100 Hz if (_streamType == PLAYBACK_STREAM) { - attributes->maxlength = 60000; - attributes->tlength = 4096; - attributes->prebuf = 4096; - attributes->minreq = 940; - attributes->fragsize = 4096; + attributes->maxlength = 16000; + attributes->tlength = 2048; + attributes->prebuf = 1024; + attributes->minreq = 1024; + 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_START_CORKED, &_volume, NULL); } else if (_streamType == CAPTURE_STREAM) { @@ -195,11 +197,11 @@ AudioStream::createStream (pa_context* c) // attributes->maxlength = 66500; // attributes->fragsize = (uint32_t)-1; - attributes->maxlength = 60000; - attributes->tlength = 4096; - attributes->prebuf = 4096; - attributes->minreq = 940; - attributes->fragsize = 4096; + attributes->maxlength = 16000; + attributes->tlength = 1024; + attributes->prebuf = 1024; + attributes->minreq = 512; + attributes->fragsize = 1024; // pa_stream_connect_record (s , NULL , attributes , PA_STREAM_START_CORKED); pa_stream_connect_record( s , NULL , attributes , PA_STREAM_INTERPOLATE_TIMING ); diff --git a/sflphone-common/src/audio/pulseaudio/pulselayer.cpp b/sflphone-common/src/audio/pulseaudio/pulselayer.cpp index 88569e918d2b9cf74f1892cda9dc3fcdfa8405d4..cea5e4eeccff50329d87b621a2f4eef1561f00da 100644 --- a/sflphone-common/src/audio/pulseaudio/pulselayer.cpp +++ b/sflphone-common/src/audio/pulseaudio/pulselayer.cpp @@ -23,11 +23,22 @@ 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)->processData(); + 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(bytes > 0); + static_cast<PulseLayer*> (userdata)->processCaptureData(); } @@ -100,9 +111,11 @@ PulseLayer::closeLayer (void) pa_threaded_mainloop_stop (m); } - playback->disconnectStream(); + // playback->disconnectStream(); + closePlaybackStream(); - record->disconnectStream(); + // record->disconnectStream(); + closeCaptureStream(); if (context) { pa_context_disconnect (context); @@ -136,7 +149,7 @@ PulseLayer::connectPulseAudioServer (void) if (pa_context_get_state (context) != PA_CONTEXT_READY) { _debug ("Error connecting to pulse audio server\n"); - pa_threaded_mainloop_unlock (m); + // pa_threaded_mainloop_unlock (m); } pa_threaded_mainloop_unlock (m); @@ -166,7 +179,6 @@ void PulseLayer::context_state_callback (pa_context* c, void* user_data) case PA_CONTEXT_READY: pulse->createStreams (c); _debug ("Connection to PulseAudio server established\n"); - break; case PA_CONTEXT_TERMINATED: @@ -187,17 +199,9 @@ bool PulseLayer::disconnectPulseAudioServer (void) { _debug (" PulseLayer::disconnectPulseAudioServer( void ) \n"); - if (playback) { - // playback->disconnectStream(); - delete playback; - playback=NULL; - } - - if (record) { - // record->disconnectStream(); - delete record; - record=NULL; - } + closePlaybackStream(); + + closeCaptureStream(); if (!playback && !record) return true; @@ -208,7 +212,7 @@ bool PulseLayer::disconnectPulseAudioServer (void) bool PulseLayer::createStreams (pa_context* c) { - _debug ("PulseLayer::createStreams \n"); + _debug ("--------------------------------- PulseLayer::createStreams ---------------------\n"); PulseLayerType * playbackParam = new PulseLayerType(); playbackParam->context = c; @@ -219,11 +223,11 @@ bool PulseLayer::createStreams (pa_context* c) playback = new AudioStream (playbackParam); 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_underflow_callback(playback->pulseStream(), playback_underflow_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_suspended_callback(playback->pulseStream(), stream_suspended_callback, this); + // pa_stream_set_moved_callback(playback->pulseStream(), stream_moved_callback, this); delete playbackParam; PulseLayerType * recordParam = new PulseLayerType(); @@ -235,9 +239,9 @@ bool PulseLayer::createStreams (pa_context* c) record = new AudioStream (recordParam); record->connectStream(); - pa_stream_set_read_callback (record->pulseStream() , audioCallback, 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_read_callback (record->pulseStream() , capture_callback, this); + // pa_stream_set_suspended_callback(record->pulseStream(), stream_suspended_callback, this); + // pa_stream_set_moved_callback(record->pulseStream(), stream_moved_callback, this); delete recordParam; pa_threaded_mainloop_signal (m , 0); @@ -254,20 +258,23 @@ bool PulseLayer::openDevice (int indexIn UNUSED, int indexOut UNUSED, int sample _audioSampleRate = sampleRate; _frameSize = frameSize; + /* m = pa_threaded_mainloop_new(); assert (m); - if (pa_threaded_mainloop_start (m) < 0) { _debug ("Failed starting the mainloop\n"); } + */ + /* // Instanciate a context if (! (context = pa_context_new (pa_threaded_mainloop_get_api (m) , "SFLphone"))) _debug ("Error while creating the context\n"); assert (context); + */ - connectPulseAudioServer(); + // connectPulseAudioServer(); // startStream(); @@ -280,10 +287,18 @@ bool PulseLayer::openDevice (int indexIn UNUSED, int indexOut UNUSED, int sample void PulseLayer::closeCaptureStream (void) { + if (record) { + delete record; + record=NULL; + } } void PulseLayer::closePlaybackStream (void) { + if (playback) { + delete playback; + playback=NULL; + } } int PulseLayer::canGetMic() @@ -304,16 +319,36 @@ int PulseLayer::getMic (void *buffer, int toCopy) void PulseLayer::startStream (void) { - + // connectPulseAudioServer(); if(!is_started) { _debug ("------------------------ PulseLayer::Start stream ---------------\n"); + if (!m) { + m = pa_threaded_mainloop_new(); + assert (m); + + if (pa_threaded_mainloop_start (m) < 0) { + _debug ("Failed starting the mainloop\n"); + } + } + + if (!context) { + + // Instanciate a context + if (! (context = pa_context_new (pa_threaded_mainloop_get_api (m) , "SFLphone"))) + _debug ("Error while creating the context\n"); + + assert (context); + } + _urgentRingBuffer.flush(); _mainBuffer.flushAllBuffers(); + connectPulseAudioServer(); + // pa_threaded_mainloop_lock (m); // pa_stream_cork (playback->pulseStream(), 0, NULL, NULL); @@ -321,6 +356,8 @@ void PulseLayer::startStream (void) // pa_threaded_mainloop_unlock (m); + // createStreams(context); + is_started = true; } @@ -340,6 +377,11 @@ PulseLayer::stopStream (void) flushMain(); flushUrgent(); + // closeCaptureStream(); + // closePlaybackStream(); + + disconnectPulseAudioServer(); + // pa_threaded_mainloop_lock (m); // pa_stream_cork (playback->pulseStream(), 1, NULL, NULL); @@ -347,6 +389,18 @@ PulseLayer::stopStream (void) // pa_threaded_mainloop_unlock (m); + if (context) { + pa_context_disconnect (context); + pa_context_unref (context); + context = NULL; + } + + if (m) { + pa_threaded_mainloop_free (m); + m = NULL; + } + + is_started = false; } @@ -368,23 +422,11 @@ void PulseLayer::overflow (pa_stream* s, void* userdata UNUSED) pa_stream_trigger (s, NULL, NULL); } -void PulseLayer::stream_suspended_callback (pa_stream *s, void *userdata UNUSED) -{ - -} -void PulseLayer::processData (void) +void PulseLayer::processPlaybackData (void) { - - // Handle the mic - // We check if the stream is ready - if ( (record->pulseStream()) && (pa_stream_get_state (record->pulseStream()) == PA_STREAM_READY)) - readFromMic(); - - // _debug("PulseLayer::processData() playback->pulseStream() \n"); - // Handle the data for the speakers - if ( (playback->pulseStream()) && (pa_stream_get_state (playback->pulseStream()) == PA_STREAM_READY)) { + if ( playback &&(playback->pulseStream()) && (pa_stream_get_state (playback->pulseStream()) == PA_STREAM_READY)) { // If the playback buffer is full, we don't overflow it; wait for it to have free space if (pa_stream_writable_size (playback->pulseStream()) == 0) @@ -392,6 +434,18 @@ void PulseLayer::processData (void) writeToSpeaker(); } + +} + + +void PulseLayer::processCaptureData(void) +{ + + // Handle the mic + // We check if the stream is ready + if ( record &&(record->pulseStream()) && (pa_stream_get_state (record->pulseStream()) == PA_STREAM_READY)) + readFromMic(); + } void PulseLayer::writeToSpeaker (void) @@ -495,7 +549,10 @@ void PulseLayer::writeToSpeaker (void) } else { + _debug("send zeros......................\n"); + bzero (out, maxNbBytesToGet); + pa_stream_write (playback->pulseStream(), out, maxNbBytesToGet, NULL, 0, PA_SEEK_RELATIVE); } _urgentRingBuffer.Discard(toGet); diff --git a/sflphone-common/src/audio/pulseaudio/pulselayer.h b/sflphone-common/src/audio/pulseaudio/pulselayer.h index cdd3096b8c4a837822a74ac584192c846fdb08c9..151fdec00591edae24a8bc1c52d408792663f4bc 100644 --- a/sflphone-common/src/audio/pulseaudio/pulselayer.h +++ b/sflphone-common/src/audio/pulseaudio/pulselayer.h @@ -78,7 +78,7 @@ class PulseLayer : public AudioLayer { static void underflow ( pa_stream* s, void* userdata ); static void stream_state_callback( pa_stream* s, void* user_data ); static void context_state_callback( pa_context* c, void* user_data ); - static void stream_suspended_callback ( pa_stream* s, void* userdata ); + // static void stream_suspended_callback ( pa_stream* s, void* userdata ); bool isCaptureActive (void){return true;} @@ -130,7 +130,9 @@ class PulseLayer : public AudioLayer { int getMicVolume( void ) { return micVolume; } void setMicVolume( int value ) { micVolume = value; } - void processData( void ); + void processPlaybackData( void ); + + void processCaptureData( void ); private: // Copy Constructor diff --git a/sflphone-common/src/managerimpl.cpp b/sflphone-common/src/managerimpl.cpp index ce0ec378ea231be50f9ef19f1183b8cdc94f0651..4055a143f154e96379c5d56054ac22e76aa11eed 100644 --- a/sflphone-common/src/managerimpl.cpp +++ b/sflphone-common/src/managerimpl.cpp @@ -428,7 +428,8 @@ ManagerImpl::hangupCall (const CallID& call_id) int nbCalls = getCallList().size(); audiolayer = getAudioDriver(); - // stop streamx + + // stop streams if (! (nbCalls >= 1)) { _debug(" hangupCall: stop audio stream, ther is only %i call(s) remaining\n", nbCalls); @@ -3149,6 +3150,7 @@ void ManagerImpl::switchAudioManager (void) default: _debug ("Error: audio layer unknown\n"); + break; } _audiodriver->setErrorMessage (-1);