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