diff --git a/sflphone-client-gnome/src/config/audioconf.c b/sflphone-client-gnome/src/config/audioconf.c index 9031c99febfd62ef4e740d56ef73b79f4b9cc88e..5dd23a4dd68a8251a7bcd0c89d409210acde3d6a 100644 --- a/sflphone-client-gnome/src/config/audioconf.c +++ b/sflphone-client-gnome/src/config/audioconf.c @@ -397,6 +397,8 @@ codec_active_toggled(GtkCellRendererToggle *renderer UNUSED, gchar *path, gpoint codec = codec_list_get_by_payload(110); else if ((g_strcasecmp(name,"speex")==0) && (g_strcasecmp(srate,"16 kHz")==0)) codec = codec_list_get_by_payload(111); + else if ((g_strcasecmp(name,"speex")==0) && (g_strcasecmp(srate,"32 kHz")==0)) + codec = codec_list_get_by_payload(112); else codec = codec_list_get_by_name(name); diff --git a/sflphone-common/src/audio/codecs/Makefile.am b/sflphone-common/src/audio/codecs/Makefile.am index 028a178cfd0342945ada0fcd9a169923e6c3f621..10a005f1c85bcd86a54a1997627352cd30d07cbd 100644 --- a/sflphone-common/src/audio/codecs/Makefile.am +++ b/sflphone-common/src/audio/codecs/Makefile.am @@ -31,6 +31,14 @@ libcodec_speex_wb_so_LDFLAGS = --shared -lc -lspeex $(SPEEX_NIMP) INSTALL_SPEEX_WB_RULE = install-libcodec_speex_wb_so endif +if BUILD_SPEEX +SPEEX_UB_LIB = libcodec_speex_ub.so +libcodec_speex_ub_so_SOURCES = speexcodec_ub.cpp +libcodec_speex_ub_so_CFLAGS = -fPIC -g -Wall +libcodec_speex_ub_so_CXXFLAGS = -fPIC -g -Wall $(SPEEXDSP) +libcodec_speex_ub_so_LDFLAGS = --shared -lc -lspeex $(SPEEX_NIMP) +INSTALL_SPEEX_UB_RULE = install-libcodec_speex_ub_so +endif if BUILD_CELT CELT_LIB = libcodec_celt.so @@ -52,7 +60,7 @@ INSTALL_ILBC_RULE = install-libcodec_ilbc_so SUBDIRS = ilbc endif -noinst_PROGRAMS = libcodec_ulaw.so libcodec_alaw.so libcodec_g722.so $(GSM_LIB) $(SPEEX_NB_LIB) $(SPEEX_WB_LIB) $(CELT_LIB) $(ILBC_LIB) +noinst_PROGRAMS = libcodec_ulaw.so libcodec_alaw.so libcodec_g722.so $(GSM_LIB) $(SPEEX_NB_LIB) $(SPEEX_WB_LIB) $(SPEEX_UB_LIB) $(CELT_LIB) $(ILBC_LIB) noinst_HEADERS = audiocodec.h @@ -72,8 +80,8 @@ libcodec_g722_so_CFLAGS = -fPIC -g -Wall libcodec_g722_so_CXXFLAGS = -fPIC -g -Wall libcodec_g722_so_LDFLAGS = --shared -lc -install-exec-local: install-libcodec_ulaw_so install-libcodec_alaw_so install-libcodec_g722_so $(INSTALL_GSM_RULE) $(INSTALL_SPEEX_NB_RULE) $(INSTALL_SPEEX_WB_RULE) $(INSTALL_CELT_RULE) $(INSTALL_ILBC_RULE) -uninstall-local: uninstall-libcodec_ulaw_so uninstall-libcodec_alaw_so uninstall-libcodec_g722_so uninstall-libcodec_gsm_so uninstall-libcodec_speex_nb_so uninstall-libcodec_speex_wb_so uninstall-libcodec_celt_so +install-exec-local: install-libcodec_ulaw_so install-libcodec_alaw_so install-libcodec_g722_so $(INSTALL_GSM_RULE) $(INSTALL_SPEEX_NB_RULE) $(INSTALL_SPEEX_WB_RULE) $(INSTALL_SPEEX_UB_RULE) $(INSTALL_CELT_RULE) $(INSTALL_ILBC_RULE) +uninstall-local: uninstall-libcodec_ulaw_so uninstall-libcodec_alaw_so uninstall-libcodec_g722_so uninstall-libcodec_gsm_so uninstall-libcodec_speex_nb_so uninstall-libcodec_speex_wb_so uninstall-libcodec_speex_ub_so uninstall-libcodec_celt_so install-libcodec_ulaw_so: libcodec_ulaw.so @@ -89,6 +97,8 @@ install-libcodec_speex_nb_so: libcodec_speex_nb.so $(INSTALL_PROGRAM) libcodec_speex_nb.so $(sflcodecdir) install-libcodec_speex_wb_so: libcodec_speex_wb.so $(INSTALL_PROGRAM) libcodec_speex_wb.so $(sflcodecdir) +install-libcodec_speex_ub_so: libcodec_speex_ub.so + $(INSTALL_PROGRAM) libcodec_speex_ub.so $(sflcodecdir) install-libcodec_celt_so: libcodec_celt.so $(INSTALL_PROGRAM) libcodec_celt.so $(sflcodecdir) install-libcodec_ilbc_so: libcodec_ilbc.so @@ -107,6 +117,8 @@ uninstall-libcodec_speex_nb_so: rm -f $(sflcodecdir)/libcodec_speex_nb.so uninstall-libcodec_speex_wb_so: rm -f $(sflcodecdir)/libcodec_speex_wb.so +uninstall-libcodec_speex_ub_so: + rm -f $(sflcodecdir)/libcodec_speex_ub.so rm -rf $(sflcodecdir) uninstall-libcodec_celt_so: libcodec_celt.so $(INSTALL_PROGRAM) libcodec_celt.so $(sflcodecdir) diff --git a/sflphone-common/src/audio/codecs/speexcodec_nb.cpp b/sflphone-common/src/audio/codecs/speexcodec_nb.cpp index 22089f0454c7f7654de0a4c3f57275c1056dfda4..96f7c63db46e2d3fe180a2c9ea51f95ffbaa9416 100644 --- a/sflphone-common/src/audio/codecs/speexcodec_nb.cpp +++ b/sflphone-common/src/audio/codecs/speexcodec_nb.cpp @@ -127,9 +127,11 @@ class Speex : public AudioCodec{ 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; } diff --git a/sflphone-common/src/audio/codecs/speexcodec_ub.cpp b/sflphone-common/src/audio/codecs/speexcodec_ub.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bce7e952e4ee37816e89d027d1ee9e72bcecffaf --- /dev/null +++ b/sflphone-common/src/audio/codecs/speexcodec_ub.cpp @@ -0,0 +1,158 @@ +/* + * 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 + * 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 "audiocodec.h" +#include <cstdio> +#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 = 32000; + _frameSize = 320; // 10 ms at 32 kHz + _channel = 1; + _bitrate = 0; + _bandwidth = 0; + initSpeex(); + } + + Speex( const Speex& ); + Speex& operator=(const Speex&); + + void initSpeex() { + + // int _samplingRate = 32000; + + // 8000 HZ --> Narrow-band mode + // TODO Manage the other modes + _speexModePtr = &speex_wb_mode; + // _speexModePtr = &speex_wb_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_SAMPLING_RATE,&_clockRate); + + speex_decoder_ctl(_speex_dec_state, SPEEX_GET_FRAME_SIZE, &_speex_frame_size); + +#ifdef HAVE_SPEEXDSP_LIB + + 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 the nuber of byte, not the number of sample + return _speex_frame_size * 2; + } + + virtual int codecEncode (unsigned char *dst, short *src, unsigned int size) + { + speex_bits_reset(&_speex_enc_bits); + +#ifdef HAVE_SPEEXDSP_LIB + + speex_preprocess_run(_preprocess_state, src); +#endif + + + speex_encode_int(_speex_enc_state, src, &_speex_enc_bits); + speex_bits_nbytes(&_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; + SpeexPreprocessState *_preprocess_state; +}; + +// the class factories +extern "C" AudioCodec* create() { + return new Speex(112); +} + +extern "C" void destroy(AudioCodec* a) { + delete a; +} + diff --git a/sflphone-common/src/audio/codecs/speexcodec_wb.cpp b/sflphone-common/src/audio/codecs/speexcodec_wb.cpp index 81d27bbcb0eebee7d7a75687bf82c0a8e410b9b6..dc93f39ec1a063732ef64b718d5fe48abf572f70 100644 --- a/sflphone-common/src/audio/codecs/speexcodec_wb.cpp +++ b/sflphone-common/src/audio/codecs/speexcodec_wb.cpp @@ -111,8 +111,9 @@ class Speex : public AudioCodec{ 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); @@ -128,9 +129,10 @@ class Speex : public AudioCodec{ speex_preprocess_run(_preprocess_state, src); #endif + printf("Codec::codecEncode() size %i\n", size); speex_encode_int(_speex_enc_state, src, &_speex_enc_bits); int nbBytes = speex_bits_write(&_speex_enc_bits, (char*)dst, size); - printf("Codec::codecEncode() nbBytes: %i \n",nbBytes); + printf("Codec::codecEncode() nbBytes %i\n", nbBytes); return nbBytes; }