From dbc2f47f2db460cf5761235a80c69087eaf37e0b Mon Sep 17 00:00:00 2001
From: yanmorin <yanmorin>
Date: Wed, 2 Nov 2005 16:32:15 +0000
Subject: [PATCH] Add audiofile for playing wave on incoming call

---
 src/audio/audiofile.cpp     |   1 +
 src/audio/audiofile.h       |   4 ++
 src/audio/audiolayer.cpp    |   4 +-
 src/audio/audiolayer.h      |   3 +-
 src/audio/audioloop.h       |   2 +
 src/audio/ringbuffer.h      |   1 -
 src/audio/tonegenerator.cpp |  59 -----------------
 src/audio/tonegenerator.h   |  15 +----
 src/audio/tonelist.cpp      |   2 +
 src/managerimpl.cpp         | 124 ++++++++++++++++++------------------
 src/managerimpl.h           |  22 ++++---
 11 files changed, 89 insertions(+), 148 deletions(-)

diff --git a/src/audio/audiofile.cpp b/src/audio/audiofile.cpp
index dac50b8873..b2a16efb5e 100644
--- a/src/audio/audiofile.cpp
+++ b/src/audio/audiofile.cpp
@@ -29,6 +29,7 @@ AudioFile::AudioFile()
 {
   // could vary later...
   _ulaw = new Ulaw (PAYLOAD_CODEC_ULAW, "G711u");
+  _start = false;
 }
 
 
diff --git a/src/audio/audiofile.h b/src/audio/audiofile.h
index 2f2e1c72a5..7d7fc04999 100644
--- a/src/audio/audiofile.h
+++ b/src/audio/audiofile.h
@@ -36,10 +36,14 @@ public:
   ~AudioFile();
 
   bool loadFile(const std::string& filename);
+  void start() { _start = true; }
+  void stop()  { _start = false; }
+  bool isStarted() { return _start; }
 
 private:
   std::string _filename;
   Ulaw* _ulaw;
+  bool _start;
 };
 
 #endif // __AUDIOFILE_H__
