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