00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "asterisk.h"
00035
00036 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 379719 $")
00037
00038 #include "asterisk/translate.h"
00039 #include "asterisk/module.h"
00040 #include "asterisk/utils.h"
00041
00042 #ifdef ILBC_WEBRTC
00043 #include <ilbc.h>
00044 typedef WebRtc_UWord16 ilbc_bytes;
00045 typedef WebRtc_Word16 ilbc_block;
00046 #define BUF_TYPE i16
00047 #else
00048 #include "ilbc/iLBC_encode.h"
00049 #include "ilbc/iLBC_decode.h"
00050 typedef unsigned char ilbc_bytes;
00051 typedef float ilbc_block;
00052 #define BUF_TYPE uc
00053 #endif
00054
00055 #define USE_ILBC_ENHANCER 0
00056 #define ILBC_MS 30
00057
00058
00059 #define ILBC_FRAME_LEN 50
00060 #define ILBC_SAMPLES 240
00061 #define BUFFER_SAMPLES 8000
00062
00063
00064 #include "asterisk/slin.h"
00065 #include "ex_ilbc.h"
00066
00067 struct ilbc_coder_pvt {
00068 iLBC_Enc_Inst_t enc;
00069 iLBC_Dec_Inst_t dec;
00070
00071 int16_t buf[BUFFER_SAMPLES];
00072 };
00073
00074 static int lintoilbc_new(struct ast_trans_pvt *pvt)
00075 {
00076 struct ilbc_coder_pvt *tmp = pvt->pvt;
00077
00078 initEncode(&tmp->enc, ILBC_MS);
00079
00080 return 0;
00081 }
00082
00083 static int ilbctolin_new(struct ast_trans_pvt *pvt)
00084 {
00085 struct ilbc_coder_pvt *tmp = pvt->pvt;
00086
00087 initDecode(&tmp->dec, ILBC_MS, USE_ILBC_ENHANCER);
00088
00089 return 0;
00090 }
00091
00092
00093 static int ilbctolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
00094 {
00095 struct ilbc_coder_pvt *tmp = pvt->pvt;
00096 int plc_mode = 1;
00097
00098
00099 int x,i;
00100 int datalen = f->datalen;
00101 int16_t *dst = pvt->outbuf.i16;
00102 ilbc_block tmpf[ILBC_SAMPLES];
00103
00104 if (!f->data.ptr && datalen) {
00105 ast_debug(1, "issue 16070, ILIB ERROR. data = NULL datalen = %d src = %s\n", datalen, f->src ? f->src : "no src set");
00106 f->datalen = 0;
00107 datalen = 0;
00108 }
00109
00110 if (datalen == 0) {
00111 datalen = ILBC_FRAME_LEN;
00112 f->samples = ILBC_SAMPLES;
00113 plc_mode = 0;
00114 pvt->samples += ILBC_SAMPLES;
00115 }
00116
00117 if (datalen % ILBC_FRAME_LEN) {
00118 ast_log(LOG_WARNING, "Huh? An ilbc frame that isn't a multiple of 50 bytes long from %s (%d)?\n", f->src, datalen);
00119 return -1;
00120 }
00121
00122 for (x=0; x < datalen ; x += ILBC_FRAME_LEN) {
00123 if (pvt->samples + ILBC_SAMPLES > BUFFER_SAMPLES) {
00124 ast_log(LOG_WARNING, "Out of buffer space\n");
00125 return -1;
00126 }
00127 iLBC_decode(tmpf, plc_mode ? f->data.ptr + x : NULL, &tmp->dec, plc_mode);
00128 for ( i=0; i < ILBC_SAMPLES; i++)
00129 dst[pvt->samples + i] = tmpf[i];
00130 pvt->samples += ILBC_SAMPLES;
00131 pvt->datalen += 2*ILBC_SAMPLES;
00132 }
00133 return 0;
00134 }
00135
00136
00137 static int lintoilbc_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
00138 {
00139 struct ilbc_coder_pvt *tmp = pvt->pvt;
00140
00141
00142
00143
00144
00145 memcpy(tmp->buf + pvt->samples, f->data.ptr, f->datalen);
00146 pvt->samples += f->samples;
00147 return 0;
00148 }
00149
00150
00151 static struct ast_frame *lintoilbc_frameout(struct ast_trans_pvt *pvt)
00152 {
00153 struct ilbc_coder_pvt *tmp = pvt->pvt;
00154 int datalen = 0;
00155 int samples = 0;
00156
00157
00158 if (pvt->samples < ILBC_SAMPLES)
00159 return NULL;
00160 while (pvt->samples >= ILBC_SAMPLES) {
00161 ilbc_block tmpf[ILBC_SAMPLES];
00162 int i;
00163
00164
00165 for (i = 0 ; i < ILBC_SAMPLES ; i++)
00166 tmpf[i] = tmp->buf[samples + i];
00167 iLBC_encode( (ilbc_bytes*)pvt->outbuf.BUF_TYPE + datalen, tmpf, &tmp->enc);
00168
00169 datalen += ILBC_FRAME_LEN;
00170 samples += ILBC_SAMPLES;
00171 pvt->samples -= ILBC_SAMPLES;
00172 }
00173
00174
00175 if (pvt->samples)
00176 memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2);
00177
00178 return ast_trans_frameout(pvt, datalen, samples);
00179 }
00180
00181 static struct ast_translator ilbctolin = {
00182 .name = "ilbctolin",
00183 .newpvt = ilbctolin_new,
00184 .framein = ilbctolin_framein,
00185 .sample = ilbc_sample,
00186 .desc_size = sizeof(struct ilbc_coder_pvt),
00187 .buf_size = BUFFER_SAMPLES * 2,
00188 .native_plc = 1,
00189 };
00190
00191 static struct ast_translator lintoilbc = {
00192 .name = "lintoilbc",
00193 .newpvt = lintoilbc_new,
00194 .framein = lintoilbc_framein,
00195 .frameout = lintoilbc_frameout,
00196 .sample = slin8_sample,
00197 .desc_size = sizeof(struct ilbc_coder_pvt),
00198 .buf_size = (BUFFER_SAMPLES * ILBC_FRAME_LEN + ILBC_SAMPLES - 1) / ILBC_SAMPLES,
00199 };
00200
00201 static int unload_module(void)
00202 {
00203 int res;
00204
00205 res = ast_unregister_translator(&lintoilbc);
00206 res |= ast_unregister_translator(&ilbctolin);
00207
00208 return res;
00209 }
00210
00211 static int load_module(void)
00212 {
00213 int res;
00214
00215 ast_format_set(&ilbctolin.src_format, AST_FORMAT_ILBC, 0);
00216 ast_format_set(&ilbctolin.dst_format, AST_FORMAT_SLINEAR, 0);
00217
00218 ast_format_set(&lintoilbc.src_format, AST_FORMAT_SLINEAR, 0);
00219 ast_format_set(&lintoilbc.dst_format, AST_FORMAT_ILBC, 0);
00220
00221
00222 res = ast_register_translator(&ilbctolin);
00223 if (!res)
00224 res=ast_register_translator(&lintoilbc);
00225 else
00226 ast_unregister_translator(&ilbctolin);
00227 if (res)
00228 return AST_MODULE_LOAD_FAILURE;
00229 return AST_MODULE_LOAD_SUCCESS;
00230 }
00231
00232 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "iLBC Coder/Decoder");