From 608ed45f1c2175a7b0e10c5c70da0fc22319d380 Mon Sep 17 00:00:00 2001
From: Alexandre Savard <alexandre.savard@savoirfairelinux.net>
Date: Thu, 22 Oct 2009 13:39:16 -0400
Subject: [PATCH] [#2333] Change (again) Pulseaudio settings to fit logiteck
 usb hdw requirement

---
 sflphone-client-gnome/doc/C/sflphone.xml      | 52 +++++++++++--------
 .../src/audio/pulseaudio/audiostream.cpp      | 22 ++++----
 .../src/audio/pulseaudio/pulselayer.cpp       | 43 +++++++++++++--
 .../src/audio/pulseaudio/pulselayer.h         |  2 +
 sflphone-common/src/managerimpl.cpp           |  9 ++++
 5 files changed, 90 insertions(+), 38 deletions(-)

diff --git a/sflphone-client-gnome/doc/C/sflphone.xml b/sflphone-client-gnome/doc/C/sflphone.xml
index 00cb6a6d18..07f31faa79 100644
--- a/sflphone-client-gnome/doc/C/sflphone.xml
+++ b/sflphone-client-gnome/doc/C/sflphone.xml
@@ -99,8 +99,11 @@
 		<application>SFLphone</application> is a free software and is distributed under the GNU General Public License version 3. It is developed by Savoir-Faire Linux, a Canadian Linux consulting company, in partnership with the global community.
 	</para>
 	<para>
-		Among the many features we developed for you, we could highlight the high definition sound (wide-band audio codecs - speex, G722, Celt), audio recording, voicemail notification and call history.
-		More than a simple softphone, <application>SFLphone</application> supports advanced enterprise-class call features: unlimited number of calls, call transfer and on/off hold option.
+		Among the many features we developed for you, we could
+		highlight the high definition sound (wide-band audio
+		codecs - speex, G722, Celt), multiple conference call,
+		audio recording, voicemail notification, and call history.
+		More than a simple softphone, <application>SFLphone</application> supports advanced enterprise-class call features: unlimited number of calls, call transfer, and on/off hold option.
 	</para>
 	<para>
 		This release also provides advanced security features (secure RTP and TLS).
@@ -137,7 +140,8 @@
 <sect1 id="accounts">
 	<title>Managing your accounts</title>
 	<para>
-		<application>SFLphone</application> supports both IAX2 and SIP accounts.
+		<application>SFLphone</application> supports both IAX2
+		and SIP accounts.
 	</para>
 
 	<sect2 id="accounts_basic">
@@ -507,36 +511,34 @@
 	</sect2>
 
 	<sect2 id="conferencecall" label="Conference calls">
-	<para>SFLphone now supports conference calling
-        integrating server like features in a simple
-        GUI.</para>
+	<para>SFLphone now supports conference call hosting
+        integrating server like features in a simple GUI.
+        </para>
         <para>
           <itemizedlist>
             <listitem>
               <guilabel>Create a conference</guilabel>
-              <para>To create a conference, drag and drop one call
+              <para>To host a conference, simply drag and drop one call
             on another. Additional participants are
             added the same way, dragging a call on the
-            conference icon. SFLphone automatically
-            includes into the newly created conference.
+            conference icon.
               </para>
             </listitem>
             <listitem>
               <guilabel>Leave a conference</guilabel>
               <para>
-            The Main Participant may leave at any time to
-            answer any other incoming communication or initiate
-            new ones. The conference is not interupted if Main
-            Participant left it. Double clicking the conference
-            let the Main Participant reintroduce
-            the conference.
+            SFLphone conference model let you leave a conference that
+            you are currently hosting to answer any other incoming
+            communication or even initiate new ones. The conference is
+            not interupted Double clicking the conference icon
+            let you reintroduce the conference.
               </para>
             </listitem>
             <listitem>
               <guilabel>Multiple conference</guilabel>
               <para>
             SFLphone supports multiple conferences running
-            simultaneously. Conferences may be joined the same way
+            simultaneously. Two conferences can be joined the same way
             they are created, dragging one on the
             other.
               </para>
@@ -582,33 +584,39 @@
         <para>
           <itemizedlist>
             <listitem>
-              <guilabel>PCMU</guilabel>
+              <guilabel>PCMU/PCMA</guilabel>
                 <para>
+		  ITU-T telefony standard PCM formats, 8kHz, 64
+		  kbit/s, using logarithmic byte compression algorithm.
                 </para>
             </listitem>
-            <listitem>
-              <guilabel>PCMA</guilabel>
-              <para>
-              </para>
-            </listitem>
             <listitem>
               <guilabel>GSM</guilabel>
               <para>
+		Global System for Mobile communications (GSM)
+		narrowband 8kHz standard based on linear prediction encoding.
               </para>
             </listitem>
             <listitem>
               <guilabel>G722</guilabel>
               <para>
+		ITU-T standard wideband 16kHz standard based on linear prediction.
               </para>
             </listitem>
             <listitem>
               <guilabel>SPEEX</guilabel>
               <para>
+		High quality voice encoding/decoding available
+		in narrowband 8Khz, wideband 16khz (HD Voice), 
+		and ultra-wideband 32 kHz. 
+		Integrate additional features such as Variable Bit
+		Rate (VBR) and noise reduction. 
               </para>
             </listitem>
             <listitem>
               <guilabel>CELT</guilabel>
               <para>
+		
               </para>
             </listitem>
           </itemizedlist>
diff --git a/sflphone-common/src/audio/pulseaudio/audiostream.cpp b/sflphone-common/src/audio/pulseaudio/audiostream.cpp
index 54309276ec..5e10a6b91f 100644
--- a/sflphone-common/src/audio/pulseaudio/audiostream.cpp
+++ b/sflphone-common/src/audio/pulseaudio/audiostream.cpp
@@ -184,27 +184,27 @@ AudioStream::createStream (pa_context* c)
     // parameters are defined as number of bytes
     // 2048 bytes (1024 int16) is 20 ms at 44100 Hz 
     if (_streamType == PLAYBACK_STREAM) {
-        attributes->maxlength = 16000;
-        attributes->tlength = 8192;
+        attributes->maxlength = 88200;
+        attributes->tlength = 22050;
         attributes->prebuf = 4096;      // Pulseaudio will not start if prebuffering is not reached
-        attributes->minreq = 2048;       // The server side playback framesize
-        attributes->fragsize = 4096;    // Fragment size at wich we receive an interupt
-        pa_stream_connect_playback( s , NULL , attributes, PA_STREAM_INTERPOLATE_TIMING, &_volume, NULL);
+        attributes->minreq = 2048;      // The server side playback framesize
+        attributes->fragsize = 11025;    // Fragment size at wich we receive an interupt
+        pa_stream_connect_playback( s , NULL , attributes, PA_STREAM_NOFLAGS, &_volume, NULL);
         // pa_stream_connect_playback (s , NULL , attributes, PA_STREAM_START_CORKED, &_volume, NULL);
     } else if (_streamType == CAPTURE_STREAM) {
 
         // attributes->maxlength = 66500;
         // attributes->fragsize = (uint32_t)-1;
 
-        attributes->maxlength = 32000;
-        attributes->tlength = (uint32_t)-1;
-        attributes->prebuf = (uint32_t)-1;
-        attributes->minreq = (uint32_t)-1;
-        attributes->fragsize = 4096;
+        attributes->maxlength = 88200;
+        attributes->tlength = 22050;
+        attributes->prebuf = 4096;
+        attributes->minreq = 2048;
+        attributes->fragsize = 11025;
 
         // 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, NULL, PA_STREAM_INTERPOLATE_TIMING );
+	pa_stream_connect_record( s, NULL, NULL, PA_STREAM_NOFLAGS);
     } else if (_streamType == UPLOAD_STREAM) {
         pa_stream_connect_upload (s , 1024);
     } else {
diff --git a/sflphone-common/src/audio/pulseaudio/pulselayer.cpp b/sflphone-common/src/audio/pulseaudio/pulselayer.cpp
index e46e1e9524..7801582cb7 100644
--- a/sflphone-common/src/audio/pulseaudio/pulselayer.cpp
+++ b/sflphone-common/src/audio/pulseaudio/pulselayer.cpp
@@ -30,6 +30,7 @@ static  void playback_callback (pa_stream* s, size_t bytes, void* userdata)
     assert (s && bytes);
     assert (bytes > 0);
     static_cast<PulseLayer*> (userdata)->processPlaybackData();
+    // static_cast<PulseLayer*> (userdata)->processData();
 }
 
 static void capture_callback (pa_stream* s, size_t bytes, void* userdata)
@@ -39,6 +40,7 @@ static void capture_callback (pa_stream* s, size_t bytes, void* userdata)
     assert(s && bytes);
     assert(bytes > 0);
     static_cast<PulseLayer*> (userdata)->processCaptureData();
+    // static_cast<PulseLayer*> (userdata)->processData();
 }
 
 
