Commit 286f49c3 authored by Emmanuel Milou's avatar Emmanuel Milou
Browse files

Add speex support - bad audio though

!!!!!!!!!!!  Must have libspeex1 and libspeex1-dev installed
parent d792b6b0
......@@ -18,78 +18,99 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "CodecSpeex.h"
CodecSpeex::CodecSpeex(int payload)
: AudioCodec(payload, "speex")
{
_description = "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;
}
speex_bits_init(&_speex_dec_bits);
_speex_dec_state = speex_decoder_init(_speexModePtr);
speex_bits_init(&_speex_enc_bits);
_speex_enc_state = speex_encoder_init(_speexModePtr);
speex_decoder_ctl(_speex_dec_state, SPEEX_GET_FRAME_SIZE, &_speex_frame_size);
}
CodecSpeex::~CodecSpeex()
{
terminateSpeex();
}
void
CodecSpeex::terminateSpeex() {
speex_bits_destroy(&_speex_dec_bits);
speex_decoder_destroy(_speex_dec_state);
_speex_dec_state = 0;
speex_bits_destroy(&_speex_enc_bits);
speex_encoder_destroy(_speex_enc_state);
_speex_enc_state = 0;
}
int
CodecSpeex::codecDecode (short *dst, unsigned char *src, unsigned int size)
{
#include "audiocodec.h"
#include <speex/speex.h>
class CodecSpeex : public AudioCodec{
public:
CodecSpeex(int payload=0)
: AudioCodec(payload, "speex")
{
_clockRate = 8000;
_channel = 1;
initSpeex();
}
int getFrameSize(){ return _speex_frame_size; }
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_dec_bits);
_speex_dec_state = speex_decoder_init(_speexModePtr);
speex_bits_init(&_speex_enc_bits);
_speex_enc_state = speex_encoder_init(_speexModePtr);
speex_decoder_ctl(_speex_dec_state, SPEEX_GET_FRAME_SIZE, &_speex_frame_size);
}
~CodecSpeex()
{
terminateSpeex();
}
void terminateSpeex() {
speex_bits_destroy(&_speex_dec_bits);
speex_decoder_destroy(_speex_dec_state);
_speex_dec_state = 0;
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
......
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)
/*
*
* 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) {
......
......@@ -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&
......@@ -121,7 +119,7 @@ CodecDescriptor::getBitRate(CodecType payload)
return 15.2;
}
return -1;
return 0.0;
}
double
......@@ -137,7 +135,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"
......
......@@ -44,7 +44,7 @@ IAXCall::setFormat(int format)
case AST_FORMAT_ILBC:
setAudioCodec(_codecMap.getCodec(PAYLOAD_CODEC_ILBC_20)); break;
case AST_FORMAT_SPEEX:
setAudioCodec(_codecMap.getCodec(PAYLOAD_CODEC_SPEEX)); break;*/
setAudioCodec(_codecMap.getCodec(PAYLOAD_CODEC_SPEEX_8000)); break;*/
case AST_FORMAT_ULAW:
setAudioCodec(PAYLOAD_CODEC_ULAW); break;
case AST_FORMAT_GSM:
......@@ -54,7 +54,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;
......@@ -79,7 +79,7 @@ IAXCall::getSupportedFormat()
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;
......@@ -107,7 +107,7 @@ IAXCall::getFirstMatchingFormat(int needles)
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;
......
......@@ -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';
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment