diff --git a/configure.ac b/configure.ac index e09abd63487dd9b2ef7b53b8c6cb69ebdc2bfbe1..8d80667fb125b4d4d2c0b4979cd85a426e03dc30 100644 --- a/configure.ac +++ b/configure.ac @@ -232,11 +232,14 @@ AS_IF([test "x$with_speex" != xno], [AC_MSG_FAILURE( [libspeex link test failed. You may use --without-speex to compile without speex codec support.])] ) - ] - ) + ] +dnl More advanced check in case the libspeexdsp is not installed +AC_CHECK_LIB(speex, speex_preprocess_run, [AC_DEFINE(HAVE_SPEEX_DSP)]) +) AC_DEFINE([HAVE_SPEEX], test "x$with_speex" = "xyes", [Define if you have libspeex]) AM_CONDITIONAL(BUILD_SPEEX, test "x$with_speex" = "xyes" ) +AM_CONDITIONAL(HAVE_SPEEX_DSP, $(HAVE_SPEEX_DSP)) dnl Check for ilbc support AC_ARG_WITH([ilbc], diff --git a/src/audio/codecs/Makefile.am b/src/audio/codecs/Makefile.am index 6f8b16559c518a1c2da8832b4befa607b1282a67..236f2d71a115b12b8aaf1e8e6cf95a55055f88ab 100644 --- a/src/audio/codecs/Makefile.am +++ b/src/audio/codecs/Makefile.am @@ -11,10 +11,14 @@ endif if BUILD_SPEEX SPEEX_LIB = libcodec_speex.so +SPEEX_DSP_LIB= +if HAVE_SPEEX_DSP +SPEEX_DSP_LIB = -lspeexdsp +endif libcodec_speex_so_SOURCES = speexcodec.cpp libcodec_speex_so_CFLAGS = -fPIC -g -Wall libcodec_speex_so_CXXFLAGS = -fPIC -g -Wall -libcodec_speex_so_LDFLAGS = --shared -lc -lspeex -lspeexdsp -lm +libcodec_speex_so_LDFLAGS = --shared -lc -lspeex $(SPEEX_DSP_LIB) -lm INSTALL_SPEEX_RULE = install-libcodec_speex_so endif diff --git a/src/audio/codecs/speexcodec.cpp b/src/audio/codecs/speexcodec.cpp index c9a350fcdb3208b58296b01d96f5bb130de7342b..b141dd5f39721c1d885ff1f03b4f8e57d80952cc 100644 --- a/src/audio/codecs/speexcodec.cpp +++ b/src/audio/codecs/speexcodec.cpp @@ -1,7 +1,7 @@ /* - * Copyright (C) 2005 Savoir-Faire Linux inc. - * Author: Yan Morin <yan.morin@savoirfairelinux.com> - * Author: Jerome Oufella <jerome.oufella@savoirfairelinux.com> + * Copyright (C) 2007-2009 Savoir-Faire Linux inc. + * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com> + * Author: Emmanuel Milou <emmanuel.milou@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 @@ -23,116 +23,114 @@ #include <speex/speex.h> #include <speex/speex_preprocess.h> - - class Speex : public AudioCodec{ -public: - Speex(int payload=0) - : AudioCodec(payload, "speex"), - _speexModePtr(NULL), - _speex_dec_bits(), - _speex_enc_bits(), - _speex_dec_state(), - _speex_enc_state(), - _speex_frame_size(), - _preprocess_state() - { - _clockRate = 8000; - _channel = 1; - _bitrate = 0; - _bandwidth = 0; - initSpeex(); - } + public: + Speex(int payload=0) + : AudioCodec(payload, "speex"), + _speexModePtr(NULL), + _speex_dec_bits(), + _speex_enc_bits(), + _speex_dec_state(), + _speex_enc_state(), + _speex_frame_size(), + _preprocess_state() + { + _clockRate = 8000; + _channel = 1; + _bitrate = 0; + _bandwidth = 0; + initSpeex(); + } Speex( const Speex& ); Speex& operator=(const Speex&); - void initSpeex() { - int enable = 1; - int quality = 10; - int complex = 10; - int attenuation = -10; - - /* - if (_clockRate < 16000 ) { - _speexModePtr = &speex_nb_mode; - } else if (_clockRate < 32000) { - _speexModePtr = &speex_wb_mode; - } else { - _speexModePtr = &speex_uwb_mode; - } - */ - // 8000 HZ --> Narrow-band mode - // TODO Manage the other modes - _speexModePtr = &speex_nb_mode; - - // Init the decoder struct - speex_bits_init(&_speex_dec_bits); - _speex_dec_state = speex_decoder_init(_speexModePtr); - - // Init the encoder struct - speex_bits_init(&_speex_enc_bits); - _speex_enc_state = speex_encoder_init(_speexModePtr); - speex_encoder_ctl(_speex_enc_state, SPEEX_SET_VAD, &enable); - speex_encoder_ctl(_speex_enc_state, SPEEX_SET_DTX, &enable); - speex_encoder_ctl(_speex_enc_state, SPEEX_SET_VBR_QUALITY, &quality); - speex_encoder_ctl(_speex_enc_state, SPEEX_SET_COMPLEXITY, &complex); - - // Init the decoder struct - speex_decoder_ctl(_speex_dec_state, SPEEX_GET_FRAME_SIZE, &_speex_frame_size); - - // Init the preprocess struct - _preprocess_state = speex_preprocess_state_init(_speex_frame_size,_clockRate); - speex_preprocess_ctl(_preprocess_state, SPEEX_PREPROCESS_SET_DENOISE, &enable); - speex_preprocess_ctl(_preprocess_state, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &attenuation); - speex_preprocess_ctl(_preprocess_state, SPEEX_PREPROCESS_SET_VAD, &enable); - speex_preprocess_ctl(_preprocess_state, SPEEX_PREPROCESS_SET_AGC, &enable); - + void initSpeex() { + + // 8000 HZ --> Narrow-band mode + // TODO Manage the other modes + _speexModePtr = &speex_nb_mode; + + // Init the decoder struct + speex_bits_init(&_speex_dec_bits); + _speex_dec_state = speex_decoder_init(_speexModePtr); + + // Init the encoder struct + speex_bits_init(&_speex_enc_bits); + _speex_enc_state = speex_encoder_init(_speexModePtr); + +#ifdef HAVE_SPEEX_DSP + + int enable = 1; + int quality = 10; + int complex = 10; + int attenuation = -10; + + speex_encoder_ctl(_speex_enc_state, SPEEX_SET_VAD, &enable); + speex_encoder_ctl(_speex_enc_state, SPEEX_SET_DTX, &enable); + speex_encoder_ctl(_speex_enc_state, SPEEX_SET_VBR_QUALITY, &quality); + speex_encoder_ctl(_speex_enc_state, SPEEX_SET_COMPLEXITY, &complex); + + // Init the decoder struct + speex_decoder_ctl(_speex_dec_state, SPEEX_GET_FRAME_SIZE, &_speex_frame_size); + + // Init the preprocess struct + _preprocess_state = speex_preprocess_state_init(_speex_frame_size,_clockRate); + speex_preprocess_ctl(_preprocess_state, SPEEX_PREPROCESS_SET_DENOISE, &enable); + speex_preprocess_ctl(_preprocess_state, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &attenuation); + speex_preprocess_ctl(_preprocess_state, SPEEX_PREPROCESS_SET_VAD, &enable); + speex_preprocess_ctl(_preprocess_state, SPEEX_PREPROCESS_SET_AGC, &enable); +#endif + + } + + ~Speex() + { + terminateSpeex(); + } + + void terminateSpeex() { + // Destroy the decoder struct + speex_bits_destroy(&_speex_dec_bits); + speex_decoder_destroy(_speex_dec_state); + _speex_dec_state = 0; + + // Destroy the encoder struct + 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) + { + int ratio = 320 / _speex_frame_size; + speex_bits_read_from(&_speex_dec_bits, (char*)src, size); + speex_decode_int(_speex_dec_state, &_speex_dec_bits, dst); + + return _speex_frame_size * ratio; + } + + virtual int codecEncode (unsigned char *dst, short *src, unsigned int size) + { + speex_bits_reset(&_speex_enc_bits); + +#ifdef HAVE_SPEEX_DSP + speex_encoder_ctl(_speex_enc_state,SPEEX_SET_SAMPLING_RATE,&_clockRate); + speex_preprocess_run(_preprocess_state, src); +#endif + + speex_encode_int(_speex_enc_state, src, &_speex_enc_bits); + int nbBytes = speex_bits_write(&_speex_enc_bits, (char*)dst, size); + return nbBytes; } - ~Speex() - { - terminateSpeex(); - } - - void terminateSpeex() { - // Destroy the decoder struct - speex_bits_destroy(&_speex_dec_bits); - speex_decoder_destroy(_speex_dec_state); - _speex_dec_state = 0; - - // Destroy the encoder struct - 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) - { - int ratio = 320 / _speex_frame_size; - speex_bits_read_from(&_speex_dec_bits, (char*)src, size); - speex_decode_int(_speex_dec_state, &_speex_dec_bits, dst); - - return _speex_frame_size * ratio; - } - - 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_preprocess_run(_preprocess_state, src); - 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; + private: + const SpeexMode* _speexModePtr; + SpeexBits _speex_dec_bits; + SpeexBits _speex_enc_bits; + void *_speex_dec_state; + void *_speex_enc_state; + int _speex_frame_size; SpeexPreprocessState *_preprocess_state; };