diff --git a/src/audio/audiolayer.cpp b/src/audio/audiolayer.cpp
index d370b52982..d372c5f8ac 100644
--- a/src/audio/audiolayer.cpp
+++ b/src/audio/audiolayer.cpp
@@ -249,9 +249,11 @@ AudioLayer::audioCallback (const void *inputBuffer, void *outputBuffer,
 		_mainSndRingBuffer.Discard(toGet);
 	}  
 	else {
-    Tone* tone = Manager::instance().getTelephoneTone();
+    AudioLoop* tone = Manager::instance().getTelephoneTone();
     if ( tone != 0) {
       tone->getNext(out, framesPerBuffer, spkrVolume);
+    } else if ( (tone=Manager::instance().getTelephoneFile()) != 0 ) {
+      tone->getNext(out, framesPerBuffer, spkrVolume);
     } else {
       // If nothing urgent, play the regular sound samples
       normalAvail = _mainSndRingBuffer.AvailForGet();
diff --git a/src/audio/audiolayer.h b/src/audio/audiolayer.h
index 5112b48c4c..b444ed8370 100644
--- a/src/audio/audiolayer.h
+++ b/src/audio/audiolayer.h
@@ -23,11 +23,12 @@
 #ifndef _AUDIO_LAYER_H
 #define _AUDIO_LAYER_H
 
+#include <cc++/thread.h> // for ost::Mutex
+
 #include "portaudiocpp/PortAudioCpp.hxx"
 
 #include "../global.h"
 #include "ringbuffer.h"
-#include <cc++/thread.h>
 
 #define FRAME_PER_BUFFER	160
 #define MIC_CHANNELS 		2 // 1=mono 2=stereo
diff --git a/src/audio/audioloop.h b/src/audio/audioloop.h
index 2322831f0a..e85ca9cadc 100644
--- a/src/audio/audioloop.h
+++ b/src/audio/audioloop.h
@@ -41,6 +41,8 @@ public:
    */
   int getNext(int16* output, int nb, short volume=100);
   void reset() { _pos = 0; }
+  unsigned int getMonoSize() { return _size>>1; }
+  unsigned int getSize() { return _size; }
 
 protected:
   int16* _buffer;
diff --git a/src/audio/ringbuffer.h b/src/audio/ringbuffer.h
index 02c4a1e8f0..f5de45606f 100644
--- a/src/audio/ringbuffer.h
+++ b/src/audio/ringbuffer.h
@@ -22,7 +22,6 @@
 
 #ifndef __RING_BUFFER__
 #define __RING_BUFFER__
-#include <cc++/thread.h>
 
 typedef unsigned char* samplePtr;
 
diff --git a/src/audio/tonegenerator.cpp b/src/audio/tonegenerator.cpp
index ef865aa1f7..4b3b4057b9 100644
--- a/src/audio/tonegenerator.cpp
+++ b/src/audio/tonegenerator.cpp
@@ -101,9 +101,6 @@ ToneThread::run (void) {
 ToneGenerator::ToneGenerator () {	
 	this->initTone();
 	tonethread = NULL;
-	_dst = NULL;
-	_src = NULL;
-	_ulaw = new Ulaw (PAYLOAD_CODEC_ULAW, "G711u");
 
   _currentTone = ZT_TONE_NULL;
   _currentZone = 0;
@@ -111,9 +108,6 @@ ToneGenerator::ToneGenerator () {
 
 ToneGenerator::~ToneGenerator (void) {
 	delete tonethread; tonethread = 0;
-  delete [] _dst;    _dst = 0;
-  delete [] _src;    _src = 0;
-  delete _ulaw;      _ulaw = 0;
 }
 
 /**
@@ -345,59 +339,6 @@ ToneGenerator::stopTone() {
   //_debug("Thread: tonethread deleted\n");
 }
 
-/**
- * @return 1 if everything is ok
- */
-int
-ToneGenerator::playRingtone (const char *fileName) {
-  if (tonethread != NULL) {
-    stopTone();
-  }
-  delete [] _dst; _dst = NULL;
-  delete [] _src; _src = NULL;
-
-	int expandedsize, length;
-
-	if (fileName == NULL) {
-		return 0;
-	}
-	
-	std::fstream file;
-	file.open(fileName, std::fstream::in);
-	if (!file.is_open()) {
-		return 0;
-  	}
-
-  // get length of file:
-  file.seekg (0, std::ios::end);
-  length = file.tellg();
-  file.seekg (0, std::ios::beg);
-
-    // allocate memory:
-  _src = new char [length];
-  _dst = new short[length*2];
-
-  // read data as a block:
-  file.read (_src,length);
-  file.close();
-
-  // Decode file.ul
-  // expandedsize is the number of bytes, not the number of int
-  expandedsize = _ulaw->codecDecode (_dst, (unsigned char *)_src, length);
-
-  //_debug("length (pre-ulaw) : %d\n", length);
-  //_debug("expandedsize (post-ulaw) : %d\n", expandedsize);
-
-  if (tonethread == NULL) {
-    //_debug("Thread: start tonethread\n");
-    // send the number of int16, so device by two
-    tonethread = new ToneThread ((int16*)_dst, expandedsize>>1);
-    tonethread->start();
-  }
-
-  return 1;
-}
-
 int
 ToneGenerator::contains (const std::string& str, char c)
 {
diff --git a/src/audio/tonegenerator.h b/src/audio/tonegenerator.h
index a857b9df8f..fbf2123115 100644
--- a/src/audio/tonegenerator.h
+++ b/src/audio/tonegenerator.h
@@ -22,10 +22,9 @@
 #define __TONE_GENERATOR_H__
 
 #include <string>
+#include <cc++/thread.h>
 
 #include "../global.h"
-#include "ulaw.h"
-#include <cc++/thread.h>
 
 #define ZT_TONE_DIALTONE   0
 #define ZT_TONE_BUSY       1
@@ -96,17 +95,11 @@ public:
   void stopTone();
 
 
-	/**
-	 * Play the ringtone when incoming call occured
-	 */
-	int  playRingtone		(const char*);
-	
 	///////////////////////////
 	// Public members variable
 	//////////////////////////
 	int16 *sample;
-	int freq1, 
-		freq2;
+	int freq1, freq2;
 	int time;
 	int totalbytes;
 	
@@ -131,10 +124,6 @@ private:
 	std::string toneZone[NB_ZONES_MAX][NB_TONES_MAX];
 	ToneThread*	tonethread;
 
-	short* _dst;
-	char* _src;
-	Ulaw* _ulaw;
-
   unsigned int _currentTone;
   unsigned int _currentZone;
 	int16 _buf[SIZEBUF];
diff --git a/src/audio/tonelist.cpp b/src/audio/tonelist.cpp
index cbf6620702..c335faa169 100644
--- a/src/audio/tonelist.cpp
+++ b/src/audio/tonelist.cpp
@@ -110,6 +110,8 @@ TelephoneTone::TelephoneTone(const std::string& countryName) {
   _tone[Tone::TONE_BUSY] = new Tone(_toneList.getDefinition(countryId, Tone::TONE_BUSY));
   _tone[Tone::TONE_RINGTONE] = new Tone(_toneList.getDefinition(countryId, Tone::TONE_RINGTONE));
   _tone[Tone::TONE_CONGESTION] = new Tone(_toneList.getDefinition(countryId, Tone::TONE_CONGESTION));
+
+  _currentTone = Tone::TONE_NULL; 
 }
 
 TelephoneTone::~TelephoneTone() 
diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp
index a839713460..94de3ae04c 100644
--- a/src/managerimpl.cpp
+++ b/src/managerimpl.cpp
@@ -20,31 +20,29 @@
 
 #include <errno.h>
 #include <time.h>
+#include <cstdlib>
+#include <iostream>
+#include <fstream>
 
 #include <sys/types.h> // mkdir(2)
 #include <sys/stat.h>	// mkdir(2)
 
-#include <cc++/thread.h>
+#include <cc++/socket.h>   // why do I need this here?
+#include <ccrtp/channel.h> // why do I need this here?
+#include <ccrtp/rtp.h>     // why do I need this here?
 #include <cc++/file.h>
 
-#include <cstdlib> 
-#include <iostream>
-#include <fstream> 
-#include <string>
-#include <vector>
-
-#include "sipvoiplink.h"
 #include "manager.h"
-#include "audio/audiocodec.h"
 #include "audio/audiolayer.h"
-#include "audio/ringbuffer.h"
-#include "audio/tonegenerator.h"
+#include "audio/audiocodec.h"
+//#include "audio/ringbuffer.h"
 #include "audio/tonelist.h"
 
+#include "sipvoiplink.h"
+#include "voIPLink.h"
 #include "call.h"
-//#include "error.h"
+
 #include "user_cfg.h"
-#include "voIPLink.h" 
 #include "gui/guiframework.h"
 
 #ifdef USE_ZEROCONF
@@ -85,9 +83,6 @@ ManagerImpl::ManagerImpl (void)
   _mic_volume  = 0; 
   _mic_volume_before_mute = 0;
 
-  _tone = new ToneGenerator();	
-  _toneType = ZT_TONE_NULL;
-
   // Call
   _currentCallId = 0;
   _nbIncomingWaitingCall=0;
@@ -101,7 +96,6 @@ ManagerImpl::ManagerImpl (void)
 ManagerImpl::~ManagerImpl (void) 
 {
   terminate();
-  delete _tone;  _tone = NULL;
 
 #ifdef USE_ZEROCONF
   delete _DNSService; _DNSService = NULL;
@@ -884,6 +878,7 @@ ManagerImpl::playATone(Tone::TONEID toneId) {
   _toneMutex.enterMutex();
   _telephoneTone->setCurrentTone(toneId);
   _toneMutex.leaveMutex();
+
   getAudioDriver()->startStream();
   return true;
 }
@@ -893,7 +888,6 @@ ManagerImpl::playATone(Tone::TONEID toneId) {
  */
 void 
 ManagerImpl::stopTone() {
-  _debug("TONE: stop tone/stream...\n");
   getAudioDriver()->stopStream();
 
   _toneMutex.enterMutex();
@@ -902,10 +896,7 @@ ManagerImpl::stopTone() {
 
   // for ringing tone..
   _toneMutex.enterMutex();
-  if ( _toneType != ZT_TONE_NULL ) {
-    _toneType = ZT_TONE_NULL;
-    _tone->stopTone();
-  }
+  _audiofile.stop();
   _toneMutex.leaveMutex();
 }
 
@@ -915,7 +906,6 @@ ManagerImpl::stopTone() {
 bool
 ManagerImpl::playTone()
 {
-  _debug("TONE: play dialtone...\n");
   return playATone(Tone::TONE_DIALTONE);
 }
 
@@ -935,6 +925,31 @@ ManagerImpl::ringback () {
   playATone(Tone::TONE_RINGTONE);
 }
 
+/**
+ * Multi Thread
+ */
+void
+ManagerImpl::ringtone() 
+{
+  std::string ringchoice = getConfigString(AUDIO, RING_CHOICE);
+  //if there is no / inside the path
+  if ( ringchoice.find(DIR_SEPARATOR_CH) == std::string::npos ) {
+    // check inside global share directory
+    ringchoice = std::string(PROGSHAREDIR) + DIR_SEPARATOR_STR + RINGDIR + DIR_SEPARATOR_STR + ringchoice; 
+  }
+  _toneMutex.enterMutex(); 
+  bool loadFile = _audiofile.loadFile(ringchoice);
+  _toneMutex.leaveMutex(); 
+  if (loadFile) {
+    _toneMutex.enterMutex(); 
+    _audiofile.start();
+    _toneMutex.leaveMutex(); 
+    getAudioDriver()->startStream();
+  } else {
+    ringback();
+  }
+}
+
 /**
  * Multi Thread
  */
@@ -965,7 +980,7 @@ ManagerImpl::callFailure(CALLID id) {
   }
 }
 
-Tone *
+AudioLoop*
 ManagerImpl::getTelephoneTone()
 {
   if(_telephoneTone) {
@@ -977,54 +992,37 @@ ManagerImpl::getTelephoneTone()
   }
 }
 
-
-/**
- * Multi Thread
- */
-void
-ManagerImpl::ringtone() 
+AudioLoop*
+ManagerImpl::getTelephoneFile()
 {
-  //std::string ringchoice = getConfigString(AUDIO, RING_CHOICE);
-  // if there is no / inside the path
-  //if ( ringchoice.find(DIR_SEPARATOR_CH) == std::string::npos ) {
-    // check inside global share directory
-  //  ringchoice = std::string(PROGSHAREDIR) + DIR_SEPARATOR_STR + RINGDIR + DIR_SEPARATOR_STR + ringchoice; 
-  //}
-  //_toneMutex.enterMutex(); 
-  //_toneType = ZT_TONE_FILE;
-  //int play = _tone->playRingtone(ringchoice.c_str());
-  //_toneMutex.leaveMutex();
-  //if (play!=1) {
-    ringback();
-  //}
+  ost::MutexLock m(_toneMutex);
+  if(_audiofile.isStarted()) {
+    return &_audiofile;
+  } else {
+    return 0;
+  }
 }
 
+
 /**
  * Use Urgent Buffer
  * By AudioRTP thread
  */
 void
 ManagerImpl::notificationIncomingCall (void) {
-  int16* buf_ctrl_vol;
-  int16* buffer = new int16[SAMPLING_RATE];
-  int size = SAMPLES_SIZE(FRAME_PER_BUFFER); //SAMPLING_RATE/2;
-  int k;
-  //int spkrVolume;
-
-  _tone->generateSin(440, 0, buffer);
-
-  // Volume Control 
-  buf_ctrl_vol = new int16[size*CHANNELS];
-  // spkrVolume = getSpkrVolume();
-  for (int j = 0; j < size; j++) {
-    k = j<<1; // fast multiply by two
-    buf_ctrl_vol[k] = buf_ctrl_vol[k+1] = buffer[j];
-    // * spkrVolume/100;
-  }
-  getAudioDriver()->putUrgent(buf_ctrl_vol, SAMPLES_SIZE(FRAME_PER_BUFFER));
-
-  delete[] buf_ctrl_vol;  buf_ctrl_vol = NULL;
-  delete[] buffer;        buffer = NULL;
+
+  AudioLayer* audiolayer = getAudioDriver();
+  if (audiolayer != 0) {
+    std::ostringstream frequency;
+    frequency << "440/" << FRAME_PER_BUFFER;
+
+    Tone tone(frequency.str());
+    unsigned int nbInt16 = tone.getSize();
+    int16 buf[nbInt16];
+    tone.getNext(buf, tone.getMonoSize());
+    audiolayer->putUrgent(buf, sizeof(int16)*nbInt16);
+  }
+
 }
 
 /**
diff --git a/src/managerimpl.h b/src/managerimpl.h
index f986eddc35..294b6323ef 100644
--- a/src/managerimpl.h
+++ b/src/managerimpl.h
@@ -21,24 +21,24 @@
 #ifndef __MANAGER_H__
 #define __MANAGER_H__
 
-#include <cc++/thread.h>
 #include <string>
 #include <vector>
+#include <cc++/thread.h>
 
-#include "audio/tonelist.h" // for Tone::TONEID declaration
 #include "../stund/stun.h"
 #include "call.h"
-#include "audio/audiodevice.h"
 #include "observer.h"
 #include "config/config.h"
+
+#include "audio/audiodevice.h"
+#include "audio/tonelist.h" // for Tone::TONEID declaration
+#include "audio/audiofile.h"
 #include "audio/dtmf.h"
 #include "audio/codecDescriptor.h"
 
 class AudioLayer;
 class CodecDescriptor;
-//class Error;
 class GuiFramework;
-class ToneGenerator;
 
 class TelephoneTone;
 
@@ -191,7 +191,9 @@ public:
   void callFailure(CALLID id);
 
   // return 0 if no tone (init before calling this function)
-  Tone* getTelephoneTone();
+  AudioLoop* getTelephoneTone();
+  // return 0 if the wav is stopped
+  AudioLoop* getTelephoneFile();
 
   /**
    * @return true is there is one or many incoming call waiting
@@ -305,10 +307,10 @@ private:
   /////////////////////
   // Private variables
   /////////////////////
-  ToneGenerator* _tone;
+  //ToneGenerator* _tone;
   TelephoneTone* _telephoneTone;
+  AudioFile _audiofile;
   ost::Mutex _toneMutex;
-  int _toneType;
 
   //
   // Multithread variable with extern accessor and change only inside the main thread
@@ -378,8 +380,8 @@ private:
   short _mic_volume_before_mute;
 
 	// To handle firewall
-  int			_firewallPort;
-  std::string		_firewallAddr;
+  int _firewallPort;
+  std::string _firewallAddr;
 
   // return false if exosip or the network checking failed
   bool initRegisterVoIPLink();
-- 
GitLab