mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-04 20:04:50 +00:00
codecs: Add Codec 2 mode 2400.
ASTERISK-26217 #close Change-Id: I1e45d8084683fab5f2b272bf35f4a149cea8b8d6
This commit is contained in:
@@ -4,6 +4,7 @@ COROSYNC=@PBX_COROSYNC@
|
|||||||
CRYPTO=@PBX_CRYPTO@
|
CRYPTO=@PBX_CRYPTO@
|
||||||
BFD=@PBX_BFD@
|
BFD=@PBX_BFD@
|
||||||
BISON=@PBX_BISON@
|
BISON=@PBX_BISON@
|
||||||
|
CODEC2=@PBX_CODEC2@
|
||||||
CURL=@PBX_CURL@
|
CURL=@PBX_CURL@
|
||||||
DAHDI=@PBX_DAHDI@
|
DAHDI=@PBX_DAHDI@
|
||||||
DLADDR=@PBX_DLADDR@
|
DLADDR=@PBX_DLADDR@
|
||||||
|
222
codecs/codec_codec2.c
Normal file
222
codecs/codec_codec2.c
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
/*
|
||||||
|
* Asterisk -- An open source telephony toolkit.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016, Alexander Traud
|
||||||
|
*
|
||||||
|
* Alexander Traud <pabstraud@compuserve.com>
|
||||||
|
*
|
||||||
|
* See http://www.asterisk.org for more information about
|
||||||
|
* the Asterisk project. Please do not directly contact
|
||||||
|
* any of the maintainers of this project for assistance;
|
||||||
|
* the project provides a web site, mailing lists and IRC
|
||||||
|
* channels for your use.
|
||||||
|
*
|
||||||
|
* This program is free software, distributed under the terms of
|
||||||
|
* the GNU General Public License Version 2. See the LICENSE file
|
||||||
|
* at the top of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! \file
|
||||||
|
*
|
||||||
|
* \brief Translate between signed linear and Codec 2
|
||||||
|
*
|
||||||
|
* \author Alexander Traud <pabstraud@compuserve.com>
|
||||||
|
*
|
||||||
|
* \note http://www.rowetel.com/codec2.html
|
||||||
|
*
|
||||||
|
* \ingroup codecs
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*** MODULEINFO
|
||||||
|
<depend>codec2</depend>
|
||||||
|
<support_level>core</support_level>
|
||||||
|
***/
|
||||||
|
|
||||||
|
#include "asterisk.h"
|
||||||
|
|
||||||
|
#include "asterisk/codec.h" /* for AST_MEDIA_TYPE_AUDIO */
|
||||||
|
#include "asterisk/frame.h" /* for ast_frame */
|
||||||
|
#include "asterisk/linkedlists.h" /* for AST_LIST_NEXT, etc */
|
||||||
|
#include "asterisk/logger.h" /* for ast_log, etc */
|
||||||
|
#include "asterisk/module.h"
|
||||||
|
#include "asterisk/rtp_engine.h" /* ast_rtp_engine_(un)load_format */
|
||||||
|
#include "asterisk/translate.h" /* for ast_trans_pvt, etc */
|
||||||
|
|
||||||
|
#include <codec2/codec2.h>
|
||||||
|
|
||||||
|
#define BUFFER_SAMPLES 8000
|
||||||
|
#define CODEC2_SAMPLES 160 /* consider codec2_samples_per_frame(.) */
|
||||||
|
#define CODEC2_FRAME_LEN 6 /* consider codec2_bits_per_frame(.) */
|
||||||
|
|
||||||
|
/* Sample frame data */
|
||||||
|
#include "asterisk/slin.h"
|
||||||
|
#include "ex_codec2.h"
|
||||||
|
|
||||||
|
struct codec2_translator_pvt {
|
||||||
|
struct CODEC2 *state; /* May be encoder or decoder */
|
||||||
|
int16_t buf[BUFFER_SAMPLES];
|
||||||
|
};
|
||||||
|
|
||||||
|
static int codec2_new(struct ast_trans_pvt *pvt)
|
||||||
|
{
|
||||||
|
struct codec2_translator_pvt *tmp = pvt->pvt;
|
||||||
|
|
||||||
|
tmp->state = codec2_create(CODEC2_MODE_2400);
|
||||||
|
|
||||||
|
if (!tmp->state) {
|
||||||
|
ast_log(LOG_ERROR, "Error creating Codec 2 conversion\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \brief decode and store in outbuf. */
|
||||||
|
static int codec2tolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
|
||||||
|
{
|
||||||
|
struct codec2_translator_pvt *tmp = pvt->pvt;
|
||||||
|
int x;
|
||||||
|
|
||||||
|
for (x = 0; x < f->datalen; x += CODEC2_FRAME_LEN) {
|
||||||
|
unsigned char *src = f->data.ptr + x;
|
||||||
|
int16_t *dst = pvt->outbuf.i16 + pvt->samples;
|
||||||
|
|
||||||
|
codec2_decode(tmp->state, dst, src);
|
||||||
|
|
||||||
|
pvt->samples += CODEC2_SAMPLES;
|
||||||
|
pvt->datalen += CODEC2_SAMPLES * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \brief store samples into working buffer for later decode */
|
||||||
|
static int lintocodec2_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
|
||||||
|
{
|
||||||
|
struct codec2_translator_pvt *tmp = pvt->pvt;
|
||||||
|
|
||||||
|
memcpy(tmp->buf + pvt->samples, f->data.ptr, f->datalen);
|
||||||
|
pvt->samples += f->samples;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \brief encode and produce a frame */
|
||||||
|
static struct ast_frame *lintocodec2_frameout(struct ast_trans_pvt *pvt)
|
||||||
|
{
|
||||||
|
struct codec2_translator_pvt *tmp = pvt->pvt;
|
||||||
|
struct ast_frame *result = NULL;
|
||||||
|
struct ast_frame *last = NULL;
|
||||||
|
int samples = 0; /* output samples */
|
||||||
|
|
||||||
|
while (pvt->samples >= CODEC2_SAMPLES) {
|
||||||
|
struct ast_frame *current;
|
||||||
|
|
||||||
|
/* Encode a frame of data */
|
||||||
|
codec2_encode(tmp->state, pvt->outbuf.uc, tmp->buf + samples);
|
||||||
|
|
||||||
|
samples += CODEC2_SAMPLES;
|
||||||
|
pvt->samples -= CODEC2_SAMPLES;
|
||||||
|
|
||||||
|
current = ast_trans_frameout(pvt, CODEC2_FRAME_LEN, CODEC2_SAMPLES);
|
||||||
|
|
||||||
|
if (!current) {
|
||||||
|
continue;
|
||||||
|
} else if (last) {
|
||||||
|
AST_LIST_NEXT(last, frame_list) = current;
|
||||||
|
} else {
|
||||||
|
result = current;
|
||||||
|
}
|
||||||
|
last = current;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move the data at the end of the buffer to the front */
|
||||||
|
if (samples) {
|
||||||
|
memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void codec2_destroy_stuff(struct ast_trans_pvt *pvt)
|
||||||
|
{
|
||||||
|
struct codec2_translator_pvt *tmp = pvt->pvt;
|
||||||
|
|
||||||
|
if (tmp->state) {
|
||||||
|
codec2_destroy(tmp->state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct ast_translator codec2tolin = {
|
||||||
|
.name = "codec2tolin",
|
||||||
|
.src_codec = {
|
||||||
|
.name = "codec2",
|
||||||
|
.type = AST_MEDIA_TYPE_AUDIO,
|
||||||
|
.sample_rate = 8000,
|
||||||
|
},
|
||||||
|
.dst_codec = {
|
||||||
|
.name = "slin",
|
||||||
|
.type = AST_MEDIA_TYPE_AUDIO,
|
||||||
|
.sample_rate = 8000,
|
||||||
|
},
|
||||||
|
.format = "slin",
|
||||||
|
.newpvt = codec2_new,
|
||||||
|
.framein = codec2tolin_framein,
|
||||||
|
.destroy = codec2_destroy_stuff,
|
||||||
|
.sample = codec2_sample,
|
||||||
|
.desc_size = sizeof(struct codec2_translator_pvt),
|
||||||
|
.buffer_samples = BUFFER_SAMPLES,
|
||||||
|
.buf_size = BUFFER_SAMPLES * 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct ast_translator lintocodec2 = {
|
||||||
|
.name = "lintocodec2",
|
||||||
|
.src_codec = {
|
||||||
|
.name = "slin",
|
||||||
|
.type = AST_MEDIA_TYPE_AUDIO,
|
||||||
|
.sample_rate = 8000,
|
||||||
|
},
|
||||||
|
.dst_codec = {
|
||||||
|
.name = "codec2",
|
||||||
|
.type = AST_MEDIA_TYPE_AUDIO,
|
||||||
|
.sample_rate = 8000,
|
||||||
|
},
|
||||||
|
.format = "codec2",
|
||||||
|
.newpvt = codec2_new,
|
||||||
|
.framein = lintocodec2_framein,
|
||||||
|
.frameout = lintocodec2_frameout,
|
||||||
|
.destroy = codec2_destroy_stuff,
|
||||||
|
.sample = slin8_sample,
|
||||||
|
.desc_size = sizeof(struct codec2_translator_pvt),
|
||||||
|
.buffer_samples = BUFFER_SAMPLES,
|
||||||
|
.buf_size = (BUFFER_SAMPLES * CODEC2_FRAME_LEN + CODEC2_SAMPLES - 1) / CODEC2_SAMPLES,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int unload_module(void)
|
||||||
|
{
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
res |= ast_rtp_engine_unload_format(ast_format_codec2);
|
||||||
|
res |= ast_unregister_translator(&lintocodec2);
|
||||||
|
res |= ast_unregister_translator(&codec2tolin);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int load_module(void)
|
||||||
|
{
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
res |= ast_register_translator(&codec2tolin);
|
||||||
|
res |= ast_register_translator(&lintocodec2);
|
||||||
|
res |= ast_rtp_engine_load_format(ast_format_codec2);
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
unload_module();
|
||||||
|
return AST_MODULE_LOAD_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return AST_MODULE_LOAD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Codec 2 Coder/Decoder");
|
32
codecs/ex_codec2.h
Normal file
32
codecs/ex_codec2.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/*! \file
|
||||||
|
* \brief 8-bit raw data
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016, Alexander Traud
|
||||||
|
*
|
||||||
|
* Distributed under the terms of the GNU General Public License
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "asterisk/format_cache.h" /* for ast_format_codec2 */
|
||||||
|
#include "asterisk/frame.h" /* for ast_frame, etc */
|
||||||
|
|
||||||
|
static uint8_t ex_codec2[] = {
|
||||||
|
0xea, 0xca, 0x14, 0x85, 0x91, 0x78,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct ast_frame *codec2_sample(void)
|
||||||
|
{
|
||||||
|
static struct ast_frame f = {
|
||||||
|
.frametype = AST_FRAME_VOICE,
|
||||||
|
.datalen = sizeof(ex_codec2),
|
||||||
|
.samples = CODEC2_SAMPLES,
|
||||||
|
.mallocd = 0,
|
||||||
|
.offset = 0,
|
||||||
|
.src = __PRETTY_FUNCTION__,
|
||||||
|
.data.ptr = ex_codec2,
|
||||||
|
};
|
||||||
|
|
||||||
|
f.subclass.format = ast_format_codec2;
|
||||||
|
|
||||||
|
return &f;
|
||||||
|
}
|
143
configure
vendored
143
configure
vendored
@@ -1152,6 +1152,10 @@ PBX_COROSYNC
|
|||||||
COROSYNC_DIR
|
COROSYNC_DIR
|
||||||
COROSYNC_INCLUDE
|
COROSYNC_INCLUDE
|
||||||
COROSYNC_LIB
|
COROSYNC_LIB
|
||||||
|
PBX_CODEC2
|
||||||
|
CODEC2_DIR
|
||||||
|
CODEC2_INCLUDE
|
||||||
|
CODEC2_LIB
|
||||||
PBX_CAP
|
PBX_CAP
|
||||||
CAP_DIR
|
CAP_DIR
|
||||||
CAP_INCLUDE
|
CAP_INCLUDE
|
||||||
@@ -1326,6 +1330,7 @@ with_bfd
|
|||||||
with_execinfo
|
with_execinfo
|
||||||
with_bluetooth
|
with_bluetooth
|
||||||
with_cap
|
with_cap
|
||||||
|
with_codec2
|
||||||
with_cpg
|
with_cpg
|
||||||
with_curses
|
with_curses
|
||||||
with_crypt
|
with_crypt
|
||||||
@@ -2065,6 +2070,7 @@ Optional Packages:
|
|||||||
--with-execinfo=PATH use Stack Backtrace files in PATH
|
--with-execinfo=PATH use Stack Backtrace files in PATH
|
||||||
--with-bluetooth=PATH use Bluetooth files in PATH
|
--with-bluetooth=PATH use Bluetooth files in PATH
|
||||||
--with-cap=PATH use POSIX 1.e capabilities files in PATH
|
--with-cap=PATH use POSIX 1.e capabilities files in PATH
|
||||||
|
--with-codec2=PATH use Codec 2 Audio Decoder/Encoder files in PATH
|
||||||
--with-cpg=PATH use Corosync files in PATH
|
--with-cpg=PATH use Corosync files in PATH
|
||||||
--with-curses=PATH use curses files in PATH
|
--with-curses=PATH use curses files in PATH
|
||||||
--with-crypt=PATH use password and data encryption files in PATH
|
--with-crypt=PATH use password and data encryption files in PATH
|
||||||
@@ -8988,6 +8994,38 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CODEC2_DESCRIP="Codec 2 Audio Decoder/Encoder"
|
||||||
|
CODEC2_OPTION="codec2"
|
||||||
|
PBX_CODEC2=0
|
||||||
|
|
||||||
|
# Check whether --with-codec2 was given.
|
||||||
|
if test "${with_codec2+set}" = set; then :
|
||||||
|
withval=$with_codec2;
|
||||||
|
case ${withval} in
|
||||||
|
n|no)
|
||||||
|
USE_CODEC2=no
|
||||||
|
# -1 is a magic value used by menuselect to know that the package
|
||||||
|
# was disabled, other than 'not found'
|
||||||
|
PBX_CODEC2=-1
|
||||||
|
;;
|
||||||
|
y|ye|yes)
|
||||||
|
ac_mandatory_list="${ac_mandatory_list} CODEC2"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
CODEC2_DIR="${withval}"
|
||||||
|
ac_mandatory_list="${ac_mandatory_list} CODEC2"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
COROSYNC_DESCRIP="Corosync"
|
COROSYNC_DESCRIP="Corosync"
|
||||||
COROSYNC_OPTION="cpg"
|
COROSYNC_OPTION="cpg"
|
||||||
PBX_COROSYNC=0
|
PBX_COROSYNC=0
|
||||||
@@ -30372,6 +30410,111 @@ fi
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if test "x${PBX_CODEC2}" != "x1" -a "${USE_CODEC2}" != "no"; then
|
||||||
|
pbxlibdir=""
|
||||||
|
# if --with-CODEC2=DIR has been specified, use it.
|
||||||
|
if test "x${CODEC2_DIR}" != "x"; then
|
||||||
|
if test -d ${CODEC2_DIR}/lib; then
|
||||||
|
pbxlibdir="-L${CODEC2_DIR}/lib"
|
||||||
|
else
|
||||||
|
pbxlibdir="-L${CODEC2_DIR}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
pbxfuncname="codec2_create"
|
||||||
|
if test "x${pbxfuncname}" = "x" ; then # empty lib, assume only headers
|
||||||
|
AST_CODEC2_FOUND=yes
|
||||||
|
else
|
||||||
|
ast_ext_lib_check_save_CFLAGS="${CFLAGS}"
|
||||||
|
CFLAGS="${CFLAGS} "
|
||||||
|
as_ac_Lib=`$as_echo "ac_cv_lib_codec2_${pbxfuncname}" | $as_tr_sh`
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lcodec2" >&5
|
||||||
|
$as_echo_n "checking for ${pbxfuncname} in -lcodec2... " >&6; }
|
||||||
|
if eval \${$as_ac_Lib+:} false; then :
|
||||||
|
$as_echo_n "(cached) " >&6
|
||||||
|
else
|
||||||
|
ac_check_lib_save_LIBS=$LIBS
|
||||||
|
LIBS="-lcodec2 ${pbxlibdir} $LIBS"
|
||||||
|
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||||
|
/* end confdefs.h. */
|
||||||
|
|
||||||
|
/* Override any GCC internal prototype to avoid an error.
|
||||||
|
Use char because int might match the return type of a GCC
|
||||||
|
builtin and then its argument prototype would still apply. */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
#endif
|
||||||
|
char ${pbxfuncname} ();
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
return ${pbxfuncname} ();
|
||||||
|
;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
_ACEOF
|
||||||
|
if ac_fn_c_try_link "$LINENO"; then :
|
||||||
|
eval "$as_ac_Lib=yes"
|
||||||
|
else
|
||||||
|
eval "$as_ac_Lib=no"
|
||||||
|
fi
|
||||||
|
rm -f core conftest.err conftest.$ac_objext \
|
||||||
|
conftest$ac_exeext conftest.$ac_ext
|
||||||
|
LIBS=$ac_check_lib_save_LIBS
|
||||||
|
fi
|
||||||
|
eval ac_res=\$$as_ac_Lib
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
|
||||||
|
$as_echo "$ac_res" >&6; }
|
||||||
|
if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
|
||||||
|
AST_CODEC2_FOUND=yes
|
||||||
|
else
|
||||||
|
AST_CODEC2_FOUND=no
|
||||||
|
fi
|
||||||
|
|
||||||
|
CFLAGS="${ast_ext_lib_check_save_CFLAGS}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# now check for the header.
|
||||||
|
if test "${AST_CODEC2_FOUND}" = "yes"; then
|
||||||
|
CODEC2_LIB="${pbxlibdir} -lcodec2 "
|
||||||
|
# if --with-CODEC2=DIR has been specified, use it.
|
||||||
|
if test "x${CODEC2_DIR}" != "x"; then
|
||||||
|
CODEC2_INCLUDE="-I${CODEC2_DIR}/include"
|
||||||
|
fi
|
||||||
|
CODEC2_INCLUDE="${CODEC2_INCLUDE} "
|
||||||
|
if test "xcodec2/codec2.h" = "x" ; then # no header, assume found
|
||||||
|
CODEC2_HEADER_FOUND="1"
|
||||||
|
else # check for the header
|
||||||
|
ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
|
||||||
|
CPPFLAGS="${CPPFLAGS} ${CODEC2_INCLUDE}"
|
||||||
|
ac_fn_c_check_header_mongrel "$LINENO" "codec2/codec2.h" "ac_cv_header_codec2_codec2_h" "$ac_includes_default"
|
||||||
|
if test "x$ac_cv_header_codec2_codec2_h" = xyes; then :
|
||||||
|
CODEC2_HEADER_FOUND=1
|
||||||
|
else
|
||||||
|
CODEC2_HEADER_FOUND=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
CPPFLAGS="${ast_ext_lib_check_saved_CPPFLAGS}"
|
||||||
|
fi
|
||||||
|
if test "x${CODEC2_HEADER_FOUND}" = "x0" ; then
|
||||||
|
CODEC2_LIB=""
|
||||||
|
CODEC2_INCLUDE=""
|
||||||
|
else
|
||||||
|
if test "x${pbxfuncname}" = "x" ; then # only checking headers -> no library
|
||||||
|
CODEC2_LIB=""
|
||||||
|
fi
|
||||||
|
PBX_CODEC2=1
|
||||||
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
#define HAVE_CODEC2 1
|
||||||
|
_ACEOF
|
||||||
|
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if test "x${PBX_COROSYNC}" != "x1" -a "${USE_COROSYNC}" != "no"; then
|
if test "x${PBX_COROSYNC}" != "x1" -a "${USE_COROSYNC}" != "no"; then
|
||||||
pbxlibdir=""
|
pbxlibdir=""
|
||||||
# if --with-COROSYNC=DIR has been specified, use it.
|
# if --with-COROSYNC=DIR has been specified, use it.
|
||||||
|
@@ -407,6 +407,7 @@ AST_EXT_LIB_SETUP([BFD], [Debug symbol decoding], [bfd])
|
|||||||
AST_EXT_LIB_SETUP([BKTR], [Stack Backtrace], [execinfo])
|
AST_EXT_LIB_SETUP([BKTR], [Stack Backtrace], [execinfo])
|
||||||
AST_EXT_LIB_SETUP([BLUETOOTH], [Bluetooth], [bluetooth])
|
AST_EXT_LIB_SETUP([BLUETOOTH], [Bluetooth], [bluetooth])
|
||||||
AST_EXT_LIB_SETUP([CAP], [POSIX 1.e capabilities], [cap])
|
AST_EXT_LIB_SETUP([CAP], [POSIX 1.e capabilities], [cap])
|
||||||
|
AST_EXT_LIB_SETUP([CODEC2], [Codec 2 Audio Decoder/Encoder], [codec2])
|
||||||
AST_EXT_LIB_SETUP([COROSYNC], [Corosync], [cpg])
|
AST_EXT_LIB_SETUP([COROSYNC], [Corosync], [cpg])
|
||||||
AST_EXT_LIB_SETUP_OPTIONAL([COROSYNC_CFG_STATE_TRACK], [A callback only in corosync 1.x], [COROSYNC], [cfg])
|
AST_EXT_LIB_SETUP_OPTIONAL([COROSYNC_CFG_STATE_TRACK], [A callback only in corosync 1.x], [COROSYNC], [cfg])
|
||||||
AST_EXT_LIB_SETUP([CURSES], [curses], [curses])
|
AST_EXT_LIB_SETUP([CURSES], [curses], [curses])
|
||||||
@@ -2336,6 +2337,8 @@ else
|
|||||||
AST_EXT_LIB_CHECK([RADIUS], [radiusclient-ng], [rc_read_config], [radiusclient-ng.h])
|
AST_EXT_LIB_CHECK([RADIUS], [radiusclient-ng], [rc_read_config], [radiusclient-ng.h])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AST_EXT_LIB_CHECK([CODEC2], [codec2], [codec2_create], [codec2/codec2.h])
|
||||||
|
|
||||||
AST_EXT_LIB_CHECK([COROSYNC], [cpg], [cpg_join], [corosync/cpg.h], [-lcfg])
|
AST_EXT_LIB_CHECK([COROSYNC], [cpg], [cpg_join], [corosync/cpg.h], [-lcfg])
|
||||||
AST_EXT_LIB_CHECK([COROSYNC_CFG_STATE_TRACK], [cfg], [corosync_cfg_state_track], [corosync/cfg.h], [-lcfg])
|
AST_EXT_LIB_CHECK([COROSYNC_CFG_STATE_TRACK], [cfg], [corosync_cfg_state_track], [corosync/cfg.h], [-lcfg])
|
||||||
|
|
||||||
|
@@ -142,6 +142,9 @@
|
|||||||
/* Define to 1 if you have the `closefrom' function. */
|
/* Define to 1 if you have the `closefrom' function. */
|
||||||
#undef HAVE_CLOSEFROM
|
#undef HAVE_CLOSEFROM
|
||||||
|
|
||||||
|
/* Define to 1 if you have the Codec 2 Audio Decoder/Encoder library. */
|
||||||
|
#undef HAVE_CODEC2
|
||||||
|
|
||||||
/* Define to 1 if you have the Corosync library. */
|
/* Define to 1 if you have the Corosync library. */
|
||||||
#undef HAVE_COROSYNC
|
#undef HAVE_COROSYNC
|
||||||
|
|
||||||
|
@@ -208,6 +208,11 @@ extern struct ast_format *ast_format_siren7;
|
|||||||
*/
|
*/
|
||||||
extern struct ast_format *ast_format_opus;
|
extern struct ast_format *ast_format_opus;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Built-in cached Codec 2 format.
|
||||||
|
*/
|
||||||
|
extern struct ast_format *ast_format_codec2;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Built-in cached t140 format.
|
* \brief Built-in cached t140 format.
|
||||||
*/
|
*/
|
||||||
|
@@ -107,6 +107,30 @@ static struct ast_codec g723 = {
|
|||||||
.get_length = g723_length,
|
.get_length = g723_length,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int codec2_samples(struct ast_frame *frame)
|
||||||
|
{
|
||||||
|
return 160 * (frame->datalen / 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int codec2_length(unsigned int samples)
|
||||||
|
{
|
||||||
|
return (samples / 160) * 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct ast_codec codec2 = {
|
||||||
|
.name = "codec2",
|
||||||
|
.description = "Codec 2",
|
||||||
|
.type = AST_MEDIA_TYPE_AUDIO,
|
||||||
|
.sample_rate = 8000,
|
||||||
|
.minimum_ms = 20,
|
||||||
|
.maximum_ms = 300,
|
||||||
|
.default_ms = 20,
|
||||||
|
.minimum_bytes = 6,
|
||||||
|
.samples_count = codec2_samples,
|
||||||
|
.get_length = codec2_length,
|
||||||
|
.smooth = 1,
|
||||||
|
};
|
||||||
|
|
||||||
static int none_samples(struct ast_frame *frame)
|
static int none_samples(struct ast_frame *frame)
|
||||||
{
|
{
|
||||||
return frame->datalen;
|
return frame->datalen;
|
||||||
@@ -863,6 +887,7 @@ int ast_codec_builtin_init(void)
|
|||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
|
res |= CODEC_REGISTER_AND_CACHE(codec2);
|
||||||
res |= CODEC_REGISTER_AND_CACHE(g723);
|
res |= CODEC_REGISTER_AND_CACHE(g723);
|
||||||
res |= CODEC_REGISTER_AND_CACHE(ulaw);
|
res |= CODEC_REGISTER_AND_CACHE(ulaw);
|
||||||
res |= CODEC_REGISTER_AND_CACHE(alaw);
|
res |= CODEC_REGISTER_AND_CACHE(alaw);
|
||||||
|
@@ -217,6 +217,11 @@ struct ast_format *ast_format_siren7;
|
|||||||
*/
|
*/
|
||||||
struct ast_format *ast_format_opus;
|
struct ast_format *ast_format_opus;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Built-in cached codec2 format.
|
||||||
|
*/
|
||||||
|
struct ast_format *ast_format_codec2;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Built-in cached t140 format.
|
* \brief Built-in cached t140 format.
|
||||||
*/
|
*/
|
||||||
@@ -328,6 +333,7 @@ static void format_cache_shutdown(void)
|
|||||||
ao2_replace(ast_format_testlaw, NULL);
|
ao2_replace(ast_format_testlaw, NULL);
|
||||||
ao2_replace(ast_format_g719, NULL);
|
ao2_replace(ast_format_g719, NULL);
|
||||||
ao2_replace(ast_format_opus, NULL);
|
ao2_replace(ast_format_opus, NULL);
|
||||||
|
ao2_replace(ast_format_codec2, NULL);
|
||||||
ao2_replace(ast_format_jpeg, NULL);
|
ao2_replace(ast_format_jpeg, NULL);
|
||||||
ao2_replace(ast_format_png, NULL);
|
ao2_replace(ast_format_png, NULL);
|
||||||
ao2_replace(ast_format_h261, NULL);
|
ao2_replace(ast_format_h261, NULL);
|
||||||
@@ -360,7 +366,9 @@ int ast_format_cache_init(void)
|
|||||||
|
|
||||||
static void set_cached_format(const char *name, struct ast_format *format)
|
static void set_cached_format(const char *name, struct ast_format *format)
|
||||||
{
|
{
|
||||||
if (!strcmp(name, "g723")) {
|
if (!strcmp(name, "codec2")) {
|
||||||
|
ao2_replace(ast_format_codec2, format);
|
||||||
|
} else if (!strcmp(name, "g723")) {
|
||||||
ao2_replace(ast_format_g723, format);
|
ao2_replace(ast_format_g723, format);
|
||||||
} else if (!strcmp(name, "ulaw")) {
|
} else if (!strcmp(name, "ulaw")) {
|
||||||
ao2_replace(ast_format_ulaw, format);
|
ao2_replace(ast_format_ulaw, format);
|
||||||
|
@@ -126,6 +126,9 @@ BFD_LIB=@BFD_LIB@
|
|||||||
BLUETOOTH_INCLUDE=@BLUETOOTH_INCLUDE@
|
BLUETOOTH_INCLUDE=@BLUETOOTH_INCLUDE@
|
||||||
BLUETOOTH_LIB=@BLUETOOTH_LIB@
|
BLUETOOTH_LIB=@BLUETOOTH_LIB@
|
||||||
|
|
||||||
|
CODEC2_INCLUDE=@CODEC2_INCLUDE@
|
||||||
|
CODEC2_LIB=@CODEC2_LIB@
|
||||||
|
|
||||||
CURL_INCLUDE=@CURL_INCLUDE@
|
CURL_INCLUDE=@CURL_INCLUDE@
|
||||||
CURL_LIB=@CURL_LIB@
|
CURL_LIB=@CURL_LIB@
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user