@@ -357,12 +359,15 @@ void PulseLayer::startStream (void)
 	// Create Streams
 	connectPulseAudioServer();
 
-	_urgentRingBuffer.flushAll();
-	_mainBuffer.flushAllBuffers();
+	// _urgentRingBuffer.flushAll();
+	// _mainBuffer.flushAllBuffers();
 
 	is_started = true;
     }
 
+    _urgentRingBuffer.flushAll();
+    _mainBuffer.flushAllBuffers();
+
 }
 
 void
@@ -451,6 +456,30 @@ void PulseLayer::processCaptureData(void)
     
 }
 
+
+void PulseLayer::processData(void)
+{
+
+    // Handle the data for the speakers
+    if ( playback &&(playback->pulseStream()) && (pa_stream_get_state (playback->pulseStream()) == PA_STREAM_READY)) {
+
+	// _debug("PulseLayer::processPlaybackData()\n");
+
+        // 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)
+            return;
+
+        writeToSpeaker();
+    }
+
+    // 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)
 {
     /** Bytes available in the urgent ringbuffer ( reserved for DTMF ) */
@@ -471,9 +500,9 @@ void PulseLayer::writeToSpeaker (void)
     urgentAvailBytes = _urgentRingBuffer.AvailForGet();
 
 
-    if (urgentAvailBytes > 0) {
+    if (urgentAvailBytes > (framesPerBuffer*sizeof(SFLDataFormat))) {
 
-        // _debug("urgentAvailBytes: %i\n", urgentAvailBytes);
+        _debug("urgentAvailBytes: %i\n", urgentAvailBytes);
 
         toGet = (urgentAvailBytes < (int) (framesPerBuffer * sizeof (SFLDataFormat))) ? urgentAvailBytes : framesPerBuffer * sizeof (SFLDataFormat);
         out = (SFLDataFormat*) pa_xmalloc (toGet * sizeof (SFLDataFormat));
@@ -490,6 +519,8 @@ void PulseLayer::writeToSpeaker (void)
         AudioLoop* tone = _manager->getTelephoneTone();
 	AudioLoop* file_tone = _manager->getTelephoneFile();
 
+	_urgentRingBuffer.flushAll();
+
         if (tone != 0) {
 
 	    if (playback->getStreamState() == PA_STREAM_READY)
@@ -577,12 +608,14 @@ void PulseLayer::writeToSpeaker (void)
 		if((tone == 0) && (file_tone == 0)) {
 
 		    // _debug("maxNbBytesToGet: %i\n", maxNbBytesToGet);
+		    
 		    SFLDataFormat* zeros = (SFLDataFormat*)pa_xmalloc (framesPerBuffer*sizeof(SFLDataFormat));
   
 		    bzero (zeros, framesPerBuffer*sizeof(SFLDataFormat));
 		    pa_stream_write(playback->pulseStream(), zeros, framesPerBuffer*sizeof(SFLDataFormat), NULL, 0, PA_SEEK_RELATIVE);
 
 		    pa_xfree (zeros);
+		    
 
 		}
             }
@@ -603,7 +636,7 @@ void PulseLayer::readFromMic (void)
     size_t r;
 
     if (pa_stream_peek (record->pulseStream() , (const void**) &data , &r) < 0 || !data) {
-        //_debug("pa_stream_peek() failed: %s\n" , pa_strerror( pa_context_errno( context) ));
+        _debug("pa_stream_peek() failed: %s\n" , pa_strerror( pa_context_errno( context) ));
     }
 
     if (data != 0) {
diff --git a/sflphone-common/src/audio/pulseaudio/pulselayer.h b/sflphone-common/src/audio/pulseaudio/pulselayer.h
index e4a4981e57..4e7e30e816 100644
--- a/sflphone-common/src/audio/pulseaudio/pulselayer.h
+++ b/sflphone-common/src/audio/pulseaudio/pulselayer.h
@@ -133,6 +133,8 @@ class PulseLayer : public AudioLayer {
     void processPlaybackData( void );
 
     void processCaptureData( void );
+
+    void processData(void);
     
   private:
     // Copy Constructor
diff --git a/sflphone-common/src/managerimpl.cpp b/sflphone-common/src/managerimpl.cpp
index 95293f6dc5..21b400a822 100644
--- a/sflphone-common/src/managerimpl.cpp
+++ b/sflphone-common/src/managerimpl.cpp
@@ -1651,6 +1651,8 @@ ManagerImpl::playDtmf (char code, bool isTalking)
     AudioLayer *audiolayer;
     SFLDataFormat *buf;
 
+    _debug("ManagerImpl::playDtmf\n");
+
     stopTone (false);
 
     bool hasToPlayTone = getConfigBool (SIGNALISATION, PLAY_DTMF);
@@ -1689,6 +1691,9 @@ ManagerImpl::playDtmf (char code, bool isTalking)
     //                            ms/s
     size = (int) ((pulselen * (float) audiolayer->getSampleRate()) / 1000);
 
+    _debug("DTMF pulselen: %i\n", pulselen);
+    _debug("DTMF size: %i\n", size);
+
     // this buffer is for mono
     // TODO <-- this should be global and hide if same size
     buf = new SFLDataFormat[size];
@@ -2023,6 +2028,8 @@ bool ManagerImpl::playATone (Tone::TONEID toneId)
     AudioLayer *audiolayer;
     unsigned int nbSamples;
 
+    _debug("ManagerImpl::playATone\n");
+
     hasToPlayTone = getConfigBool (SIGNALISATION, PLAY_TONES);
 
     if (!hasToPlayTone)
@@ -2213,6 +2220,8 @@ void ManagerImpl::notificationIncomingCall (void)
 
     audiolayer = getAudioDriver();
 
+    _debug("ManagerImpl::notificationIncomingCall\n");
+
     if (audiolayer != 0) {
         samplerate = audiolayer->getSampleRate();
         frequency << "440/" << FRAME_PER_BUFFER;
-- 
GitLab