Skip to content
Snippets Groups Projects
Commit c8932198 authored by Guillaume Carmel-Archambault's avatar Guillaume Carmel-Archambault
Browse files
parents 85385193 ed424321
Branches
Tags
No related merge requests found
Showing
with 840 additions and 171 deletions
...@@ -35,6 +35,8 @@ AC_CONFIG_FILES([libs/Makefile \ ...@@ -35,6 +35,8 @@ AC_CONFIG_FILES([libs/Makefile \
AC_CONFIG_FILES([src/Makefile \ AC_CONFIG_FILES([src/Makefile \
src/sflphone \ src/sflphone \
src/audio/Makefile \ src/audio/Makefile \
src/audio/codecs/Makefile
src/audio/codecs/ilbc/Makefile \
src/config/Makefile \ src/config/Makefile \
src/dbus/Makefile \ src/dbus/Makefile \
src/zeroconf/Makefile]) src/zeroconf/Makefile])
......
/*
* Copyright (C) 2005 Savoir-Faire Linux inc.
* Author: Yan Morin <yan.morin@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 __CODEC_SPEEX_H_
#define __CODEC_SPEEX_H_
#include "audiocodec.h"
#include <speex/speex.h>
class CodecSpeex : public AudioCodec
{
public:
CodecSpeex(int payload);
~CodecSpeex();
int codecDecode(short *, unsigned char *, unsigned int);
int codecEncode(unsigned char *, short *, unsigned int);
// only for speex
int getFrameSize() { return _speex_frame_size; }
private:
unsigned int _clockRate;
unsigned int _channel;
void initSpeex();
void terminateSpeex();
const SpeexMode* _speexModePtr;
SpeexBits _speex_dec_bits;
SpeexBits _speex_enc_bits;
void *_speex_dec_state;
void *_speex_enc_state;
int _speex_frame_size;
};
#endif // __CODEC_SPEEX_H_
sflcodecdir = $(libdir)/sflphone/codecs/ sflcodecdir = $(libdir)/sflphone/codecs
noinst_LTLIBRARIES = libaudio.la noinst_LTLIBRARIES = libaudio.la
noinst_PROGRAMS = libcodec_ulaw.so libcodec_alaw.so libcodec_gsm.so libcodec_speex.so
libcodec_ulaw_so_SOURCES = ulaw.cpp SUBDIRS = codecs
libcodec_ulaw_so_CFLAGS = -fPIC -g -Wall
libcodec_ulaw_so_LDFLAGS = -shared -lc
libcodec_alaw_so_SOURCES = alaw.cpp
libcodec_alaw_so_CFLAGS = -fPIC -g -Wall
libcodec_alaw_so_LDFLAGS = -shared -lc
libcodec_gsm_so_SOURCES = gsmcodec.cpp
libcodec_gsm_so_CFLAGS = -fPIC -g -Wall
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
SPEEX_FLAG=-DHAVE_SPEEX
SPEEX_LIB=-lspeex
else
SPEEX_SOURCES_CPP=
SPEEX_FLAG=
SPEEX_LIB=
endif
#SUBDIRS = ilbc
libaudio_la_SOURCES = audiofile.cpp tonelist.cpp \ libaudio_la_SOURCES = audiofile.cpp tonelist.cpp \
audiortp.cpp dtmf.cpp tone.cpp audiolayer.cpp audiodevice.cpp dtmfgenerator.cpp \ audiortp.cpp dtmf.cpp tone.cpp audiolayer.cpp audiodevice.cpp dtmfgenerator.cpp \
...@@ -41,30 +14,7 @@ AM_CXXFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/libs $(libccext2_CFLAGS) $ ...@@ -41,30 +14,7 @@ AM_CXXFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/libs $(libccext2_CFLAGS) $
libaudio_la_CPPFLAGS = $(SPEEX_FLAG) libaudio_la_CPPFLAGS = $(SPEEX_FLAG)
noinst_HEADERS = audioloop.h common.h ringbuffer.h audiofile.h \ noinst_HEADERS = audioloop.h common.h ringbuffer.h audiofile.h \
tonelist.h audiortp.h audiocodec.h audiolayer.h audiodevice.h \ tonelist.h audiortp.h audiolayer.h audiodevice.h \
dtmfgenerator.h tonegenerator.h \ dtmfgenerator.h tonegenerator.h \
codecDescriptor.h dtmf.h tone.h \ codecDescriptor.h dtmf.h tone.h
CodecSpeex.h
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)
$(INSTALL_PROGRAM) libcodec_ulaw.so $(sflcodecdir)
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
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)
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#define __AUDIOFILE_H__ #define __AUDIOFILE_H__
#include "audioloop.h" #include "audioloop.h"
#include "audiocodec.h" #include "codecs/audiocodec.h"
/** /**
@author Yan Morin <yan.morin@savoirfairelinux.com> @author Yan Morin <yan.morin@savoirfairelinux.com>
......
...@@ -97,13 +97,12 @@ AudioRtp::closeRtpSession () { ...@@ -97,13 +97,12 @@ AudioRtp::closeRtpSession () {
// AudioRtpRTX Class // // AudioRtpRTX Class //
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
AudioRtpRTX::AudioRtpRTX (SIPCall *sipcall, bool sym) AudioRtpRTX::AudioRtpRTX (SIPCall *sipcall, bool sym)
: _fstream("/tmp/audio.dat", std::ofstream::binary|std::ios::out|std::ios::app) : _fstream("/tmp/audio.gsm", std::ofstream::binary|std::ios::out|std::ios::app)
{ {
setCancel(cancelDeferred); setCancel(cancelDeferred);
time = new ost::Time(); time = new ost::Time();
_ca = sipcall; _ca = sipcall;
_sym = sym; _sym = sym;
//std::string s = "snd.dat";
// AudioRtpRTX should be close if we change sample rate // AudioRtpRTX should be close if we change sample rate
//_codecSampleRate = _ca->getAudioCodec()->getClockRate(); //_codecSampleRate = _ca->getAudioCodec()->getClockRate();
...@@ -141,7 +140,6 @@ AudioRtpRTX::~AudioRtpRTX () { ...@@ -141,7 +140,6 @@ AudioRtpRTX::~AudioRtpRTX () {
} }
//_debug("terminate audiortprtx ended...\n"); //_debug("terminate audiortprtx ended...\n");
_ca = 0; _ca = 0;
//fd = fopen("snd_data", "wa");
if (!_sym) { if (!_sym) {
delete _sessionRecv; _sessionRecv = NULL; delete _sessionRecv; _sessionRecv = NULL;
delete _sessionSend; _sessionSend = NULL; delete _sessionSend; _sessionSend = NULL;
...@@ -184,8 +182,7 @@ AudioRtpRTX::initAudioRtpSession (void) ...@@ -184,8 +182,7 @@ AudioRtpRTX::initAudioRtpSession (void)
try { try {
if (_ca == 0) { return; } if (_ca == 0) { return; }
AudioCodec* audiocodec = loadCodec(_ca->getAudioCodec()); _codecSampleRate = _audiocodec->getClockRate();
_codecSampleRate = audiocodec->getClockRate();
_debug("Init audio RTP session\n"); _debug("Init audio RTP session\n");
ost::InetHostAddress remote_ip(_ca->getRemoteIp().c_str()); ost::InetHostAddress remote_ip(_ca->getRemoteIp().c_str());
...@@ -217,12 +214,12 @@ AudioRtpRTX::initAudioRtpSession (void) ...@@ -217,12 +214,12 @@ AudioRtpRTX::initAudioRtpSession (void)
} }
bool payloadIsSet = false; bool payloadIsSet = false;
if (audiocodec) { if (_audiocodec) {
if (audiocodec->hasDynamicPayload()) { if (_audiocodec->hasDynamicPayload()) {
payloadIsSet = _sessionRecv->setPayloadFormat(ost::DynamicPayloadFormat((ost::PayloadType) audiocodec->getPayload(), audiocodec->getClockRate())); payloadIsSet = _sessionRecv->setPayloadFormat(ost::DynamicPayloadFormat((ost::PayloadType) _audiocodec->getPayload(), _audiocodec->getClockRate()));
} else { } else {
payloadIsSet= _sessionRecv->setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) audiocodec->getPayload())); payloadIsSet= _sessionRecv->setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) _audiocodec->getPayload()));
payloadIsSet = _sessionSend->setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) audiocodec->getPayload())); payloadIsSet = _sessionSend->setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) _audiocodec->getPayload()));
} }
} }
_sessionSend->setMark(true); _sessionSend->setMark(true);
...@@ -235,22 +232,21 @@ AudioRtpRTX::initAudioRtpSession (void) ...@@ -235,22 +232,21 @@ AudioRtpRTX::initAudioRtpSession (void)
} }
bool payloadIsSet = false; bool payloadIsSet = false;
if (audiocodec) { if (_audiocodec) {
if (audiocodec->hasDynamicPayload()) { if (_audiocodec->hasDynamicPayload()) {
payloadIsSet = _session->setPayloadFormat(ost::DynamicPayloadFormat((ost::PayloadType) audiocodec->getPayload(), audiocodec->getClockRate())); payloadIsSet = _session->setPayloadFormat(ost::DynamicPayloadFormat((ost::PayloadType) _audiocodec->getPayload(), _audiocodec->getClockRate()));
} else { } else {
payloadIsSet = _session->setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) audiocodec->getPayload())); payloadIsSet = _session->setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) _audiocodec->getPayload()));
} }
} }
} }
unloadCodec(audiocodec);
} catch(...) { } catch(...) {
_debugException("! ARTP Failure: initialisation failed"); _debugException("! ARTP Failure: initialisation failed");
throw; throw;
} }
} }
AudioCodec* void
AudioRtpRTX::loadCodec(int payload) AudioRtpRTX::loadCodec(int payload)
{ {
using std::cerr; using std::cerr;
...@@ -282,11 +278,12 @@ AudioRtpRTX::loadCodec(int payload) ...@@ -282,11 +278,12 @@ AudioRtpRTX::loadCodec(int payload)
if(dlsym_error){ if(dlsym_error){
cerr << "Cannot load symbol create: " << dlsym_error << '\n'; cerr << "Cannot load symbol create: " << dlsym_error << '\n';
} }
return create_codec();
_audiocodec = create_codec();
} }
void void
AudioRtpRTX::unloadCodec(AudioCodec* audiocodec) AudioRtpRTX::unloadCodec()
{ {
using std::cerr; using std::cerr;
destroy_t* destroy_codec = (destroy_t*)dlsym(handle_codec, "destroy"); destroy_t* destroy_codec = (destroy_t*)dlsym(handle_codec, "destroy");
...@@ -294,7 +291,7 @@ AudioRtpRTX::unloadCodec(AudioCodec* audiocodec) ...@@ -294,7 +291,7 @@ AudioRtpRTX::unloadCodec(AudioCodec* audiocodec)
if(dlsym_error){ if(dlsym_error){
cerr << "Cannot load symbol destroy" << dlsym_error << '\n'; cerr << "Cannot load symbol destroy" << dlsym_error << '\n';
} }
destroy_codec(audiocodec); destroy_codec(_audiocodec);
dlclose(handle_codec); dlclose(handle_codec);
} }
...@@ -302,7 +299,6 @@ AudioRtpRTX::unloadCodec(AudioCodec* audiocodec) ...@@ -302,7 +299,6 @@ AudioRtpRTX::unloadCodec(AudioCodec* audiocodec)
void void
AudioRtpRTX::sendSessionFromMic(int timestamp) AudioRtpRTX::sendSessionFromMic(int timestamp)
{ {
AudioCodec* audiocodec = loadCodec(_ca->getAudioCodec());
// STEP: // STEP:
// 1. get data from mic // 1. get data from mic
// 2. convert it to int16 - good sample, good rate // 2. convert it to int16 - good sample, good rate
...@@ -316,25 +312,21 @@ try { ...@@ -316,25 +312,21 @@ try {
AudioLayer* audiolayer = Manager::instance().getAudioDriver(); AudioLayer* audiolayer = Manager::instance().getAudioDriver();
if (!audiolayer) { _debug(" !ARTP: No audiolayer available for mic\n"); return; } if (!audiolayer) { _debug(" !ARTP: No audiolayer available for mic\n"); return; }
//AudioCodec* audiocodec = _ca->getAudioCodec(); if (!_audiocodec) { _debug(" !ARTP: No audiocodec available for mic\n"); return; }
if (!audiocodec) { _debug(" !ARTP: No audiocodec available for mic\n"); return; }
// we have to get 20ms of data from the mic *20/1000 = /50 // we have to get 20ms of data from the mic *20/1000 = /50
int maxBytesToGet = _layerSampleRate * _layerFrameSize * sizeof(SFLDataFormat) / 1000; int maxBytesToGet = _layerSampleRate * _layerFrameSize * sizeof(SFLDataFormat) / 1000;
// available bytes inside ringbuffer // available bytes inside ringbuffer
int availBytesFromMic = audiolayer->canGetMic(); int availBytesFromMic = audiolayer->canGetMic();
// take the lowest // take the lowest
int bytesAvail = (availBytesFromMic < maxBytesToGet) ? availBytesFromMic : maxBytesToGet; int bytesAvail = (availBytesFromMic < maxBytesToGet) ? availBytesFromMic : maxBytesToGet;
//printf("clock rate = %i\n", audiocodec->getClockRate());
// Get bytes from micRingBuffer to data_from_mic // Get bytes from micRingBuffer to data_from_mic
int nbSample = audiolayer->getMic(_dataAudioLayer, bytesAvail) / sizeof(SFLDataFormat); int nbSample = audiolayer->getMic(_dataAudioLayer, bytesAvail) / sizeof(SFLDataFormat);
int nb_sample_up = nbSample; int nb_sample_up = nbSample;
int nbSamplesMax = _layerFrameSize * audiocodec->getClockRate() / 1000; int nbSamplesMax = _layerFrameSize * _audiocodec->getClockRate() / 1000;
//_fstream.write((char*) _dataAudioLayer, nbSample);
nbSample = reSampleData(audiocodec->getClockRate(), nb_sample_up, DOWN_SAMPLING); nbSample = reSampleData(_audiocodec->getClockRate(), nb_sample_up, DOWN_SAMPLING);
toSIP = _intBufferDown; toSIP = _intBufferDown;
...@@ -348,7 +340,7 @@ try { ...@@ -348,7 +340,7 @@ try {
//_debug("AR: Nb sample: %d int, [0]=%d [1]=%d [2]=%d\n", nbSample, toSIP[0], toSIP[1], toSIP[2]); //_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) // for the mono: range = 0 to RTP_FRAME2SEND * sizeof(int16)
// codecEncode(char *dest, int16* src, size in bytes of the src) // codecEncode(char *dest, int16* src, size in bytes of the src)
int compSize = audiocodec->codecEncode(_sendDataEncoded, toSIP, nbSample*sizeof(int16)); int compSize = _audiocodec->codecEncode(_sendDataEncoded, toSIP, nbSample*sizeof(int16));
//printf("jusqu'ici tout vas bien\n"); //printf("jusqu'ici tout vas bien\n");
// encode divise by two // encode divise by two
...@@ -364,7 +356,6 @@ try { ...@@ -364,7 +356,6 @@ try {
_debugException("! ARTP: sending failed"); _debugException("! ARTP: sending failed");
throw; throw;
} }
unloadCodec(audiocodec);
} }
...@@ -373,7 +364,6 @@ void ...@@ -373,7 +364,6 @@ void
AudioRtpRTX::receiveSessionForSpkr (int& countTime) AudioRtpRTX::receiveSessionForSpkr (int& countTime)
{ {
AudioCodec* audiocodec;
if (_ca == 0) { return; } if (_ca == 0) { return; }
try { try {
...@@ -397,11 +387,10 @@ try { ...@@ -397,11 +387,10 @@ try {
unsigned char* data = (unsigned char*)adu->getData(); // data in char 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); //_fstream.write((char*) data, size);
audiocodec = loadCodec(payload);
// Decode data with relevant codec // Decode data with relevant codec
_codecSampleRate = audiocodec->getClockRate(); int max = (int)(_codecSampleRate * _layerFrameSize / 1000);
int max = (int)(_codecSampleRate * _layerFrameSize);
if ( size > max ) { if ( size > max ) {
_debug("We have received from RTP a packet larger than expected: %s VS %s\n", size, max); _debug("We have received from RTP a packet larger than expected: %s VS %s\n", size, max);
...@@ -411,8 +400,11 @@ try { ...@@ -411,8 +400,11 @@ try {
//printf("size = %i\n", size); //printf("size = %i\n", size);
if (audiocodec != NULL) { if (_audiocodec != NULL) {
int expandedSize = audiocodec->codecDecode(_receiveDataDecoded, data, size);
int expandedSize = _audiocodec->codecDecode(_receiveDataDecoded, data, size);
// printf("%i\n", expandedSize);
//_fstream.write((char*) _receiveDataDecoded, );
//buffer _receiveDataDecoded ----> short int or int16, coded on 2 bytes //buffer _receiveDataDecoded ----> short int or int16, coded on 2 bytes
int nbInt16 = expandedSize / sizeof(int16); int nbInt16 = expandedSize / sizeof(int16);
//nbInt16 represents the number of samples we just decoded //nbInt16 represents the number of samples we just decoded
...@@ -455,7 +447,6 @@ try { ...@@ -455,7 +447,6 @@ try {
throw; throw;
} }
unloadCodec(audiocodec);
} }
...@@ -527,6 +518,7 @@ AudioRtpRTX::run () { ...@@ -527,6 +518,7 @@ AudioRtpRTX::run () {
//mic, we receive from soundcard in stereo, and we send encoded //mic, we receive from soundcard in stereo, and we send encoded
//encoding before sending //encoding before sending
AudioLayer *audiolayer = Manager::instance().getAudioDriver(); AudioLayer *audiolayer = Manager::instance().getAudioDriver();
loadCodec(_ca->getAudioCodec());
_layerFrameSize = audiolayer->getFrameSize(); // en ms _layerFrameSize = audiolayer->getFrameSize(); // en ms
_layerSampleRate = audiolayer->getSampleRate(); _layerSampleRate = audiolayer->getSampleRate();
...@@ -569,7 +561,8 @@ try { ...@@ -569,7 +561,8 @@ try {
Thread::sleep(TimerPort::getTimer()); Thread::sleep(TimerPort::getTimer());
TimerPort::incTimer(_layerFrameSize); // 'frameSize' ms TimerPort::incTimer(_layerFrameSize); // 'frameSize' ms
} }
//_fstream.close(); _fstream.close();
unloadCodec();
//_debug("stop stream for audiortp loop\n"); //_debug("stop stream for audiortp loop\n");
audiolayer->stopStream(); audiolayer->stopStream();
} catch(std::exception &e) { } catch(std::exception &e) {
......
...@@ -124,18 +124,21 @@ class AudioRtpRTX : public ost::Thread, public ost::TimerPort { ...@@ -124,18 +124,21 @@ class AudioRtpRTX : public ost::Thread, public ost::TimerPort {
/** Pointer on function to handle codecs **/ /** Pointer on function to handle codecs **/
void* handle_codec; void* handle_codec;
AudioCodec* _audiocodec;
/** /**
* Load dynamically a codec (.so library) * Load dynamically a codec (.so library)
* @param payload The payload of the codec you want to load * @param payload The payload of the codec you want to load
* @return AudioCodec* A pointer on a audio codec object * @return AudioCodec* A pointer on a audio codec object
*/ */
AudioCodec* loadCodec(int payload); void loadCodec(int payload);
/** /**
* Destroy and close dynamically a codec (.so library) * Destroy and close dynamically a codec (.so library)
* @param audiocodec The audio codec you want to unload * @param audiocodec The audio codec you want to unload
*/ */
void unloadCodec(AudioCodec* audiocodec); void unloadCodec(void);
}; };
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
......
...@@ -22,11 +22,7 @@ ...@@ -22,11 +22,7 @@
#include <iostream> #include <iostream>
#include <cstdlib> #include <cstdlib>
#include "audiocodec.h"
#include "codecDescriptor.h" #include "codecDescriptor.h"
/*#ifdef HAVE_SPEEX
#include "CodecSpeex.h"
#endif*/
CodecDescriptor::CodecDescriptor() CodecDescriptor::CodecDescriptor()
{ {
...@@ -112,7 +108,7 @@ CodecDescriptor::getBitRate(CodecType payload) ...@@ -112,7 +108,7 @@ CodecDescriptor::getBitRate(CodecType payload)
case PAYLOAD_CODEC_ILBC_20: case PAYLOAD_CODEC_ILBC_20:
return 15.2; return 15.2;
case PAYLOAD_CODEC_ILBC_30: case PAYLOAD_CODEC_ILBC_30:
return 15.2; return 13.3;
} }
return 0.0; return 0.0;
......
...@@ -50,7 +50,7 @@ typedef enum { ...@@ -50,7 +50,7 @@ typedef enum {
PAYLOAD_CODEC_SPEEX_32000 = 112 PAYLOAD_CODEC_SPEEX_32000 = 112
} CodecType; } CodecType;
#include "audiocodec.h" #include "codecs/audiocodec.h"
/* A codec is identified by its payload. A payload is associated with a name. */ /* A codec is identified by its payload. A payload is associated with a name. */
typedef std::map<CodecType, std::string> CodecMap; typedef std::map<CodecType, std::string> CodecMap;
......
sflcodecdir = $(libdir)/sflphone/codecs
noinst_PROGRAMS = libcodec_ulaw.so libcodec_alaw.so libcodec_gsm.so libcodec_speex.so libcodec_ilbc.so
noinst_HEADERS = audiocodec.h
libcodec_ulaw_so_SOURCES = ulaw.cpp
libcodec_ulaw_so_CFLAGS = -fPIC -g -Wall
libcodec_ulaw_so_LDFLAGS = -shared -lc
libcodec_alaw_so_SOURCES = alaw.cpp
libcodec_alaw_so_CFLAGS = -fPIC -g -Wall
libcodec_alaw_so_LDFLAGS = -shared -lc
libcodec_gsm_so_SOURCES = gsmcodec.cpp
libcodec_gsm_so_CFLAGS = -fPIC -g -Wall
libcodec_gsm_so_LDFLAGS = -shared -lc -lgsm
libcodec_speex_so_SOURCES = speexcodec.cpp
libcodec_speex_so_CFLAGS = -fPIC -g -Wall
libcodec_speex_so_LDFLAGS = -shared -lc -lspeex
libcodec_ilbc_so_SOURCES = ilbc.cpp
libcodec_ilbc_so_CFLAGS = -fPIC -g -Wall
libcodec_ilbc_so_LDFLAGS = -shared ilbc/*.o -lc
SUBDIRS = ilbc
install-exec-local: install-libcodec_ulaw_so install-libcodec_alaw_so install-libcodec_gsm_so install-libcodec_speex_so install-libcodec_ilbc_so
uninstall-local: uninstall-libcodec_ulaw_so uninstall-libcodec_alaw_so uninstall-libcodec_gsm_so uninstall-libcodec_speex_so uninstall-libcodec_ilbc_so
install-libcodec_ulaw_so: libcodec_ulaw.so
mkdir -p $(sflcodecdir)
$(INSTALL_PROGRAM) libcodec_ulaw.so $(sflcodecdir)
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)
install-libcodec_ilbc_so: libcodec_ilbc.so
$(INSTALL_PROGRAM) libcodec_ilbc.so $(sflcodecdir)
uninstall-libcodec_ulaw_so:
rm -f $(sflcodecdir)/libcodec_ulaw.so
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
uninstall-libcodec_ilbc_so:
rm -f $(sflcodecdir)/libcodec_ilbc.so
rm -rf $(sflcodecdir)
File moved
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include "common.h" #include "../common.h"
#include "audiocodec.h" #include "audiocodec.h"
class Alaw : public AudioCodec { class Alaw : public AudioCodec {
...@@ -31,7 +31,7 @@ public: ...@@ -31,7 +31,7 @@ public:
_channel = 1; _channel = 1;
} }
virtual ~Alaw(){}
virtual int codecDecode (short *dst, unsigned char *src, unsigned int size) virtual int codecDecode (short *dst, unsigned char *src, unsigned int size)
{ {
int16* end = dst+size; int16* end = dst+size;
......
#ifndef _CODEC_AUDIO_H
#define _CODEC_AUDIO_H
#include <string>
#include <iostream>
#include <dlfcn.h>
class AudioCodec {
protected:
/** Holds SDP-compliant codec name */
std::string _codecName; // what we put inside sdp
/** Clock rate or sample rate of the codec, in Hz */
unsigned int _clockRate;
/** Number of channel 1 = mono, 2 = stereo */
unsigned int _channel;
private:
int _payload;
bool _hasDynamicPayload;
public:
AudioCodec(int payload, const std::string &codecName)
: _codecName(codecName) {
_payload = payload;
_clockRate = 8000; // default
_channel = 1; // default
_hasDynamicPayload = (_payload >= 96 && _payload <= 127) ? true : false;
}
virtual ~AudioCodec() {
}
/**
* @return the number of bytes decoded
*/
virtual int codecDecode(short *, unsigned char *, unsigned int) = 0;
virtual int codecEncode(unsigned char *, short *, unsigned int) = 0;
/** Value used for SDP negotiation */
std::string getCodecName() { return _codecName; }
int getPayload() { return _payload; }
bool hasDynamicPayload() { return _hasDynamicPayload; }
unsigned int getClockRate() { return _clockRate; }
unsigned int getChannel() { return _channel; }
};
// the types of the class factories
typedef AudioCodec* create_t();
typedef void destroy_t(AudioCodec*);
#endif
...@@ -18,15 +18,11 @@ ...@@ -18,15 +18,11 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef __GSM_H__
#define __GSM_H__
#include <gsm.h>
#include "audiocodec.h" #include "audiocodec.h"
/*extern "C" { extern "C"{
#include "gsm/gsm.h" #include <gsm.h>
}*/ }
/** /**
* GSM audio codec C++ class (over gsm/gsm.h) * GSM audio codec C++ class (over gsm/gsm.h)
...@@ -34,16 +30,43 @@ ...@@ -34,16 +30,43 @@
class Gsm : public AudioCodec { class Gsm : public AudioCodec {
public: public:
// _payload should be 3 // _payload should be 3
Gsm (int payload=3); Gsm (int payload=3): AudioCodec(payload, "GSM"){
~Gsm (void); _clockRate = 8000;
_channel = 1;
if (!(_decode_gsmhandle = gsm_create() ))
printf("ERROR: decode_gsm_create\n");
if (!(_encode_gsmhandle = gsm_create() ))
printf("AudioCodec: ERROR: encode_gsm_create\n");
}
int codecDecode (short *, unsigned char *, unsigned int); virtual ~Gsm (void){
int codecEncode (unsigned char *, short *, unsigned int); gsm_destroy(_decode_gsmhandle);
void test(); gsm_destroy(_encode_gsmhandle);
}
virtual int codecDecode (short * dst, unsigned char * src, unsigned int size){
(void)size;
if(gsm_decode(_decode_gsmhandle, (gsm_byte*)src, (gsm_signal*)dst) < 0)
printf("ERROR: gsm_decode\n");
return 320;
}
virtual int codecEncode (unsigned char * dst, short * src, unsigned int size){
(void)size;
gsm_encode(_encode_gsmhandle, (gsm_signal*)src, (gsm_byte*) dst);
return 33;
}
private: private:
gsm _decode_gsmhandle; gsm _decode_gsmhandle;
gsm _encode_gsmhandle; gsm _encode_gsmhandle;
}; };
#endif // __ULAW_H__ extern "C" AudioCodec* create(){
return new Gsm(3);
}
extern "C" void destroy(AudioCodec* a){
delete a;
}
#include "audiocodec.h"
extern "C" {
#include "ilbc/iLBC_encode.h"
#include "ilbc/iLBC_decode.h"
}
class Ilbc: public AudioCodec
{
public:
Ilbc(int payload)
: AudioCodec(payload, "iLBC"){
_clockRate = 8000;
_channel = 1;
initILBC();
}
void initILBC(){
initDecode(ilbc_dec, 20, 1);
initEncode(ilbc_enc, 20);
}
virtual int codecDecode(short *dst, unsigned char *src, unsigned int size){
iLBC_decode((float*) dst, src, ilbc_dec, 0);
return 160;
}
virtual int codecEncode(unsigned char *dst, short* src, unsigned int size){
iLBC_encode(dst, (float*) src, ilbc_enc);
return 160;
}
private:
iLBC_Dec_Inst_t* ilbc_dec;
iLBC_Enc_Inst_t* ilbc_enc;
};
// the class factories
extern "C" AudioCodec* create(){
return new Ilbc(97);
}
extern "C" void destroy(AudioCodec* a){
delete a;
}
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
FrameClassify.c
Copyright (C) The Internet Society (2004).
All Rights Reserved.
******************************************************************/
#include "iLBC_define.h"
/*---------------------------------------------------------------*
* Classification of subframes to localize start state
*--------------------------------------------------------------*/
int FrameClassify( /* index to the max-energy sub-frame */
iLBC_Enc_Inst_t *iLBCenc_inst,
/* (i/o) the encoder state structure */
float *residual /* (i) lpc residual signal */
) {
float max_ssqEn, fssqEn[NSUB_MAX], bssqEn[NSUB_MAX], *pp;
int n, l, max_ssqEn_n;
const float ssqEn_win[NSUB_MAX-1]={(float)0.8,(float)0.9,
(float)1.0,(float)0.9,(float)0.8};
const float sampEn_win[5]={(float)1.0/(float)6.0,
(float)2.0/(float)6.0, (float)3.0/(float)6.0,
(float)4.0/(float)6.0, (float)5.0/(float)6.0};
/* init the front and back energies to zero */
memset(fssqEn, 0, NSUB_MAX*sizeof(float));
memset(bssqEn, 0, NSUB_MAX*sizeof(float));
/* Calculate front of first seqence */
n=0;
pp=residual;
for (l=0; l<5; l++) {
fssqEn[n] += sampEn_win[l] * (*pp) * (*pp);
pp++;
}
for (l=5; l<SUBL; l++) {
fssqEn[n] += (*pp) * (*pp);
pp++;
}
/* Calculate front and back of all middle sequences */
for (n=1; n<iLBCenc_inst->nsub-1; n++) {
pp=residual+n*SUBL;
for (l=0; l<5; l++) {
fssqEn[n] += sampEn_win[l] * (*pp) * (*pp);
bssqEn[n] += (*pp) * (*pp);
pp++;
}
for (l=5; l<SUBL-5; l++) {
fssqEn[n] += (*pp) * (*pp);
bssqEn[n] += (*pp) * (*pp);
pp++;
}
for (l=SUBL-5; l<SUBL; l++) {
fssqEn[n] += (*pp) * (*pp);
bssqEn[n] += sampEn_win[SUBL-l-1] * (*pp) * (*pp);
pp++;
}
}
/* Calculate back of last seqence */
n=iLBCenc_inst->nsub-1;
pp=residual+n*SUBL;
for (l=0; l<SUBL-5; l++) {
bssqEn[n] += (*pp) * (*pp);
pp++;
}
for (l=SUBL-5; l<SUBL; l++) {
bssqEn[n] += sampEn_win[SUBL-l-1] * (*pp) * (*pp);
pp++;
}
/* find the index to the weighted 80 sample with
most energy */
if (iLBCenc_inst->mode==20) l=1;
else l=0;
max_ssqEn=(fssqEn[0]+bssqEn[1])*ssqEn_win[l];
max_ssqEn_n=1;
for (n=2; n<iLBCenc_inst->nsub; n++) {
l++;
if ((fssqEn[n-1]+bssqEn[n])*ssqEn_win[l] > max_ssqEn) {
max_ssqEn=(fssqEn[n-1]+bssqEn[n]) *
ssqEn_win[l];
max_ssqEn_n=n;
}
}
return max_ssqEn_n;
}
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
FrameClassify.h
Copyright (C) The Internet Society (2004).
All Rights Reserved.
******************************************************************/
#ifndef __iLBC_FRAMECLASSIFY_H
#define __iLBC_FRAMECLASSIFY_H
int FrameClassify( /* index to the max-energy sub-frame */
iLBC_Enc_Inst_t *iLBCenc_inst,
/* (i/o) the encoder state structure */
float *residual /* (i) lpc residual signal */
);
#endif
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
LPC_decode.c
Copyright (C) The Internet Society (2004).
All Rights Reserved.
******************************************************************/
#include <math.h>
#include <string.h>
#include "helpfun.h"
#include "lsf.h"
#include "iLBC_define.h"
#include "constants.h"
/*---------------------------------------------------------------*
* interpolation of lsf coefficients for the decoder
*--------------------------------------------------------------*/
void LSFinterpolate2a_dec(
float *a, /* (o) lpc coefficients for a sub-frame */
float *lsf1, /* (i) first lsf coefficient vector */
float *lsf2, /* (i) second lsf coefficient vector */
float coef, /* (i) interpolation weight */
int length /* (i) length of lsf vectors */
){
float lsftmp[LPC_FILTERORDER];
interpolate(lsftmp, lsf1, lsf2, coef, length);
lsf2a(a, lsftmp);
}
/*---------------------------------------------------------------*
* obtain dequantized lsf coefficients from quantization index
*--------------------------------------------------------------*/
void SimplelsfDEQ(
float *lsfdeq, /* (o) dequantized lsf coefficients */
int *index, /* (i) quantization index */
int lpc_n /* (i) number of LPCs */
){
int i, j, pos, cb_pos;
/* decode first LSF */
pos = 0;
cb_pos = 0;
for (i = 0; i < LSF_NSPLIT; i++) {
for (j = 0; j < dim_lsfCbTbl[i]; j++) {
lsfdeq[pos + j] = lsfCbTbl[cb_pos +
(long)(index[i])*dim_lsfCbTbl[i] + j];
}
pos += dim_lsfCbTbl[i];
cb_pos += size_lsfCbTbl[i]*dim_lsfCbTbl[i];
}
if (lpc_n>1) {
/* decode last LSF */
pos = 0;
cb_pos = 0;
for (i = 0; i < LSF_NSPLIT; i++) {
for (j = 0; j < dim_lsfCbTbl[i]; j++) {
lsfdeq[LPC_FILTERORDER + pos + j] =
lsfCbTbl[cb_pos +
(long)(index[LSF_NSPLIT + i])*
dim_lsfCbTbl[i] + j];
}
pos += dim_lsfCbTbl[i];
cb_pos += size_lsfCbTbl[i]*dim_lsfCbTbl[i];
}
}
}
/*----------------------------------------------------------------*
* obtain synthesis and weighting filters form lsf coefficients
*---------------------------------------------------------------*/
void DecoderInterpolateLSF(
float *syntdenum, /* (o) synthesis filter coefficients */
float *weightdenum, /* (o) weighting denumerator
coefficients */
float *lsfdeq, /* (i) dequantized lsf coefficients */
int length, /* (i) length of lsf coefficient vector */
iLBC_Dec_Inst_t *iLBCdec_inst
/* (i) the decoder state structure */
){
int i, pos, lp_length;
float lp[LPC_FILTERORDER + 1], *lsfdeq2;
lsfdeq2 = lsfdeq + length;
lp_length = length + 1;
if (iLBCdec_inst->mode==30) {
/* sub-frame 1: Interpolation between old and first */
LSFinterpolate2a_dec(lp, iLBCdec_inst->lsfdeqold, lsfdeq,
lsf_weightTbl_30ms[0], length);
memcpy(syntdenum,lp,lp_length*sizeof(float));
bwexpand(weightdenum, lp, LPC_CHIRP_WEIGHTDENUM,
lp_length);
/* sub-frames 2 to 6: interpolation between first
and last LSF */
pos = lp_length;
for (i = 1; i < 6; i++) {
LSFinterpolate2a_dec(lp, lsfdeq, lsfdeq2,
lsf_weightTbl_30ms[i], length);
memcpy(syntdenum + pos,lp,lp_length*sizeof(float));
bwexpand(weightdenum + pos, lp,
LPC_CHIRP_WEIGHTDENUM, lp_length);
pos += lp_length;
}
}
else {
pos = 0;
for (i = 0; i < iLBCdec_inst->nsub; i++) {
LSFinterpolate2a_dec(lp, iLBCdec_inst->lsfdeqold,
lsfdeq, lsf_weightTbl_20ms[i], length);
memcpy(syntdenum+pos,lp,lp_length*sizeof(float));
bwexpand(weightdenum+pos, lp, LPC_CHIRP_WEIGHTDENUM,
lp_length);
pos += lp_length;
}
}
/* update memory */
if (iLBCdec_inst->mode==30)
memcpy(iLBCdec_inst->lsfdeqold, lsfdeq2,
length*sizeof(float));
else
memcpy(iLBCdec_inst->lsfdeqold, lsfdeq,
length*sizeof(float));
}
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
LPC_decode.h
Copyright (C) The Internet Society (2004).
All Rights Reserved.
******************************************************************/
#ifndef __iLBC_LPC_DECODE_H
#define __iLBC_LPC_DECODE_H
void LSFinterpolate2a_dec(
float *a, /* (o) lpc coefficients for a sub-frame */
float *lsf1, /* (i) first lsf coefficient vector */
float *lsf2, /* (i) second lsf coefficient vector */
float coef, /* (i) interpolation weight */
int length /* (i) length of lsf vectors */
);
void SimplelsfDEQ(
float *lsfdeq, /* (o) dequantized lsf coefficients */
int *index, /* (i) quantization index */
int lpc_n /* (i) number of LPCs */
);
void DecoderInterpolateLSF(
float *syntdenum, /* (o) synthesis filter coefficients */
float *weightdenum, /* (o) weighting denumerator
coefficients */
float *lsfdeq, /* (i) dequantized lsf coefficients */
int length, /* (i) length of lsf coefficient vector */
iLBC_Dec_Inst_t *iLBCdec_inst
/* (i) the decoder state structure */
);
#endif
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
LPCencode.c
Copyright (C) The Internet Society (2004).
All Rights Reserved.
******************************************************************/
#include <string.h>
#include "iLBC_define.h"
#include "helpfun.h"
#include "lsf.h"
#include "constants.h"
/*----------------------------------------------------------------*
* lpc analysis (subrutine to LPCencode)
*---------------------------------------------------------------*/
void SimpleAnalysis(
float *lsf, /* (o) lsf coefficients */
float *data, /* (i) new data vector */
iLBC_Enc_Inst_t *iLBCenc_inst
/* (i/o) the encoder state structure */
){
int k, is;
float temp[BLOCKL_MAX], lp[LPC_FILTERORDER + 1];
float lp2[LPC_FILTERORDER + 1];
float r[LPC_FILTERORDER + 1];
is=LPC_LOOKBACK+BLOCKL_MAX-iLBCenc_inst->blockl;
memcpy(iLBCenc_inst->lpc_buffer+is,data,
iLBCenc_inst->blockl*sizeof(float));
/* No lookahead, last window is asymmetric */
for (k = 0; k < iLBCenc_inst->lpc_n; k++) {
is = LPC_LOOKBACK;
if (k < (iLBCenc_inst->lpc_n - 1)) {
window(temp, lpc_winTbl,
iLBCenc_inst->lpc_buffer, BLOCKL_MAX);
} else {
window(temp, lpc_asymwinTbl,
iLBCenc_inst->lpc_buffer + is, BLOCKL_MAX);
}
autocorr(r, temp, BLOCKL_MAX, LPC_FILTERORDER);
window(r, r, lpc_lagwinTbl, LPC_FILTERORDER + 1);
levdurb(lp, temp, r, LPC_FILTERORDER);
bwexpand(lp2, lp, LPC_CHIRP_SYNTDENUM, LPC_FILTERORDER+1);
a2lsf(lsf + k*LPC_FILTERORDER, lp2);
}
is=LPC_LOOKBACK+BLOCKL_MAX-iLBCenc_inst->blockl;
memmove(iLBCenc_inst->lpc_buffer,
iLBCenc_inst->lpc_buffer+LPC_LOOKBACK+BLOCKL_MAX-is,
is*sizeof(float));
}
/*----------------------------------------------------------------*
* lsf interpolator and conversion from lsf to a coefficients
* (subrutine to SimpleInterpolateLSF)
*---------------------------------------------------------------*/
void LSFinterpolate2a_enc(
float *a, /* (o) lpc coefficients */
float *lsf1,/* (i) first set of lsf coefficients */
float *lsf2,/* (i) second set of lsf coefficients */
float coef, /* (i) weighting coefficient to use between
lsf1 and lsf2 */
long length /* (i) length of coefficient vectors */
){
float lsftmp[LPC_FILTERORDER];
interpolate(lsftmp, lsf1, lsf2, coef, length);
lsf2a(a, lsftmp);
}
/*----------------------------------------------------------------*
* lsf interpolator (subrutine to LPCencode)
*---------------------------------------------------------------*/
void SimpleInterpolateLSF(
float *syntdenum, /* (o) the synthesis filter denominator
resulting from the quantized
interpolated lsf */
float *weightdenum, /* (o) the weighting filter denominator
resulting from the unquantized
interpolated lsf */
float *lsf, /* (i) the unquantized lsf coefficients */
float *lsfdeq, /* (i) the dequantized lsf coefficients */
float *lsfold, /* (i) the unquantized lsf coefficients of
the previous signal frame */
float *lsfdeqold, /* (i) the dequantized lsf coefficients of
the previous signal frame */
int length, /* (i) should equate LPC_FILTERORDER */
iLBC_Enc_Inst_t *iLBCenc_inst
/* (i/o) the encoder state structure */
){
int i, pos, lp_length;
float lp[LPC_FILTERORDER + 1], *lsf2, *lsfdeq2;
lsf2 = lsf + length;
lsfdeq2 = lsfdeq + length;
lp_length = length + 1;
if (iLBCenc_inst->mode==30) {
/* sub-frame 1: Interpolation between old and first
set of lsf coefficients */
LSFinterpolate2a_enc(lp, lsfdeqold, lsfdeq,
lsf_weightTbl_30ms[0], length);
memcpy(syntdenum,lp,lp_length*sizeof(float));
LSFinterpolate2a_enc(lp, lsfold, lsf,
lsf_weightTbl_30ms[0], length);
bwexpand(weightdenum, lp, LPC_CHIRP_WEIGHTDENUM, lp_length);
/* sub-frame 2 to 6: Interpolation between first
and second set of lsf coefficients */
pos = lp_length;
for (i = 1; i < iLBCenc_inst->nsub; i++) {
LSFinterpolate2a_enc(lp, lsfdeq, lsfdeq2,
lsf_weightTbl_30ms[i], length);
memcpy(syntdenum + pos,lp,lp_length*sizeof(float));
LSFinterpolate2a_enc(lp, lsf, lsf2,
lsf_weightTbl_30ms[i], length);
bwexpand(weightdenum + pos, lp,
LPC_CHIRP_WEIGHTDENUM, lp_length);
pos += lp_length;
}
}
else {
pos = 0;
for (i = 0; i < iLBCenc_inst->nsub; i++) {
LSFinterpolate2a_enc(lp, lsfdeqold, lsfdeq,
lsf_weightTbl_20ms[i], length);
memcpy(syntdenum+pos,lp,lp_length*sizeof(float));
LSFinterpolate2a_enc(lp, lsfold, lsf,
lsf_weightTbl_20ms[i], length);
bwexpand(weightdenum+pos, lp,
LPC_CHIRP_WEIGHTDENUM, lp_length);
pos += lp_length;
}
}
/* update memory */
if (iLBCenc_inst->mode==30) {
memcpy(lsfold, lsf2, length*sizeof(float));
memcpy(lsfdeqold, lsfdeq2, length*sizeof(float));
}
else {
memcpy(lsfold, lsf, length*sizeof(float));
memcpy(lsfdeqold, lsfdeq, length*sizeof(float));
}
}
/*----------------------------------------------------------------*
* lsf quantizer (subrutine to LPCencode)
*---------------------------------------------------------------*/
void SimplelsfQ(
float *lsfdeq, /* (o) dequantized lsf coefficients
(dimension FILTERORDER) */
int *index, /* (o) quantization index */
float *lsf, /* (i) the lsf coefficient vector to be
quantized (dimension FILTERORDER ) */
int lpc_n /* (i) number of lsf sets to quantize */
){
/* Quantize first LSF with memoryless split VQ */
SplitVQ(lsfdeq, index, lsf, lsfCbTbl, LSF_NSPLIT,
dim_lsfCbTbl, size_lsfCbTbl);
if (lpc_n==2) {
/* Quantize second LSF with memoryless split VQ */
SplitVQ(lsfdeq + LPC_FILTERORDER, index + LSF_NSPLIT,
lsf + LPC_FILTERORDER, lsfCbTbl, LSF_NSPLIT,
dim_lsfCbTbl, size_lsfCbTbl);
}
}
/*----------------------------------------------------------------*
* lpc encoder
*---------------------------------------------------------------*/
void LPCencode(
float *syntdenum, /* (i/o) synthesis filter coefficients
before/after encoding */
float *weightdenum, /* (i/o) weighting denumerator
coefficients before/after
encoding */
int *lsf_index, /* (o) lsf quantization index */
float *data, /* (i) lsf coefficients to quantize */
iLBC_Enc_Inst_t *iLBCenc_inst
/* (i/o) the encoder state structure */
){
float lsf[LPC_FILTERORDER * LPC_N_MAX];
float lsfdeq[LPC_FILTERORDER * LPC_N_MAX];
int change=0;
SimpleAnalysis(lsf, data, iLBCenc_inst);
SimplelsfQ(lsfdeq, lsf_index, lsf, iLBCenc_inst->lpc_n);
change=LSF_check(lsfdeq, LPC_FILTERORDER, iLBCenc_inst->lpc_n);
SimpleInterpolateLSF(syntdenum, weightdenum,
lsf, lsfdeq, iLBCenc_inst->lsfold,
iLBCenc_inst->lsfdeqold, LPC_FILTERORDER, iLBCenc_inst);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment