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