mirror of
https://git.jami.net/savoirfairelinux/jami-daemon.git
synced 2025-08-12 22:09:25 +08:00
Merge commit 'origin/master' into video
This commit is contained in:
@ -44,5 +44,6 @@ Dependencies to use audio codecs
|
||||
`--------------------`----------`-----------------------------------------------------
|
||||
Program Version Notes
|
||||
--------------------------------------------------------------------------------------
|
||||
libgsm1 1.0.10 Standard package - Necessary to use GSM codec
|
||||
libgsm1-dev 1.0.10 Standard package - Necessary to use GSM codec
|
||||
libspeex1-dev 1.1.12 Standard package - Necessary to use SPEEX codec
|
||||
--------------------------------------------------------------------------------------
|
||||
|
@ -1,4 +1,4 @@
|
||||
sflcodecdir = ($libdir)/sflphone/codecs
|
||||
sflcodecdir = $(libdir)/sflphone/codecs
|
||||
bin_PROGRAMS = sflphoned
|
||||
|
||||
|
||||
|
@ -18,78 +18,99 @@
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "CodecSpeex.h"
|
||||
#include "audiocodec.h"
|
||||
#include <speex/speex.h>
|
||||
|
||||
CodecSpeex::CodecSpeex(int payload)
|
||||
: AudioCodec(payload, "speex")
|
||||
{
|
||||
_description = "Speex";
|
||||
|
||||
_clockRate = 8000;
|
||||
_channel = 1;
|
||||
initSpeex();
|
||||
}
|
||||
class CodecSpeex : public AudioCodec{
|
||||
public:
|
||||
CodecSpeex(int payload=0)
|
||||
: AudioCodec(payload, "speex")
|
||||
{
|
||||
_clockRate = 8000;
|
||||
_channel = 1;
|
||||
initSpeex();
|
||||
}
|
||||
|
||||
void
|
||||
CodecSpeex::initSpeex() {
|
||||
if (_clockRate < 16000 ) {
|
||||
_speexModePtr = &speex_nb_mode;
|
||||
} else if (_clockRate < 32000) {
|
||||
_speexModePtr = &speex_wb_mode;
|
||||
} else {
|
||||
_speexModePtr = &speex_uwb_mode;
|
||||
}
|
||||
int getFrameSize(){ return _speex_frame_size; }
|
||||
|
||||
speex_bits_init(&_speex_dec_bits);
|
||||
_speex_dec_state = speex_decoder_init(_speexModePtr);
|
||||
void initSpeex() {
|
||||
if (_clockRate < 16000 ) {
|
||||
_speexModePtr = &speex_nb_mode;
|
||||
} else if (_clockRate < 32000) {
|
||||
_speexModePtr = &speex_wb_mode;
|
||||
} else {
|
||||
_speexModePtr = &speex_uwb_mode;
|
||||
}
|
||||
|
||||
speex_bits_init(&_speex_enc_bits);
|
||||
_speex_enc_state = speex_encoder_init(_speexModePtr);
|
||||
speex_bits_init(&_speex_dec_bits);
|
||||
_speex_dec_state = speex_decoder_init(_speexModePtr);
|
||||
|
||||
speex_decoder_ctl(_speex_dec_state, SPEEX_GET_FRAME_SIZE, &_speex_frame_size);
|
||||
}
|
||||
speex_bits_init(&_speex_enc_bits);
|
||||
_speex_enc_state = speex_encoder_init(_speexModePtr);
|
||||
|
||||
CodecSpeex::~CodecSpeex()
|
||||
{
|
||||
terminateSpeex();
|
||||
}
|
||||
speex_decoder_ctl(_speex_dec_state, SPEEX_GET_FRAME_SIZE, &_speex_frame_size);
|
||||
}
|
||||
|
||||
void
|
||||
CodecSpeex::terminateSpeex() {
|
||||
speex_bits_destroy(&_speex_dec_bits);
|
||||
speex_decoder_destroy(_speex_dec_state);
|
||||
_speex_dec_state = 0;
|
||||
~CodecSpeex()
|
||||
{
|
||||
terminateSpeex();
|
||||
}
|
||||
|
||||
speex_bits_destroy(&_speex_enc_bits);
|
||||
speex_encoder_destroy(_speex_enc_state);
|
||||
_speex_enc_state = 0;
|
||||
}
|
||||
void terminateSpeex() {
|
||||
speex_bits_destroy(&_speex_dec_bits);
|
||||
speex_decoder_destroy(_speex_dec_state);
|
||||
_speex_dec_state = 0;
|
||||
|
||||
int
|
||||
CodecSpeex::codecDecode (short *dst, unsigned char *src, unsigned int size)
|
||||
{
|
||||
speex_bits_destroy(&_speex_enc_bits);
|
||||
speex_encoder_destroy(_speex_enc_state);
|
||||
_speex_enc_state = 0;
|
||||
}
|
||||
|
||||
virtual int codecDecode (short *dst, unsigned char *src, unsigned int size)
|
||||
{
|
||||
// void *enh; speex_decoder_ctl(dec_state, SPEEX_SET_ENH, &enh);
|
||||
// decoding
|
||||
speex_bits_read_from(&_speex_dec_bits, (char*)src, size);
|
||||
int return_status = speex_decode_int(_speex_dec_state, &_speex_dec_bits, dst);
|
||||
//int return_status = speex_decode_int(_speex_dec_state, &_speex_dec_bits, dst);
|
||||
// 0 = no error
|
||||
// -1 = end of stream
|
||||
// -2 = other
|
||||
speex_decode_int(_speex_dec_state, &_speex_dec_bits, dst);
|
||||
|
||||
return _speex_frame_size;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
CodecSpeex::codecEncode (unsigned char *dst, short *src, unsigned int size)
|
||||
{
|
||||
virtual int codecEncode (unsigned char *dst, short *src, unsigned int size)
|
||||
{
|
||||
speex_bits_reset(&_speex_enc_bits);
|
||||
speex_encoder_ctl(_speex_enc_state,SPEEX_SET_SAMPLING_RATE,&_clockRate);
|
||||
|
||||
speex_encode_int(_speex_enc_state, src, &_speex_enc_bits);
|
||||
int nbBytes = speex_bits_write(&_speex_enc_bits, (char*)dst, size);
|
||||
return nbBytes;
|
||||
}
|
||||
|
||||
private:
|
||||
const SpeexMode* _speexModePtr;
|
||||
SpeexBits _speex_dec_bits;
|
||||
SpeexBits _speex_enc_bits;
|
||||
void *_speex_dec_state;
|
||||
void *_speex_enc_state;
|
||||
int _speex_frame_size;
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
//the class factories
|
||||
extern "C" AudioCodec* create(){
|
||||
return new CodecSpeex(110);
|
||||
}
|
||||
|
||||
extern "C" void destroy(AudioCodec* a){
|
||||
delete a;
|
||||
}
|
||||
|
||||
/*
|
||||
* Speex example
|
||||
|
@ -1,19 +1,23 @@
|
||||
sflcodecdir = $(libdir)/sflphone/codecs/
|
||||
|
||||
noinst_LTLIBRARIES = libaudio.la
|
||||
noinst_PROGRAMS = libcodec_ulaw.so libcodec_alaw.so libcodec_gsm.so
|
||||
noinst_PROGRAMS = libcodec_ulaw.so libcodec_alaw.so libcodec_gsm.so libcodec_speex.so
|
||||
|
||||
libcodec_ulaw_so_SOURCES = ulaw.cpp
|
||||
libcodec_ulaw_so_CFLAGS = -fPIC -g -Wall
|
||||
libcodec_ulaw_so_LDFLAGS = -shared
|
||||
libcodec_ulaw_so_LDFLAGS = -shared -lc
|
||||
|
||||
libcodec_alaw_so_SOURCES = alaw.cpp
|
||||
libcodec_alaw_so_CFLAGS = -fPIC -g -Wall
|
||||
libcodec_alaw_so_LDFLAGS = -shared
|
||||
libcodec_alaw_so_LDFLAGS = -shared -lc
|
||||
|
||||
libcodec_gsm_so_SOURCES = gsmcodec.cpp
|
||||
libcodec_gsm_so_CFLAGS = -fPIC -g -Wall
|
||||
libcodec_gsm_so_LDFLAGS = -shared -lgsm
|
||||
libcodec_gsm_so_LDFLAGS = -shared -lc -lgsm
|
||||
|
||||
libcodec_speex_so_SOURCES = CodecSpeex.cpp
|
||||
libcodec_speex_so_CFLAGS = -fPIC -g -Wall
|
||||
libcodec_speex_so_LDFLAGS = -shared -lc -lspeex
|
||||
|
||||
if USE_SPEEX
|
||||
SPEEX_SOURCES_CPP=CodecSpeex.cpp
|
||||
@ -25,6 +29,8 @@ SPEEX_FLAG=
|
||||
SPEEX_LIB=
|
||||
endif
|
||||
|
||||
#SUBDIRS = ilbc
|
||||
|
||||
libaudio_la_SOURCES = audiofile.cpp tonelist.cpp \
|
||||
audiortp.cpp dtmf.cpp tone.cpp audiolayer.cpp audiodevice.cpp dtmfgenerator.cpp \
|
||||
tonegenerator.cpp codecDescriptor.cpp \
|
||||
@ -40,8 +46,8 @@ noinst_HEADERS = audioloop.h common.h ringbuffer.h audiofile.h
|
||||
codecDescriptor.h dtmf.h tone.h \
|
||||
CodecSpeex.h
|
||||
|
||||
install-exec-local: install-libcodec_ulaw_so install-libcodec_alaw_so install-libcodec_gsm_so
|
||||
uninstall-local: uninstall-libcodec_ulaw_so uninstall-libcodec_alaw_so uninstall-libcodec_gsm_so
|
||||
install-exec-local: install-libcodec_ulaw_so install-libcodec_alaw_so install-libcodec_gsm_so install-libcodec_speex_so
|
||||
uninstall-local: uninstall-libcodec_ulaw_so uninstall-libcodec_alaw_so uninstall-libcodec_gsm_so uninstall-libcodec_speex_so
|
||||
|
||||
install-libcodec_ulaw_so: libcodec_ulaw.so
|
||||
mkdir -p $(sflcodecdir)
|
||||
@ -50,6 +56,8 @@ install-libcodec_alaw_so: libcodec_alaw.so
|
||||
$(INSTALL_PROGRAM) libcodec_alaw.so $(sflcodecdir)
|
||||
install-libcodec_gsm_so: libcodec_gsm.so
|
||||
$(INSTALL_PROGRAM) libcodec_gsm.so $(sflcodecdir)
|
||||
install-libcodec_speex_so: libcodec_speex.so
|
||||
$(INSTALL_PROGRAM) libcodec_speex.so $(sflcodecdir)
|
||||
|
||||
uninstall-libcodec_ulaw_so:
|
||||
rm -f $(sflcodecdir)/libcodec_ulaw.so
|
||||
@ -57,4 +65,6 @@ uninstall-libcodec_alaw_so:
|
||||
rm -f $(sflcodecdir)/libcodec_alaw.so
|
||||
uninstall-libcodec_gsm_so:
|
||||
rm -f $(sflcodecdir)/libcodec_gsm.so
|
||||
uninstall-libcodec_speex_so:
|
||||
rm -f $(sflcodecdir)/libcodec_speex.so
|
||||
rm -rf $(sflcodecdir)
|
||||
|
@ -23,100 +23,98 @@
|
||||
|
||||
class Alaw : public AudioCodec {
|
||||
public:
|
||||
|
||||
// 8 PCMA A 8000 1 [RFC3551]
|
||||
Alaw(int payload=0)
|
||||
: AudioCodec(payload, "PCMA")
|
||||
{
|
||||
//_description = "G711a";
|
||||
|
||||
_clockRate = 8000;
|
||||
_channel = 1;
|
||||
}
|
||||
// 8 PCMA A 8000 1 [RFC3551]
|
||||
Alaw(int payload=0)
|
||||
: AudioCodec(payload, "PCMA")
|
||||
{
|
||||
_clockRate = 8000;
|
||||
_channel = 1;
|
||||
}
|
||||
|
||||
|
||||
virtual int codecDecode (short *dst, unsigned char *src, unsigned int size)
|
||||
{
|
||||
int16* end = dst+size;
|
||||
while(dst<end)
|
||||
*dst++ = ALawDecode(*src++);
|
||||
return size<<1;
|
||||
}
|
||||
virtual int codecDecode (short *dst, unsigned char *src, unsigned int size)
|
||||
{
|
||||
int16* end = dst+size;
|
||||
while(dst<end)
|
||||
*dst++ = ALawDecode(*src++);
|
||||
return size<<1;
|
||||
}
|
||||
|
||||
int ALawDecode(uint8 alaw)
|
||||
{
|
||||
alaw ^= 0x55; // A-law has alternate bits inverted for transmission
|
||||
|
||||
uint sign = alaw&0x80;
|
||||
|
||||
int linear = alaw&0x1f;
|
||||
linear <<= 4;
|
||||
linear += 8; // Add a 'half' bit (0x08) to place PCM value in middle of range
|
||||
|
||||
alaw &= 0x7f;
|
||||
if(alaw>=0x20)
|
||||
{
|
||||
linear |= 0x100; // Put in MSB
|
||||
uint shift = (alaw>>4)-1;
|
||||
linear <<= shift;
|
||||
}
|
||||
|
||||
if(!sign)
|
||||
return -linear;
|
||||
else
|
||||
return linear;
|
||||
}
|
||||
|
||||
virtual int codecEncode (unsigned char *dst, short *src, unsigned int size)
|
||||
{
|
||||
size >>= 1;
|
||||
uint8* end = dst+size;
|
||||
while(dst<end)
|
||||
*dst++ = ALawEncode(*src++);
|
||||
return size;
|
||||
}
|
||||
virtual int codecEncode (unsigned char *dst, short *src, unsigned int size)
|
||||
{
|
||||
size >>= 1;
|
||||
uint8* end = dst+size;
|
||||
while(dst<end)
|
||||
*dst++ = ALawEncode(*src++);
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
uint8 ALawEncode (int16 pcm16)
|
||||
{
|
||||
int p = pcm16;
|
||||
uint u; // u-law value we are forming
|
||||
|
||||
if(p<0)
|
||||
{
|
||||
p = ~p;
|
||||
u = 0x80^0x10^0xff; // Sign bit = 1 (^0x10 because this will get inverted later) ^0xff ^0xff to invert final u-Law code
|
||||
}
|
||||
else
|
||||
int ALawDecode(uint8 alaw)
|
||||
{
|
||||
alaw ^= 0x55; // A-law has alternate bits inverted for transmission
|
||||
uint sign = alaw&0x80;
|
||||
int linear = alaw&0x1f;
|
||||
linear <<= 4;
|
||||
linear += 8; // Add a 'half' bit (0x08) to place PCM value in middle of range
|
||||
|
||||
alaw &= 0x7f;
|
||||
if(alaw>=0x20)
|
||||
{
|
||||
linear |= 0x100; // Put in MSB
|
||||
uint shift = (alaw>>4)-1;
|
||||
linear <<= shift;
|
||||
}
|
||||
|
||||
if(!sign)
|
||||
return -linear;
|
||||
else
|
||||
return linear;
|
||||
}
|
||||
|
||||
|
||||
uint8 ALawEncode (int16 pcm16)
|
||||
{
|
||||
int p = pcm16;
|
||||
uint a; // u-law value we are forming
|
||||
|
||||
if(p<0)
|
||||
{
|
||||
p = ~p;
|
||||
a = 0x00; // sign = 0
|
||||
}
|
||||
else
|
||||
{
|
||||
//+ve value
|
||||
a = 0x80; //sign = 1
|
||||
}
|
||||
//calculate segment and interval numbers
|
||||
p >>= 4;
|
||||
if(p>=0x20)
|
||||
{
|
||||
//+ve value
|
||||
u = 0x00^0x10^0xff;
|
||||
}
|
||||
|
||||
p += 0x84; // Add uLaw bias
|
||||
|
||||
if(p>0x7f00)
|
||||
p = 0x7f00; // Clip to 15 bits
|
||||
p >>= 3; // Shift down to 13bit
|
||||
if(p>=0x100)
|
||||
{
|
||||
p >>= 4;
|
||||
u ^= 0x40;
|
||||
if(p>=0x100)
|
||||
{
|
||||
p >>= 4;
|
||||
a += 0x40;
|
||||
}
|
||||
if(p>=0x40)
|
||||
{
|
||||
p >>= 2;
|
||||
a += 0x20;
|
||||
}
|
||||
if(p>=0x20)
|
||||
{
|
||||
p >>= 1;
|
||||
a += 0x10;
|
||||
}
|
||||
}
|
||||
if(p>=0x40)
|
||||
{
|
||||
p >>= 2;
|
||||
u ^= 0x20;
|
||||
}
|
||||
if(p>=0x20)
|
||||
{
|
||||
p >>= 1;
|
||||
u ^= 0x10;
|
||||
}
|
||||
u ^= p; // u now equal to encoded u-law value (with all bits inverted)
|
||||
// a&0x70 now holds segment value and 'p' the interval number
|
||||
a += p; // a now equal to encoded A-law value
|
||||
|
||||
return a^0x55; // A-law has alternate bits inverted for transmission
|
||||
}
|
||||
|
||||
return u;
|
||||
}
|
||||
};
|
||||
|
||||
// the class factories
|
||||
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2005-2006 Savoir-Faire Linux inc.
|
||||
* Author: Yan Morin <yan.morin@savoirfairelinux.com>
|
||||
* Author: Laurielle Lea <laurielle.lea@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __ALAW_H__
|
||||
#define __ALAW_H__
|
||||
|
||||
#include "audiocodec.h"
|
||||
|
||||
/**
|
||||
* Alaw audio codec (payload is 8)
|
||||
*/
|
||||
class Alaw : public AudioCodec {
|
||||
public:
|
||||
// payload should be 8
|
||||
Alaw (int payload=8);
|
||||
~Alaw (void);
|
||||
|
||||
int codecDecode (short *, unsigned char *, unsigned int);
|
||||
int codecEncode (unsigned char *, short *, unsigned int);
|
||||
void test () ;
|
||||
};
|
||||
|
||||
#endif // __ULAW_H__
|
@ -1,4 +1,5 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (C) 2004-2007 Savoir-Faire Linux inc.
|
||||
* Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
|
||||
* Author: Alexandre Bourget <alexandre.bourget@savoirfairelinux.com>
|
||||
@ -26,8 +27,6 @@
|
||||
#include <assert.h>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
//#include <fstream> // fstream + iostream pour fstream debugging..
|
||||
//#include <iostream> // removeable...
|
||||
#include <math.h>
|
||||
#include <dlfcn.h>
|
||||
#include <iostream>
|
||||
@ -98,17 +97,17 @@ AudioRtp::closeRtpSession () {
|
||||
// AudioRtpRTX Class //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
AudioRtpRTX::AudioRtpRTX (SIPCall *sipcall, bool sym)
|
||||
// : _fstream("/tmp/audio.dat", std::ofstream::binary)
|
||||
: _fstream("/tmp/audio.dat", std::ofstream::binary|std::ios::out|std::ios::app)
|
||||
{
|
||||
setCancel(cancelDeferred);
|
||||
time = new ost::Time();
|
||||
_ca = sipcall;
|
||||
_sym = sym;
|
||||
//std::string s = "snd.dat";
|
||||
// AudioRtpRTX should be close if we change sample rate
|
||||
|
||||
//_codecSampleRate = _ca->getAudioCodec()->getClockRate();
|
||||
|
||||
|
||||
// TODO: Change bind address according to user settings.
|
||||
// TODO: this should be the local ip not the external (router) IP
|
||||
std::string localipConfig = _ca->getLocalIp(); // _ca->getLocalIp();
|
||||
@ -142,7 +141,7 @@ AudioRtpRTX::~AudioRtpRTX () {
|
||||
}
|
||||
//_debug("terminate audiortprtx ended...\n");
|
||||
_ca = 0;
|
||||
|
||||
//fd = fopen("snd_data", "wa");
|
||||
if (!_sym) {
|
||||
delete _sessionRecv; _sessionRecv = NULL;
|
||||
delete _sessionSend; _sessionSend = NULL;
|
||||
@ -185,7 +184,6 @@ AudioRtpRTX::initAudioRtpSession (void)
|
||||
|
||||
try {
|
||||
if (_ca == 0) { return; }
|
||||
_debug("AUDIOCODEC=%i\n", _ca->getAudioCodec());
|
||||
AudioCodec* audiocodec = loadCodec(_ca->getAudioCodec());
|
||||
_codecSampleRate = audiocodec->getClockRate();
|
||||
|
||||
@ -270,6 +268,9 @@ AudioRtpRTX::loadCodec(int payload)
|
||||
case 97:
|
||||
handle_codec = dlopen(CODECS_DIR "/libcodec_ilbc.so", RTLD_LAZY);
|
||||
break;
|
||||
case 110:
|
||||
handle_codec = dlopen(CODECS_DIR "/libcodec_speex.so", RTLD_LAZY);
|
||||
break;
|
||||
}
|
||||
|
||||
if(!handle_codec){
|
||||
@ -302,7 +303,6 @@ void
|
||||
AudioRtpRTX::sendSessionFromMic(int timestamp)
|
||||
{
|
||||
AudioCodec* audiocodec = loadCodec(_ca->getAudioCodec());
|
||||
|
||||
// STEP:
|
||||
// 1. get data from mic
|
||||
// 2. convert it to int16 - good sample, good rate
|
||||
@ -327,11 +327,12 @@ try {
|
||||
|
||||
// take the lowest
|
||||
int bytesAvail = (availBytesFromMic < maxBytesToGet) ? availBytesFromMic : maxBytesToGet;
|
||||
|
||||
//printf("clock rate = %i\n", audiocodec->getClockRate());
|
||||
// Get bytes from micRingBuffer to data_from_mic
|
||||
int nbSample = audiolayer->getMic(_dataAudioLayer, bytesAvail) / sizeof(SFLDataFormat);
|
||||
int nb_sample_up = nbSample;
|
||||
int nbSamplesMax = _layerFrameSize * audiocodec->getClockRate() / 1000;
|
||||
//_fstream.write((char*) _dataAudioLayer, nbSample);
|
||||
|
||||
nbSample = reSampleData(audiocodec->getClockRate(), nb_sample_up, DOWN_SAMPLING);
|
||||
|
||||
@ -343,11 +344,12 @@ try {
|
||||
memset(toSIP + nbSample, 0, (nbSamplesMax-nbSample)*sizeof(int16));
|
||||
nbSample = nbSamplesMax;
|
||||
}
|
||||
//_debug("AR: Nb sample: %d int, [0]=%d [1]=%d [2]=%d\n", nbSample, toSIP[0], toSIP[1], toSIP[2]);
|
||||
|
||||
// debug - dump sound in a file
|
||||
//_debug("AR: Nb sample: %d int, [0]=%d [1]=%d [2]=%d\n", nbSample, toSIP[0], toSIP[1], toSIP[2]);
|
||||
// for the mono: range = 0 to RTP_FRAME2SEND * sizeof(int16)
|
||||
// codecEncode(char *dest, int16* src, size in bytes of the src)
|
||||
int compSize = audiocodec->codecEncode(_sendDataEncoded, toSIP, nbSample*sizeof(int16));
|
||||
//printf("jusqu'ici tout vas bien\n");
|
||||
|
||||
// encode divise by two
|
||||
// Send encoded audio sample over the network
|
||||
@ -393,8 +395,9 @@ try {
|
||||
|
||||
int payload = adu->getType(); // codec type
|
||||
unsigned char* data = (unsigned char*)adu->getData(); // data in char
|
||||
unsigned int size = adu->getSize(); // size in char
|
||||
unsigned int size = adu->getSize(); // size in char
|
||||
|
||||
//_fstream.write((char*) data, size);
|
||||
audiocodec = loadCodec(payload);
|
||||
// Decode data with relevant codec
|
||||
_codecSampleRate = audiocodec->getClockRate();
|
||||
@ -405,7 +408,8 @@ try {
|
||||
_debug("The packet size has been cropped\n");
|
||||
size=max;
|
||||
}
|
||||
|
||||
|
||||
//printf("size = %i\n", size);
|
||||
|
||||
if (audiocodec != NULL) {
|
||||
int expandedSize = audiocodec->codecDecode(_receiveDataDecoded, data, size);
|
||||
@ -565,6 +569,7 @@ try {
|
||||
Thread::sleep(TimerPort::getTimer());
|
||||
TimerPort::incTimer(_layerFrameSize); // 'frameSize' ms
|
||||
}
|
||||
//_fstream.close();
|
||||
//_debug("stop stream for audiortp loop\n");
|
||||
audiolayer->stopStream();
|
||||
} catch(std::exception &e) {
|
||||
|
@ -74,7 +74,8 @@ class AudioRtpRTX : public ost::Thread, public ost::TimerPort {
|
||||
float32* _floatBufferUp;
|
||||
|
||||
/** Debugging output file */
|
||||
//std::ofstream _fstream;
|
||||
std::ofstream _fstream;
|
||||
FILE* fd;
|
||||
|
||||
/** libsamplerate converter for incoming voice */
|
||||
SRC_STATE* _src_state_spkr;
|
||||
|
@ -52,11 +52,9 @@ void
|
||||
CodecDescriptor::setDefaultOrder()
|
||||
{
|
||||
_codecOrder.clear();
|
||||
//_codecOrder.push_back(PAYLOAD_CODEC_ILBC_20);
|
||||
_codecOrder.push_back(PAYLOAD_CODEC_ULAW);
|
||||
_codecOrder.push_back(PAYLOAD_CODEC_ALAW);
|
||||
_codecOrder.push_back(PAYLOAD_CODEC_GSM);
|
||||
//_codecOrder.push_back(PAYLOAD_CODEC_SPEEX_8000);
|
||||
}
|
||||
|
||||
std::string&
|
||||
@ -70,19 +68,15 @@ CodecDescriptor::getCodecName(CodecType payload)
|
||||
}
|
||||
|
||||
bool
|
||||
CodecDescriptor::isSupported(CodecType payload)
|
||||
CodecDescriptor::isActive(CodecType payload)
|
||||
{
|
||||
CodecMap::iterator iter = _codecMap.begin();
|
||||
while(iter!=_codecMap.end()) {
|
||||
if (iter->first == payload) {
|
||||
// codec is already in the map --> nothing to do
|
||||
_debug("Codec with payload %i already in the map\n", payload);
|
||||
//break;
|
||||
return true;
|
||||
}
|
||||
iter++;
|
||||
int i;
|
||||
for(i=0 ; i < _codecOrder.size() ; i++)
|
||||
{
|
||||
if(_codecOrder[i] == payload)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
@ -121,7 +115,7 @@ CodecDescriptor::getBitRate(CodecType payload)
|
||||
return 15.2;
|
||||
|
||||
}
|
||||
return -1;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
double
|
||||
@ -137,7 +131,7 @@ CodecDescriptor::getBandwidthPerCall(CodecType payload)
|
||||
case PAYLOAD_CODEC_ILBC_20:
|
||||
return 30.8;
|
||||
}
|
||||
return -1;
|
||||
return 0.0;
|
||||
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,9 @@ typedef enum {
|
||||
// 97 speex/8000
|
||||
// http://support.xten.com/viewtopic.php?p=8684&sid=3367a83d01fdcad16c7459a79859b08e
|
||||
// 100 speex/16000
|
||||
PAYLOAD_CODEC_SPEEX = 110
|
||||
PAYLOAD_CODEC_SPEEX_8000 = 110,
|
||||
PAYLOAD_CODEC_SPEEX_16000 = 111,
|
||||
PAYLOAD_CODEC_SPEEX_32000 = 112
|
||||
} CodecType;
|
||||
|
||||
#include "audiocodec.h"
|
||||
@ -89,7 +91,7 @@ public:
|
||||
* @return true if the codec specified is supported
|
||||
* false otherwise
|
||||
*/
|
||||
bool isSupported(CodecType payload);
|
||||
bool isActive(CodecType payload);
|
||||
|
||||
/**
|
||||
* Remove the codec with payload payload from the list
|
||||
|
@ -1,3 +1,25 @@
|
||||
/**
|
||||
* Copyright (C) 2004-2005 Savoir-Faire Linux inc.
|
||||
* Author: Yan Morin <yan.morin@savoirfairelinux.com>
|
||||
* Author: Laurielle Lea <laurielle.lea@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
**/
|
||||
|
||||
|
||||
|
||||
#include "common.h"
|
||||
#include "audiocodec.h"
|
||||
|
||||
@ -11,7 +33,6 @@ public:
|
||||
_channel = 1;
|
||||
}
|
||||
|
||||
|
||||
virtual int codecDecode (short *dst, unsigned char *src, unsigned int size) {
|
||||
int16* end = dst+size;
|
||||
while(dst<end)
|
||||
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2005-2006 Savoir-Faire Linux inc.
|
||||
* Author: Yan Morin <yan.morin@savoirfairelinux.com>
|
||||
* Author: Laurielle Lea <laurielle.lea@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __ULAW_H__
|
||||
#define __ULAW_H__
|
||||
|
||||
#include "audiocodec.h"
|
||||
|
||||
/**
|
||||
* Ulaw audio codec (payload = 0)
|
||||
*/
|
||||
class Ulaw : public AudioCodec {
|
||||
public:
|
||||
// payload should be 0
|
||||
Ulaw(int payload=0);
|
||||
~Ulaw(void);
|
||||
|
||||
int codecDecode(short *, unsigned char *, unsigned int);
|
||||
int codecEncode(unsigned char *, short *, unsigned int);
|
||||
void test();
|
||||
};
|
||||
|
||||
#endif // __ULAW_H__
|
@ -35,16 +35,6 @@ IAXCall::setFormat(int format)
|
||||
{
|
||||
_format = format;
|
||||
switch(format) {
|
||||
/*case AST_FORMAT_ULAW:
|
||||
setAudioCodec(_codecMap.getCodec(PAYLOAD_CODEC_ULAW)); break;
|
||||
case AST_FORMAT_GSM:
|
||||
setAudioCodec(_codecMap.getCodec(PAYLOAD_CODEC_GSM)); break;
|
||||
case AST_FORMAT_ALAW:
|
||||
setAudioCodec(_codecMap.getCodec(PAYLOAD_CODEC_ALAW)); break;
|
||||
case AST_FORMAT_ILBC:
|
||||
setAudioCodec(_codecMap.getCodec(PAYLOAD_CODEC_ILBC_20)); break;
|
||||
case AST_FORMAT_SPEEX:
|
||||
setAudioCodec(_codecMap.getCodec(PAYLOAD_CODEC_SPEEX)); break;*/
|
||||
case AST_FORMAT_ULAW:
|
||||
setAudioCodec(PAYLOAD_CODEC_ULAW); break;
|
||||
case AST_FORMAT_GSM:
|
||||
@ -54,7 +44,7 @@ IAXCall::setFormat(int format)
|
||||
case AST_FORMAT_ILBC:
|
||||
setAudioCodec(PAYLOAD_CODEC_ILBC_20); break;
|
||||
case AST_FORMAT_SPEEX:
|
||||
setAudioCodec(PAYLOAD_CODEC_SPEEX); break;
|
||||
setAudioCodec(PAYLOAD_CODEC_SPEEX_8000); break;
|
||||
default:
|
||||
setAudioCodec((CodecType) -1);
|
||||
break;
|
||||
@ -65,12 +55,12 @@ IAXCall::setFormat(int format)
|
||||
int
|
||||
IAXCall::getSupportedFormat()
|
||||
{
|
||||
CodecMap map = getCodecMap().getCodecMap();
|
||||
int format = 0;
|
||||
CodecOrder map = getCodecMap().getActiveCodecs();
|
||||
int format = 0;
|
||||
int iter;
|
||||
|
||||
CodecMap::iterator iter = map.begin();
|
||||
while(iter != map.end()) {
|
||||
switch(iter->first) {
|
||||
for(iter=0 ; iter < map.size() ; iter++){
|
||||
switch(map[iter]) {
|
||||
case PAYLOAD_CODEC_ULAW:
|
||||
format |= AST_FORMAT_ULAW; break;
|
||||
case PAYLOAD_CODEC_GSM:
|
||||
@ -79,12 +69,12 @@ IAXCall::getSupportedFormat()
|
||||
format |= AST_FORMAT_ALAW; break;
|
||||
case PAYLOAD_CODEC_ILBC_20:
|
||||
format |= AST_FORMAT_ILBC; break;
|
||||
case PAYLOAD_CODEC_SPEEX:
|
||||
format |= AST_FORMAT_SPEEX; break;
|
||||
case PAYLOAD_CODEC_SPEEX_8000:
|
||||
format |= AST_FORMAT_SPEEX;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
return format;
|
||||
|
||||
@ -93,30 +83,30 @@ IAXCall::getSupportedFormat()
|
||||
int
|
||||
IAXCall::getFirstMatchingFormat(int needles)
|
||||
{
|
||||
CodecMap map = getCodecMap().getCodecMap();
|
||||
int format = 0;
|
||||
CodecOrder map = getCodecMap().getActiveCodecs();
|
||||
int format = 0;
|
||||
int iter;
|
||||
|
||||
CodecMap::iterator iter = map.begin();
|
||||
while(iter != map.end()) {
|
||||
switch(iter->first) {
|
||||
for(iter=0 ; iter < map.size() ; iter++) {
|
||||
switch(map[iter]) {
|
||||
case PAYLOAD_CODEC_ULAW:
|
||||
format = AST_FORMAT_ULAW; break;
|
||||
case PAYLOAD_CODEC_GSM:
|
||||
format = AST_FORMAT_GSM; break;
|
||||
case PAYLOAD_CODEC_ALAW:
|
||||
format = AST_FORMAT_ALAW; break;
|
||||
format = AST_FORMAT_ALAW;
|
||||
break;
|
||||
case PAYLOAD_CODEC_ILBC_20:
|
||||
format = AST_FORMAT_ILBC; break;
|
||||
case PAYLOAD_CODEC_SPEEX:
|
||||
case PAYLOAD_CODEC_SPEEX_8000:
|
||||
format = AST_FORMAT_SPEEX; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Return the first that matches
|
||||
if (format & needles)
|
||||
return format;
|
||||
iter++;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -247,6 +247,9 @@ IAXVoIPLink::loadCodec(int payload)
|
||||
case 97:
|
||||
handle_codec = dlopen(CODECS_DIR "/libcodec_ilbc.so", RTLD_LAZY);
|
||||
break;
|
||||
case 110:
|
||||
handle_codec = dlopen(CODECS_DIR "/libcodec_speex.so", RTLD_LAZY);
|
||||
break;
|
||||
}
|
||||
if(!handle_codec){
|
||||
cerr<<"cannot load library: "<< dlerror() <<'\n';
|
||||
@ -512,6 +515,8 @@ Call*
|
||||
IAXVoIPLink::newOutgoingCall(const CallID& id, const std::string& toUrl)
|
||||
{
|
||||
IAXCall* call = new IAXCall(id, Call::Outgoing);
|
||||
call->setCodecMap(Manager::instance().getCodecDescriptorMap());
|
||||
|
||||
|
||||
if (call) {
|
||||
call->setPeerNumber(toUrl);
|
||||
@ -954,6 +959,7 @@ IAXVoIPLink::iaxHandlePrecallEvent(iax_event* event)
|
||||
call->setCodecMap(Manager::instance().getCodecDescriptorMap());
|
||||
call->setConnectionState(Call::Progressing);
|
||||
|
||||
|
||||
if (event->ies.calling_number)
|
||||
call->setPeerNumber(std::string(event->ies.calling_number));
|
||||
if (event->ies.calling_name)
|
||||
@ -1005,3 +1011,12 @@ IAXVoIPLink::iaxHandlePrecallEvent(iax_event* event)
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
IAXVoIPLink::iaxCodecMapToFormat(IAXCall* call)
|
||||
{
|
||||
CodecOrder map = call->getCodecMap().getActiveCodecs();
|
||||
printf("taytciatcia = %i\n", map.size());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -353,17 +353,18 @@ SIPCall::sdp_complete_message(sdp_message_t * remote_sdp, osip_message_t * msg)
|
||||
remote_med_m_payloads = &(remote_med->m_payloads);
|
||||
#endif
|
||||
|
||||
while (!osip_list_eol(remote_med_m_payloads, iPayload) && iPayload < 2) {
|
||||
//while (!osip_list_eol(remote_med_m_payloads, iPayload) && iPayload < 2) {
|
||||
while (!osip_list_eol(remote_med_m_payloads, iPayload)) {
|
||||
tmp = (char *)osip_list_get(remote_med_m_payloads, iPayload);
|
||||
if (tmp!=NULL) {
|
||||
int payload = atoi(tmp);
|
||||
_debug("remote payload = %s\n", tmp);
|
||||
CodecType audiocodec = (CodecType)payload;
|
||||
//if (audiocodec != NULL && audiocodec->isActive()) {
|
||||
if (audiocodec != (CodecType)-1 && _codecMap.isSupported(audiocodec)) {
|
||||
if (audiocodec != (CodecType)-1 && _codecMap.isActive(audiocodec)) {
|
||||
_debug("PAYLOAD = %i", payload);
|
||||
listCodec << payload << " ";
|
||||
//listRtpMap << "a=rtpmap:" << payload << " " << audiocodec->getCodecName() << "/" << audiocodec->getClockRate();
|
||||
listRtpMap << "a=rtpmap:" << payload << " " << _codecMap.getCodecName(audiocodec) << "/" << 8000;
|
||||
listRtpMap << "a=rtpmap:" << payload << " " << _codecMap.getCodecName(audiocodec) << "/" << _codecMap.getSampleRate(audiocodec);
|
||||
// TODO: manage a way to get the channel infos
|
||||
/*if ( audiocodec->getChannel() != 1) {
|
||||
listRtpMap << "/" << audiocodec->getChannel();
|
||||
@ -586,7 +587,7 @@ SIPCall::setAudioCodecFromSDP(sdp_media_t* remote_med, int tid)
|
||||
if (tmp != NULL ) {
|
||||
int payload = atoi(tmp);
|
||||
// stop if we find a correct codec
|
||||
if (_codecMap.isSupported((CodecType)payload)){
|
||||
if (_codecMap.isActive((CodecType)payload)){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -943,32 +943,32 @@ SIPVoIPLink::SIPStartCall(SIPCall* call, const std::string& subject)
|
||||
|
||||
std::ostringstream media_audio;
|
||||
std::ostringstream rtpmap_attr;
|
||||
int payload;
|
||||
CodecType payload;
|
||||
int nbChannel;
|
||||
int iter;
|
||||
|
||||
// Set rtpmap according to the supported codec order
|
||||
CodecMap map = call->getCodecMap().getCodecMap();
|
||||
//CodecMap map = Manager::instance().getCodecDescriptorMap();
|
||||
CodecMap::iterator iter = map.begin();
|
||||
//CodecMap map = call->getCodecMap().getCodecMap();
|
||||
CodecOrder map = call->getCodecMap().getActiveCodecs();
|
||||
|
||||
for(iter=0 ; iter < map.size() ; iter++){
|
||||
if(map[iter] != -1){
|
||||
payload = map[iter];
|
||||
// add each payload in the list of payload
|
||||
media_audio << payload << " ";
|
||||
|
||||
while(iter != map.end()) {
|
||||
//if (iter->second!=0 && iter->second->isActive()) {
|
||||
if(iter->first != -1){
|
||||
payload = iter->first;
|
||||
// add each payload in the list of payload
|
||||
media_audio << payload << " ";
|
||||
rtpmap_attr << "a=rtpmap:" << payload << " " <<
|
||||
call->getCodecMap().getCodecName(payload) << "/" << call->getCodecMap().getSampleRate(payload);
|
||||
|
||||
rtpmap_attr << "a=rtpmap:" << payload << " " <<
|
||||
iter->second.data() << "/" << 8000; //iter->second->getClockRate();
|
||||
|
||||
/*nbChannel = iter->second->getChannel();
|
||||
if (nbChannel!=1) {
|
||||
rtpmap_attr << "/" << nbChannel;
|
||||
}*/
|
||||
rtpmap_attr << "\r\n";
|
||||
}
|
||||
//TODO add channel infos
|
||||
/*nbChannel = iter->second->getChannel();
|
||||
if (nbChannel!=1) {
|
||||
rtpmap_attr << "/" << nbChannel;
|
||||
}*/
|
||||
rtpmap_attr << "\r\n";
|
||||
}
|
||||
// go to next codec
|
||||
iter++;
|
||||
//*iter++;
|
||||
}
|
||||
|
||||
// http://www.antisip.com/documentation/eXosip2/group__howto1__initialize.html
|
||||
|
Reference in New Issue
Block a user