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 #include "asterisk.h"
00031
00032 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 125386 $")
00033
00034 #include "asterisk/translate.h"
00035 #include "asterisk/config.h"
00036 #include "asterisk/module.h"
00037 #include "asterisk/utils.h"
00038
00039 #include "lpc10/lpc10.h"
00040
00041
00042 #include "slin_lpc10_ex.h"
00043 #include "lpc10_slin_ex.h"
00044
00045
00046
00047
00048
00049
00050 #define LPC10_BYTES_IN_COMPRESSED_FRAME (LPC10_BITS_IN_COMPRESSED_FRAME + 7)/8
00051
00052 #define BUFFER_SAMPLES 8000
00053
00054 struct lpc10_coder_pvt {
00055 union {
00056 struct lpc10_encoder_state *enc;
00057 struct lpc10_decoder_state *dec;
00058 } lpc10;
00059
00060 short buf[BUFFER_SAMPLES];
00061 int longer;
00062 };
00063
00064 static int lpc10_enc_new(struct ast_trans_pvt *pvt)
00065 {
00066 struct lpc10_coder_pvt *tmp = pvt->pvt;
00067
00068 return (tmp->lpc10.enc = create_lpc10_encoder_state()) ? 0 : -1;
00069 }
00070
00071 static int lpc10_dec_new(struct ast_trans_pvt *pvt)
00072 {
00073 struct lpc10_coder_pvt *tmp = pvt->pvt;
00074
00075 return (tmp->lpc10.dec = create_lpc10_decoder_state()) ? 0 : -1;
00076 }
00077
00078 static struct ast_frame *lintolpc10_sample(void)
00079 {
00080 static struct ast_frame f;
00081 f.frametype = AST_FRAME_VOICE;
00082 f.subclass = AST_FORMAT_SLINEAR;
00083 f.datalen = sizeof(slin_lpc10_ex);
00084
00085 f.samples = LPC10_SAMPLES_PER_FRAME;
00086 f.mallocd = 0;
00087 f.offset = 0;
00088 f.src = __PRETTY_FUNCTION__;
00089 f.data.ptr = slin_lpc10_ex;
00090 return &f;
00091 }
00092
00093 static struct ast_frame *lpc10tolin_sample(void)
00094 {
00095 static struct ast_frame f;
00096 f.frametype = AST_FRAME_VOICE;
00097 f.subclass = AST_FORMAT_LPC10;
00098 f.datalen = sizeof(lpc10_slin_ex);
00099
00100
00101 f.samples = LPC10_SAMPLES_PER_FRAME;
00102 f.mallocd = 0;
00103 f.offset = 0;
00104 f.src = __PRETTY_FUNCTION__;
00105 f.data.ptr = lpc10_slin_ex;
00106 return &f;
00107 }
00108
00109 static void extract_bits(INT32 *bits, unsigned char *c)
00110 {
00111 int x;
00112 for (x=0;x<LPC10_BITS_IN_COMPRESSED_FRAME;x++) {
00113 if (*c & (0x80 >> (x & 7)))
00114 bits[x] = 1;
00115 else
00116 bits[x] = 0;
00117 if ((x & 7) == 7)
00118 c++;
00119 }
00120 }
00121
00122
00123 static void build_bits(unsigned char *c, INT32 *bits)
00124 {
00125 unsigned char mask=0x80;
00126 int x;
00127 *c = 0;
00128 for (x=0;x<LPC10_BITS_IN_COMPRESSED_FRAME;x++) {
00129 if (bits[x])
00130 *c |= mask;
00131 mask = mask >> 1;
00132 if ((x % 8)==7) {
00133 c++;
00134 *c = 0;
00135 mask = 0x80;
00136 }
00137 }
00138 }
00139
00140 static int lpc10tolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
00141 {
00142 struct lpc10_coder_pvt *tmp = pvt->pvt;
00143 int16_t *dst = pvt->outbuf.i16;
00144 int len = 0;
00145
00146 while (len + LPC10_BYTES_IN_COMPRESSED_FRAME <= f->datalen) {
00147 int x;
00148 float tmpbuf[LPC10_SAMPLES_PER_FRAME];
00149 INT32 bits[LPC10_BITS_IN_COMPRESSED_FRAME];
00150 if (pvt->samples + LPC10_SAMPLES_PER_FRAME > BUFFER_SAMPLES) {
00151 ast_log(LOG_WARNING, "Out of buffer space\n");
00152 return -1;
00153 }
00154 extract_bits(bits, f->data.ptr + len);
00155 if (lpc10_decode(bits, tmpbuf, tmp->lpc10.dec)) {
00156 ast_log(LOG_WARNING, "Invalid lpc10 data\n");
00157 return -1;
00158 }
00159 for (x=0;x<LPC10_SAMPLES_PER_FRAME;x++) {
00160
00161 dst[pvt->samples + x] = (int16_t)(32768.0 * tmpbuf[x]);
00162 }
00163
00164 pvt->samples += LPC10_SAMPLES_PER_FRAME;
00165 pvt->datalen += 2*LPC10_SAMPLES_PER_FRAME;
00166 len += LPC10_BYTES_IN_COMPRESSED_FRAME;
00167 }
00168 if (len != f->datalen)
00169 printf("Decoded %d, expected %d\n", len, f->datalen);
00170 return 0;
00171 }
00172
00173 static int lintolpc10_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
00174 {
00175 struct lpc10_coder_pvt *tmp = pvt->pvt;
00176
00177
00178 if (pvt->samples + f->samples > BUFFER_SAMPLES) {
00179 ast_log(LOG_WARNING, "Out of buffer space\n");
00180 return -1;
00181 }
00182 memcpy(tmp->buf + pvt->samples, f->data.ptr, f->datalen);
00183 pvt->samples += f->samples;
00184 return 0;
00185 }
00186
00187 static struct ast_frame *lintolpc10_frameout(struct ast_trans_pvt *pvt)
00188 {
00189 struct lpc10_coder_pvt *tmp = pvt->pvt;
00190 int x;
00191 int datalen = 0;
00192 int samples = 0;
00193 float tmpbuf[LPC10_SAMPLES_PER_FRAME];
00194 INT32 bits[LPC10_BITS_IN_COMPRESSED_FRAME];
00195
00196 if (pvt->samples < LPC10_SAMPLES_PER_FRAME)
00197 return NULL;
00198 while (pvt->samples >= LPC10_SAMPLES_PER_FRAME) {
00199
00200 for (x=0;x<LPC10_SAMPLES_PER_FRAME;x++)
00201 tmpbuf[x] = (float)tmp->buf[x + samples] / 32768.0;
00202 lpc10_encode(tmpbuf, bits, tmp->lpc10.enc);
00203 build_bits(pvt->outbuf.uc + datalen, bits);
00204 datalen += LPC10_BYTES_IN_COMPRESSED_FRAME;
00205 samples += LPC10_SAMPLES_PER_FRAME;
00206 pvt->samples -= LPC10_SAMPLES_PER_FRAME;
00207
00208
00209 tmp->longer = 1 - tmp->longer;
00210 }
00211
00212 if (pvt->samples)
00213 memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2);
00214 return ast_trans_frameout(pvt, datalen, samples);
00215 }
00216
00217
00218 static void lpc10_destroy(struct ast_trans_pvt *arg)
00219 {
00220 struct lpc10_coder_pvt *pvt = arg->pvt;
00221
00222 ast_free(pvt->lpc10.enc);
00223 }
00224
00225 static struct ast_translator lpc10tolin = {
00226 .name = "lpc10tolin",
00227 .srcfmt = AST_FORMAT_LPC10,
00228 .dstfmt = AST_FORMAT_SLINEAR,
00229 .newpvt = lpc10_dec_new,
00230 .framein = lpc10tolin_framein,
00231 .destroy = lpc10_destroy,
00232 .sample = lpc10tolin_sample,
00233 .desc_size = sizeof(struct lpc10_coder_pvt),
00234 .buffer_samples = BUFFER_SAMPLES,
00235 .plc_samples = LPC10_SAMPLES_PER_FRAME,
00236 .buf_size = BUFFER_SAMPLES * 2,
00237 };
00238
00239 static struct ast_translator lintolpc10 = {
00240 .name = "lintolpc10",
00241 .srcfmt = AST_FORMAT_SLINEAR,
00242 .dstfmt = AST_FORMAT_LPC10,
00243 .newpvt = lpc10_enc_new,
00244 .framein = lintolpc10_framein,
00245 .frameout = lintolpc10_frameout,
00246 .destroy = lpc10_destroy,
00247 .sample = lintolpc10_sample,
00248 .desc_size = sizeof(struct lpc10_coder_pvt),
00249 .buffer_samples = BUFFER_SAMPLES,
00250 .buf_size = LPC10_BYTES_IN_COMPRESSED_FRAME * (1 + BUFFER_SAMPLES / LPC10_SAMPLES_PER_FRAME),
00251 };
00252
00253 static int parse_config(int reload)
00254 {
00255 struct ast_variable *var;
00256 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
00257 struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
00258 if (cfg == NULL)
00259 return 0;
00260 if (cfg == CONFIG_STATUS_FILEUNCHANGED)
00261 return 0;
00262 for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
00263 if (!strcasecmp(var->name, "genericplc")) {
00264 lpc10tolin.useplc = ast_true(var->value) ? 1 : 0;
00265 ast_verb(3, "codec_lpc10: %susing generic PLC\n",
00266 lpc10tolin.useplc ? "" : "not ");
00267 }
00268 }
00269 ast_config_destroy(cfg);
00270 return 0;
00271 }
00272
00273 static int reload(void)
00274 {
00275 if (parse_config(1))
00276 return AST_MODULE_LOAD_DECLINE;
00277 return AST_MODULE_LOAD_SUCCESS;
00278 }
00279
00280
00281 static int unload_module(void)
00282 {
00283 int res;
00284
00285 res = ast_unregister_translator(&lintolpc10);
00286 res |= ast_unregister_translator(&lpc10tolin);
00287
00288 return res;
00289 }
00290
00291 static int load_module(void)
00292 {
00293 int res;
00294
00295 if (parse_config(0))
00296 return AST_MODULE_LOAD_DECLINE;
00297 res = ast_register_translator(&lpc10tolin);
00298 if (!res)
00299 res = ast_register_translator(&lintolpc10);
00300 else
00301 ast_unregister_translator(&lpc10tolin);
00302 if (res)
00303 return AST_MODULE_LOAD_FAILURE;
00304 return AST_MODULE_LOAD_SUCCESS;
00305 }
00306
00307 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "LPC10 2.4kbps Coder/Decoder",
00308 .load = load_module,
00309 .unload = unload_module,
00310 .reload = reload,
00311 );