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: 267492 $")
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 "asterisk/slin.h"
00043 #include "ex_lpc10.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 void extract_bits(INT32 *bits, unsigned char *c)
00079 {
00080 int x;
00081 for (x=0;x<LPC10_BITS_IN_COMPRESSED_FRAME;x++) {
00082 if (*c & (0x80 >> (x & 7)))
00083 bits[x] = 1;
00084 else
00085 bits[x] = 0;
00086 if ((x & 7) == 7)
00087 c++;
00088 }
00089 }
00090
00091
00092 static void build_bits(unsigned char *c, INT32 *bits)
00093 {
00094 unsigned char mask=0x80;
00095 int x;
00096 *c = 0;
00097 for (x=0;x<LPC10_BITS_IN_COMPRESSED_FRAME;x++) {
00098 if (bits[x])
00099 *c |= mask;
00100 mask = mask >> 1;
00101 if ((x % 8)==7) {
00102 c++;
00103 *c = 0;
00104 mask = 0x80;
00105 }
00106 }
00107 }
00108
00109 static int lpc10tolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
00110 {
00111 struct lpc10_coder_pvt *tmp = pvt->pvt;
00112 int16_t *dst = pvt->outbuf.i16;
00113 int len = 0;
00114
00115 while (len + LPC10_BYTES_IN_COMPRESSED_FRAME <= f->datalen) {
00116 int x;
00117 float tmpbuf[LPC10_SAMPLES_PER_FRAME];
00118 INT32 bits[LPC10_BITS_IN_COMPRESSED_FRAME];
00119 if (pvt->samples + LPC10_SAMPLES_PER_FRAME > BUFFER_SAMPLES) {
00120 ast_log(LOG_WARNING, "Out of buffer space\n");
00121 return -1;
00122 }
00123 extract_bits(bits, f->data.ptr + len);
00124 if (lpc10_decode(bits, tmpbuf, tmp->lpc10.dec)) {
00125 ast_log(LOG_WARNING, "Invalid lpc10 data\n");
00126 return -1;
00127 }
00128 for (x=0;x<LPC10_SAMPLES_PER_FRAME;x++) {
00129
00130 dst[pvt->samples + x] = (int16_t)(32768.0 * tmpbuf[x]);
00131 }
00132
00133 pvt->samples += LPC10_SAMPLES_PER_FRAME;
00134 pvt->datalen += 2*LPC10_SAMPLES_PER_FRAME;
00135 len += LPC10_BYTES_IN_COMPRESSED_FRAME;
00136 }
00137 if (len != f->datalen)
00138 printf("Decoded %d, expected %d\n", len, f->datalen);
00139 return 0;
00140 }
00141
00142 static int lintolpc10_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
00143 {
00144 struct lpc10_coder_pvt *tmp = pvt->pvt;
00145
00146
00147 if (pvt->samples + f->samples > BUFFER_SAMPLES) {
00148 ast_log(LOG_WARNING, "Out of buffer space\n");
00149 return -1;
00150 }
00151 memcpy(tmp->buf + pvt->samples, f->data.ptr, f->datalen);
00152 pvt->samples += f->samples;
00153 return 0;
00154 }
00155
00156 static struct ast_frame *lintolpc10_frameout(struct ast_trans_pvt *pvt)
00157 {
00158 struct lpc10_coder_pvt *tmp = pvt->pvt;
00159 int x;
00160 int datalen = 0;
00161 int samples = 0;
00162 float tmpbuf[LPC10_SAMPLES_PER_FRAME];
00163 INT32 bits[LPC10_BITS_IN_COMPRESSED_FRAME];
00164
00165 if (pvt->samples < LPC10_SAMPLES_PER_FRAME)
00166 return NULL;
00167 while (pvt->samples >= LPC10_SAMPLES_PER_FRAME) {
00168
00169 for (x=0;x<LPC10_SAMPLES_PER_FRAME;x++)
00170 tmpbuf[x] = (float)tmp->buf[x + samples] / 32768.0;
00171 lpc10_encode(tmpbuf, bits, tmp->lpc10.enc);
00172 build_bits(pvt->outbuf.uc + datalen, bits);
00173 datalen += LPC10_BYTES_IN_COMPRESSED_FRAME;
00174 samples += LPC10_SAMPLES_PER_FRAME;
00175 pvt->samples -= LPC10_SAMPLES_PER_FRAME;
00176
00177
00178 tmp->longer = 1 - tmp->longer;
00179 }
00180
00181 if (pvt->samples)
00182 memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2);
00183 return ast_trans_frameout(pvt, datalen, samples);
00184 }
00185
00186
00187 static void lpc10_destroy(struct ast_trans_pvt *arg)
00188 {
00189 struct lpc10_coder_pvt *pvt = arg->pvt;
00190
00191 ast_free(pvt->lpc10.enc);
00192 }
00193
00194 static struct ast_translator lpc10tolin = {
00195 .name = "lpc10tolin",
00196 .srcfmt = AST_FORMAT_LPC10,
00197 .dstfmt = AST_FORMAT_SLINEAR,
00198 .newpvt = lpc10_dec_new,
00199 .framein = lpc10tolin_framein,
00200 .destroy = lpc10_destroy,
00201 .sample = lpc10_sample,
00202 .desc_size = sizeof(struct lpc10_coder_pvt),
00203 .buffer_samples = BUFFER_SAMPLES,
00204 .buf_size = BUFFER_SAMPLES * 2,
00205 };
00206
00207 static struct ast_translator lintolpc10 = {
00208 .name = "lintolpc10",
00209 .srcfmt = AST_FORMAT_SLINEAR,
00210 .dstfmt = AST_FORMAT_LPC10,
00211 .newpvt = lpc10_enc_new,
00212 .framein = lintolpc10_framein,
00213 .frameout = lintolpc10_frameout,
00214 .destroy = lpc10_destroy,
00215 .sample = slin8_sample,
00216 .desc_size = sizeof(struct lpc10_coder_pvt),
00217 .buffer_samples = BUFFER_SAMPLES,
00218 .buf_size = LPC10_BYTES_IN_COMPRESSED_FRAME * (1 + BUFFER_SAMPLES / LPC10_SAMPLES_PER_FRAME),
00219 };
00220
00221 static int reload(void)
00222 {
00223 return AST_MODULE_LOAD_SUCCESS;
00224 }
00225
00226
00227 static int unload_module(void)
00228 {
00229 int res;
00230
00231 res = ast_unregister_translator(&lintolpc10);
00232 res |= ast_unregister_translator(&lpc10tolin);
00233
00234 return res;
00235 }
00236
00237 static int load_module(void)
00238 {
00239 int res;
00240
00241 res = ast_register_translator(&lpc10tolin);
00242 if (!res)
00243 res = ast_register_translator(&lintolpc10);
00244 else
00245 ast_unregister_translator(&lpc10tolin);
00246 if (res)
00247 return AST_MODULE_LOAD_FAILURE;
00248 return AST_MODULE_LOAD_SUCCESS;
00249 }
00250
00251 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "LPC10 2.4kbps Coder/Decoder",
00252 .load = load_module,
00253 .unload = unload_module,
00254 .reload = reload,
00255 );