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