mirror of
https://git.jami.net/savoirfairelinux/jami-daemon.git
synced 2025-08-12 22:09:25 +08:00
Add audiofile for playing wave on incoming call
This commit is contained in:
@ -29,6 +29,7 @@ AudioFile::AudioFile()
|
||||
{
|
||||
// could vary later...
|
||||
_ulaw = new Ulaw (PAYLOAD_CODEC_ULAW, "G711u");
|
||||
_start = false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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__
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -22,7 +22,6 @@
|
||||
|
||||
#ifndef __RING_BUFFER__
|
||||
#define __RING_BUFFER__
|
||||
#include <cc++/thread.h>
|
||||
|
||||
typedef unsigned char* samplePtr;
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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];
|
||||
|
@ -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()
|
||||
|
@ -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);
|
||||
AudioLayer* audiolayer = getAudioDriver();
|
||||
if (audiolayer != 0) {
|
||||
std::ostringstream frequency;
|
||||
frequency << "440/" << FRAME_PER_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;
|
||||
Tone tone(frequency.str());
|
||||
unsigned int nbInt16 = tone.getSize();
|
||||
int16 buf[nbInt16];
|
||||
tone.getNext(buf, tone.getMonoSize());
|
||||
audiolayer->putUrgent(buf, sizeof(int16)*nbInt16);
|
||||
}
|
||||
getAudioDriver()->putUrgent(buf_ctrl_vol, SAMPLES_SIZE(FRAME_PER_BUFFER));
|
||||
|
||||
delete[] buf_ctrl_vol; buf_ctrl_vol = NULL;
|
||||
delete[] buffer; buffer = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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();
|
||||
|
Reference in New Issue
Block a user