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: 125386 $")
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->datalen == 0) {
00121 f->datalen = ILBC_FRAME_LEN;
00122 f->samples = ILBC_SAMPLES;
00123 plc_mode = 0;
00124 pvt->samples += ILBC_SAMPLES;
00125 }
00126
00127 if (f->datalen % ILBC_FRAME_LEN) {
00128 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);
00129 return -1;
00130 }
00131
00132 for (x=0; x < f->datalen ; x += ILBC_FRAME_LEN) {
00133 if (pvt->samples + ILBC_SAMPLES > BUFFER_SAMPLES) {
00134 ast_log(LOG_WARNING, "Out of buffer space\n");
00135 return -1;
00136 }
00137 iLBC_decode(tmpf, plc_mode ? f->data.ptr + x : NULL, &tmp->dec, plc_mode);
00138 for ( i=0; i < ILBC_SAMPLES; i++)
00139 dst[pvt->samples + i] = tmpf[i];
00140 pvt->samples += ILBC_SAMPLES;
00141 pvt->datalen += 2*ILBC_SAMPLES;
00142 }
00143 return 0;
00144 }
00145
00146
00147 static int lintoilbc_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
00148 {
00149 struct ilbc_coder_pvt *tmp = pvt->pvt;
00150
00151
00152
00153
00154
00155 memcpy(tmp->buf + pvt->samples, f->data.ptr, f->datalen);
00156 pvt->samples += f->samples;
00157 return 0;
00158 }
00159
00160
00161 static struct ast_frame *lintoilbc_frameout(struct ast_trans_pvt *pvt)
00162 {
00163 struct ilbc_coder_pvt *tmp = pvt->pvt;
00164 int datalen = 0;
00165 int samples = 0;
00166
00167
00168 if (pvt->samples < ILBC_SAMPLES)
00169 return NULL;
00170 while (pvt->samples >= ILBC_SAMPLES) {
00171 float tmpf[ILBC_SAMPLES];
00172 int i;
00173
00174
00175 for (i = 0 ; i < ILBC_SAMPLES ; i++)
00176 tmpf[i] = tmp->buf[samples + i];
00177 iLBC_encode( pvt->outbuf.uc + datalen, tmpf, &tmp->enc);
00178
00179 datalen += ILBC_FRAME_LEN;
00180 samples += ILBC_SAMPLES;
00181 pvt->samples -= ILBC_SAMPLES;
00182 }
00183
00184
00185 if (pvt->samples)
00186 memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2);
00187
00188 return ast_trans_frameout(pvt, datalen, samples);
00189 }
00190
00191 static struct ast_translator ilbctolin = {
00192 .name = "ilbctolin",
00193 .srcfmt = AST_FORMAT_ILBC,
00194 .dstfmt = AST_FORMAT_SLINEAR,
00195 .newpvt = ilbctolin_new,
00196 .framein = ilbctolin_framein,
00197 .sample = ilbctolin_sample,
00198 .desc_size = sizeof(struct ilbc_coder_pvt),
00199 .buf_size = BUFFER_SAMPLES * 2,
00200 .native_plc = 1,
00201 };
00202
00203 static struct ast_translator lintoilbc = {
00204 .name = "lintoilbc",
00205 .srcfmt = AST_FORMAT_SLINEAR,
00206 .dstfmt = AST_FORMAT_ILBC,
00207 .newpvt = lintoilbc_new,
00208 .framein = lintoilbc_framein,
00209 .frameout = lintoilbc_frameout,
00210 .sample = lintoilbc_sample,
00211 .desc_size = sizeof(struct ilbc_coder_pvt),
00212 .buf_size = (BUFFER_SAMPLES * ILBC_FRAME_LEN + ILBC_SAMPLES - 1) / ILBC_SAMPLES,
00213 };
00214
00215 static int unload_module(void)
00216 {
00217 int res;
00218
00219 res = ast_unregister_translator(&lintoilbc);
00220 res |= ast_unregister_translator(&ilbctolin);
00221
00222 return res;
00223 }
00224
00225 static int load_module(void)
00226 {
00227 int res;
00228
00229 res = ast_register_translator(&ilbctolin);
00230 if (!res)
00231 res=ast_register_translator(&lintoilbc);
00232 else
00233 ast_unregister_translator(&ilbctolin);
00234 if (res)
00235 return AST_MODULE_LOAD_FAILURE;
00236 return AST_MODULE_LOAD_SUCCESS;
00237 }
00238
00239 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "iLBC Coder/Decoder");