From b6771a0c529d4c31b20b24af483e96435585889b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Anthony=20L=C3=A9onard?=
 <anthony.leonard@savoirfairelinux.com>
Date: Tue, 20 Sep 2016 14:52:37 -0400
Subject: [PATCH] audio: TelephoneTone isn't recreated entirely anymore

A new instance of TelephoneTone was created every time the
sample rate was changed. Consequently, the selected tone
was lost each time it happened and the ALSA backend was
trying to read an empty buffer in an infinite loop when the
contact wasn't answering the call.
The precise changes are :
 * A setSampleRate was added as a method in tonelist[.cpp|.h]
 * A buildTones method was also created to prevent code
   redundancy.
 * setSampleRate is used instead of recreating the object in
   tonecontrol.cpp

Change-Id: I44a86345953068848d0304516d502de5c37bb113
Tuleap: #168
Reviewed-by: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
---
 src/media/audio/sound/tonelist.cpp | 26 +++++++++++++++++++-------
 src/media/audio/sound/tonelist.h   |  3 +++
 src/media/audio/tonecontrol.cpp    |  5 ++++-
 3 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/src/media/audio/sound/tonelist.cpp b/src/media/audio/sound/tonelist.cpp
index ec2a107b4a..9e52dbd6c1 100644
--- a/src/media/audio/sound/tonelist.cpp
+++ b/src/media/audio/sound/tonelist.cpp
@@ -91,14 +91,9 @@ TelephoneTone::getCountryId(const std::string& countryName)
 }
 
 TelephoneTone::TelephoneTone(const std::string& countryName, unsigned int sampleRate) :
-    currentTone_(Tone::TONE_NULL)
+    currentTone_(Tone::TONE_NULL), countryId_(getCountryId(countryName))
 {
-    TelephoneTone::COUNTRYID countryId = getCountryId(countryName);
-
-    tone_[Tone::TONE_DIALTONE] = new Tone(toneZone[countryId][Tone::TONE_DIALTONE], sampleRate);
-    tone_[Tone::TONE_BUSY] = new Tone(toneZone[countryId][Tone::TONE_BUSY], sampleRate);
-    tone_[Tone::TONE_RINGTONE] = new Tone(toneZone[countryId][Tone::TONE_RINGTONE], sampleRate);
-    tone_[Tone::TONE_CONGESTION] = new Tone(toneZone[countryId][Tone::TONE_CONGESTION], sampleRate);
+    buildTones(sampleRate);
 }
 
 TelephoneTone::~TelephoneTone()
@@ -116,6 +111,14 @@ TelephoneTone::setCurrentTone(Tone::TONEID toneId)
     currentTone_ = toneId;
 }
 
+void
+TelephoneTone::setSampleRate(unsigned int sampleRate)
+{
+    for (size_t i=0; i < Tone::TONE_NULL; i++)
+        delete tone_[i];
+    buildTones(sampleRate);
+}
+
 Tone*
 TelephoneTone::getCurrentTone()
 {
@@ -125,4 +128,13 @@ TelephoneTone::getCurrentTone()
     return tone_[currentTone_];
 }
 
+void
+TelephoneTone::buildTones(unsigned int sampleRate)
+{
+    tone_[Tone::TONE_DIALTONE] = new Tone(toneZone[countryId_][Tone::TONE_DIALTONE], sampleRate);
+    tone_[Tone::TONE_BUSY] = new Tone(toneZone[countryId_][Tone::TONE_BUSY], sampleRate);
+    tone_[Tone::TONE_RINGTONE] = new Tone(toneZone[countryId_][Tone::TONE_RINGTONE], sampleRate);
+    tone_[Tone::TONE_CONGESTION] = new Tone(toneZone[countryId_][Tone::TONE_CONGESTION], sampleRate);
+}
+
 } // namespace ring
diff --git a/src/media/audio/sound/tonelist.h b/src/media/audio/sound/tonelist.h
index f57f4e3c5a..d1614c9f68 100644
--- a/src/media/audio/sound/tonelist.h
+++ b/src/media/audio/sound/tonelist.h
@@ -46,6 +46,7 @@ class TelephoneTone {
         ~TelephoneTone();
 
         void setCurrentTone(Tone::TONEID toneId);
+        void setSampleRate(unsigned int sampleRate);
         Tone* getCurrentTone();
 
     private:
@@ -53,6 +54,8 @@ class TelephoneTone {
 
         static COUNTRYID getCountryId(const std::string& countryName);
 
+        void buildTones(unsigned int sampleRate);
+        COUNTRYID countryId_;
         Tone* tone_[Tone::TONE_NULL];
         Tone::TONEID currentTone_;
 };
diff --git a/src/media/audio/tonecontrol.cpp b/src/media/audio/tonecontrol.cpp
index 06331a9bf9..a4a3ba16e5 100644
--- a/src/media/audio/tonecontrol.cpp
+++ b/src/media/audio/tonecontrol.cpp
@@ -44,7 +44,10 @@ ToneControl::setSampleRate(unsigned rate)
 {
     std::lock_guard<std::mutex> lk(mutex_);
     sampleRate_ = rate;
-    telephoneTone_.reset(new TelephoneTone(prefs_.getZoneToneChoice(), rate));
+    if (!telephoneTone_)
+        telephoneTone_.reset(new TelephoneTone(prefs_.getZoneToneChoice(), rate));
+    else
+        telephoneTone_->setSampleRate(rate);
 }
 
 AudioLoop*
-- 
GitLab