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