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