Commit 916bc091 authored by Emmanuel Milou's avatar Emmanuel Milou
Browse files

chargement dynamique des codecs (Ulaw + Alaw).

Copier les librairies dynamiques (codec_*.so) dans le répertoire /usr/lib et upda
faire ldconfig
parent dfe7e9a4
......@@ -13,7 +13,7 @@ SPEEX_LIB=
endif
libaudio_la_SOURCES = alaw.cpp audiofile.cpp g711.cpp tonelist.cpp \
audiortp.cpp dtmf.cpp tone.cpp audiocodec.cpp audiolayer.cpp audiodevice.cpp dtmfgenerator.cpp gsmcodec.cpp \
audiortp.cpp dtmf.cpp tone.cpp audiolayer.cpp audiodevice.cpp dtmfgenerator.cpp gsmcodec.cpp \
tonegenerator.cpp ulaw.cpp codecDescriptor.cpp \
audioloop.cpp ringbuffer.cpp $(SPEEX_SOURCES_CPP)
......
......@@ -18,11 +18,14 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "g711.h"
#include "alaw.h"
#include "common.h"
#include "audiocodec.h"
class Alaw : public AudioCodec {
public:
// 8 PCMA A 8000 1 [RFC3551]
Alaw::Alaw(int payload)
Alaw(int payload=0)
: AudioCodec(payload, "PCMA")
{
_description = "G711a";
......@@ -31,19 +34,101 @@ Alaw::Alaw(int payload)
_channel = 1;
}
Alaw::~Alaw (void)
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
Alaw::codecDecode (short *dst, unsigned char *src, unsigned int size)
int ALawDecode(uint8 alaw)
{
return G711::ALawDecode (dst, src, size);
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;
}
int
Alaw::codecEncode (unsigned char *dst, short *src, unsigned int size)
virtual int codecEncode (unsigned char *dst, short *src, unsigned int size)
{
return G711::ALawEncode (dst, src, size);
size >>= 1;
uint8* end = dst+size;
while(dst<end)
*dst++ = ALawEncode(*src++);
return size;
}
virtual void test()
{
printf("MON OSTIE ALAW!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
}
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
{
//+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>=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)
return u;
}
};
// the class factories
extern "C" AudioCodec* create_alaw() {
return new Alaw();
}
extern "C" void destroy_alaw(AudioCodec* a) {
delete a;
}
......@@ -34,6 +34,7 @@ public:
int codecDecode (short *, unsigned char *, unsigned int);
int codecEncode (unsigned char *, short *, unsigned int);
void test () ;
};
#endif // __ULAW_H__
/*
* 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.
*/
#ifndef _CODEC_AUDIO_H
#define _CODEC_AUDIO_H
#ifndef __CODEC_AUDIO_H__
#define __CODEC_AUDIO_H__
#include <string>
#include <iostream>
#include <string>
/**
* Abstract audio codec class.
* A codec can be decode, encode
* Each codec have a payload, clock rate and a codec name
*/
class AudioCodec {
public:
AudioCodec(int payload, const std::string &codecName);
virtual ~AudioCodec(void);
/**
* @return the number of bytes decoded
*/
virtual int codecDecode(short *, unsigned char *, unsigned int) = 0;
virtual int codecEncode(unsigned char *, short *, unsigned int) = 0;
/** Returns description for GUI usage */
std::string getDescription() { return _description; }
/** 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; }
bool isActive() { return _active; }
void setActive(bool active) { _active = active; }
protected:
/** Holds SDP-compliant codec name */
std::string _codecName; // what we put inside sdp
/** Holds the GUI-style codec description */
std::string _description; // what we display to the user
/**
* Clock rate or sample rate of the codec, in Hz
*/
/** Clock rate or sample rate of the codec, in Hz */
unsigned int _clockRate;
/**
* Number of channel 1 = mono, 2 = stereo
*/
/** Number of channel 1 = mono, 2 = stereo */
unsigned int _channel;
private:
bool _active;
int _payload;
bool _hasDynamicPayload;
public:
AudioCodec(int payload, const std::string &codecName)
: _codecName(codecName) {
_payload = payload;
_clockRate = 8000; // default
_channel = 1; // default
_active = false;
_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;
virtual void test()=0;
/** Returns description for GUI usage */
std::string getDescription() { return _description; }
/** 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; }
bool isActive() { return _active; }
void setActive(bool active) { _active = active; }
};
#endif // __CODEC_AUDIO_H__
// the types of the class factories
typedef AudioCodec* create_t();
typedef void destroy_t(AudioCodec*);
#endif
......@@ -29,6 +29,8 @@
//#include <fstream> // fstream + iostream pour fstream debugging..
//#include <iostream> // removeable...
#include <math.h>
#include <dlfcn.h>
#include <iostream>
#include "../global.h"
#include "../manager.h"
......@@ -248,6 +250,32 @@ AudioRtpRTX::initAudioRtpSession (void)
void
AudioRtpRTX::sendSessionFromMic(int timestamp)
{
using std::cout;
using std::cerr;
void* codec = dlopen("codec_alaw.so", RTLD_LAZY);
if(!codec){
cerr<<"cannot load library: "<< dlerror() <<'\n';
}
//reset errors
dlerror();
//load the symbols
create_t* create_codec = (create_t*)dlsym(codec, "create_alaw");
const char* dlsym_error = dlerror();
if(dlsym_error){
cerr << "Cannot load symbol create: " << dlsym_error << '\n';
}
destroy_t* destroy_codec = (destroy_t*) dlsym(codec, "destroy_alaw");
dlsym_error = dlerror();
if(dlsym_error){
cerr << "Cannot load symbol destroy" << dlsym_error << '\n';
}
int pl = 0;
AudioCodec* audiocodec = create_codec();
//audiocodec1->test();
// STEP:
// 1. get data from mic
// 2. convert it to int16 - good sample, good rate
......@@ -261,7 +289,8 @@ AudioRtpRTX::sendSessionFromMic(int timestamp)
AudioLayer* audiolayer = Manager::instance().getAudioDriver();
if (!audiolayer) { _debug(" !ARTP: No audiolayer available for mic\n"); return; }
AudioCodec* audiocodec = _ca->getAudioCodec();
//AudioCodec* audiocodec = _ca->getAudioCodec();
//AudioCodec* audiocodec = _ca->getAudioCodec();
if (!audiocodec) { _debug(" !ARTP: No audiocodec available for mic\n"); return; }
// we have to get 20ms of data from the mic *20/1000 = /50
......@@ -308,6 +337,9 @@ AudioRtpRTX::sendSessionFromMic(int timestamp)
throw;
}
destroy_codec(audiocodec);
dlclose(codec);
}
......@@ -336,10 +368,35 @@ AudioRtpRTX::receiveSessionForSpkr (int& countTime)
int payload = adu->getType(); // codec type
unsigned char* data = (unsigned char*)adu->getData(); // data in char
unsigned int size = adu->getSize(); // size in char
using std::cout;
using std::cerr;
void* codec = dlopen("codec_alaw.so", RTLD_LAZY);
if(!codec){
cerr<<"cannot load library: "<< dlerror() <<'\n';
}
//reset errors
dlerror();
//load the symbols
create_t* create_codec = (create_t*)dlsym(codec, "create_alaw");
const char* dlsym_error = dlerror();
if(dlsym_error){
cerr << "Cannot load symbol create: " << dlsym_error << '\n';
}
destroy_t* destroy_codec = (destroy_t*) dlsym(codec, "destroy_alaw");
dlsym_error = dlerror();
if(dlsym_error){
cerr << "Cannot load symbol destroy" << dlsym_error << '\n';
}
int pl = 0;
AudioCodec* audiocodec = create_codec();
//audiocodec1->test();
// Decode data with relevant codec
AudioCodec* audiocodec = _ca->getCodecMap().getCodec((CodecType)payload);
//AudioCodec* audiocodec = _ca->getCodecMap().getCodec((CodecType)payload);
_codecSampleRate = audiocodec->getClockRate();
int max = (int)(_codecSampleRate * _layerFrameSize);
......@@ -389,10 +446,15 @@ AudioRtpRTX::receiveSessionForSpkr (int& countTime)
}
delete adu; adu = NULL;
destroy_codec(audiocodec);
dlclose(codec);
} catch(...) {
_debugException("! ARTP: receiving failed");
throw;
}
}
int
......
......@@ -59,4 +59,10 @@ Gsm::codecEncode (unsigned char *dst, short *src, unsigned int size)
return 33;
}
void
Gsm::test()
{
printf("MOn OSTIE GSM!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
}
......@@ -37,6 +37,7 @@ public:
int codecDecode (short *, unsigned char *, unsigned int);
int codecEncode (unsigned char *, short *, unsigned int);
void test();
private:
gsm _decode_gsmhandle;
......
/**
* 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 "g711.h"
#include "ulaw.h"
// 0 PCMU A 8000 1 [RFC3551]
Ulaw::Ulaw(int payload)
: AudioCodec(payload, "PCMU")
{
_description = "G711u";
_clockRate = 8000;
_channel = 1;
}
#include "common.h"
#include "audiocodec.h"
Ulaw::~Ulaw (void)
{
}
class Ulaw : public AudioCodec {
public:
// 0 PCMU A 8000 1 [RFC3551]
Ulaw(int payload=0)
: AudioCodec(payload, "PCMU")
{
_description = "G711u";
_clockRate = 8000;
_channel = 1;
}
int
Ulaw::codecDecode (short *dst, unsigned char *src, unsigned int size)
{
return G711::ULawDecode (dst, src, size);
}
virtual void test(){
printf("MON OSTIE !!!!!!!!!!!!!!!!!!!!!!!!!!\n");
}
virtual int codecDecode (short *dst, unsigned char *src, unsigned int size) {
int16* end = dst+size;
while(dst<end)
*dst++ = ULawDecode(*src++);
return size<<1;
}
virtual int codecEncode (unsigned char *dst, short *src, unsigned int size) {
//return G711::ULawEncode (dst, src, size);
size >>= 1;
uint8* end = dst+size;
while(dst<end)
*dst++ = ULawEncode(*src++);
return size;
}
int ULawDecode(uint8 ulaw)
{
ulaw ^= 0xff; // u-law has all bits inverted for transmission
int linear = ulaw&0x0f;
linear <<= 3;
linear |= 0x84; // Set MSB (0x80) and a 'half' bit (0x04) to place PCM value in middle of range
uint shift = ulaw>>4;
shift &= 7;
linear <<= shift;
linear -= 0x84; // Subract uLaw bias
int
Ulaw::codecEncode (unsigned char *dst, short *src, unsigned int size)
{
return G711::ULawEncode (dst, src, size);
if(ulaw&0x80)
return -linear;
else
return linear;
}
uint8 ULawEncode(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{
u = 0x00^0x10^0xff; // Sign bit = 0 (-0x10 because this amount extra will get added later) ^0xff to invert final u-Law code
}
p += 0x84; // Add uLaw bias
if(p>0x7f00)
p = 0x7f00; // Clip to 15 bits
// Calculate segment and interval numbers
p >>= 3; // Shift down to 13bit
if(p>=0x100)
{
p >>= 4;
u ^= 0x40;
}
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)
return u;
}
};
// the class factories
extern "C" AudioCodec* create_ulaw() {
return new Ulaw();
}
extern "C" void destroy_ulaw(AudioCodec* a) {
delete a;
}
......@@ -34,6 +34,7 @@ public:
int codecDecode(short *, unsigned char *, unsigned int);
int codecEncode(unsigned char *, short *, unsigned int);
void test();
};
#endif // __ULAW_H__
Supports Markdown
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