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
00033
00034 #include "asterisk.h"
00035
00036 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 328209 $")
00037
00038 #include "asterisk/translate.h"
00039 #include "asterisk/config.h"
00040 #include "asterisk/module.h"
00041 #include "asterisk/utils.h"
00042
00043 #ifdef HAVE_GSM_HEADER
00044 #include "gsm.h"
00045 #elif defined(HAVE_GSM_GSM_HEADER)
00046 #include <gsm/gsm.h>
00047 #endif
00048
00049 #include "../formats/msgsm.h"
00050
00051 #define BUFFER_SAMPLES 8000
00052 #define GSM_SAMPLES 160
00053 #define GSM_FRAME_LEN 33
00054 #define MSGSM_FRAME_LEN 65
00055
00056
00057 #include "asterisk/slin.h"
00058 #include "ex_gsm.h"
00059
00060 struct gsm_translator_pvt {
00061 gsm gsm;
00062 int16_t buf[BUFFER_SAMPLES];
00063 };
00064
00065 static int gsm_new(struct ast_trans_pvt *pvt)
00066 {
00067 struct gsm_translator_pvt *tmp = pvt->pvt;
00068
00069 return (tmp->gsm = gsm_create()) ? 0 : -1;
00070 }
00071
00072
00073 static int gsmtolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
00074 {
00075 struct gsm_translator_pvt *tmp = pvt->pvt;
00076 int x;
00077 int16_t *dst = pvt->outbuf.i16;
00078
00079 int flen = (f->datalen % MSGSM_FRAME_LEN == 0) ?
00080 MSGSM_FRAME_LEN : GSM_FRAME_LEN;
00081
00082 for (x=0; x < f->datalen; x += flen) {
00083 unsigned char data[2 * GSM_FRAME_LEN];
00084 unsigned char *src;
00085 int len;
00086 if (flen == MSGSM_FRAME_LEN) {
00087 len = 2*GSM_SAMPLES;
00088 src = data;
00089
00090
00091
00092
00093 conv65(f->data.ptr + x, data);
00094 } else {
00095 len = GSM_SAMPLES;
00096 src = f->data.ptr + x;
00097 }
00098
00099 if (pvt->samples + len > BUFFER_SAMPLES) {
00100 ast_log(LOG_WARNING, "Out of buffer space\n");
00101 return -1;
00102 }
00103 if (gsm_decode(tmp->gsm, src, dst + pvt->samples)) {
00104 ast_log(LOG_WARNING, "Invalid GSM data (1)\n");
00105 return -1;
00106 }
00107 pvt->samples += GSM_SAMPLES;
00108 pvt->datalen += 2 * GSM_SAMPLES;
00109 if (flen == MSGSM_FRAME_LEN) {
00110 if (gsm_decode(tmp->gsm, data + GSM_FRAME_LEN, dst + pvt->samples)) {
00111 ast_log(LOG_WARNING, "Invalid GSM data (2)\n");
00112 return -1;
00113 }
00114 pvt->samples += GSM_SAMPLES;
00115 pvt->datalen += 2 * GSM_SAMPLES;
00116 }
00117 }
00118 return 0;
00119 }
00120
00121
00122 static int lintogsm_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
00123 {
00124 struct gsm_translator_pvt *tmp = pvt->pvt;
00125
00126
00127
00128
00129 if (pvt->samples + f->samples > BUFFER_SAMPLES) {
00130 ast_log(LOG_WARNING, "Out of buffer space\n");
00131 return -1;
00132 }
00133 memcpy(tmp->buf + pvt->samples, f->data.ptr, f->datalen);
00134 pvt->samples += f->samples;
00135 return 0;
00136 }
00137
00138
00139 static struct ast_frame *lintogsm_frameout(struct ast_trans_pvt *pvt)
00140 {
00141 struct gsm_translator_pvt *tmp = pvt->pvt;
00142 int datalen = 0;
00143 int samples = 0;
00144
00145
00146 if (pvt->samples < GSM_SAMPLES)
00147 return NULL;
00148 while (pvt->samples >= GSM_SAMPLES) {
00149
00150 gsm_encode(tmp->gsm, tmp->buf + samples, (gsm_byte *) pvt->outbuf.c + datalen);
00151 datalen += GSM_FRAME_LEN;
00152 samples += GSM_SAMPLES;
00153 pvt->samples -= GSM_SAMPLES;
00154 }
00155
00156
00157 if (pvt->samples)
00158 memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2);
00159
00160 return ast_trans_frameout(pvt, datalen, samples);
00161 }
00162
00163 static void gsm_destroy_stuff(struct ast_trans_pvt *pvt)
00164 {
00165 struct gsm_translator_pvt *tmp = pvt->pvt;
00166 if (tmp->gsm)
00167 gsm_destroy(tmp->gsm);
00168 }
00169
00170 static struct ast_translator gsmtolin = {
00171 .name = "gsmtolin",
00172 .srcfmt = AST_FORMAT_GSM,
00173 .dstfmt = AST_FORMAT_SLINEAR,
00174 .newpvt = gsm_new,
00175 .framein = gsmtolin_framein,
00176 .destroy = gsm_destroy_stuff,
00177 .sample = gsm_sample,
00178 .buffer_samples = BUFFER_SAMPLES,
00179 .buf_size = BUFFER_SAMPLES * 2,
00180 .desc_size = sizeof (struct gsm_translator_pvt ),
00181 };
00182
00183 static struct ast_translator lintogsm = {
00184 .name = "lintogsm",
00185 .srcfmt = AST_FORMAT_SLINEAR,
00186 .dstfmt = AST_FORMAT_GSM,
00187 .newpvt = gsm_new,
00188 .framein = lintogsm_framein,
00189 .frameout = lintogsm_frameout,
00190 .destroy = gsm_destroy_stuff,
00191 .sample = slin8_sample,
00192 .desc_size = sizeof (struct gsm_translator_pvt ),
00193 .buf_size = (BUFFER_SAMPLES * GSM_FRAME_LEN + GSM_SAMPLES - 1)/GSM_SAMPLES,
00194 };
00195
00196
00197 static int reload(void)
00198 {
00199 return AST_MODULE_LOAD_SUCCESS;
00200 }
00201
00202 static int unload_module(void)
00203 {
00204 int res;
00205
00206 res = ast_unregister_translator(&lintogsm);
00207 if (!res)
00208 res = ast_unregister_translator(&gsmtolin);
00209
00210 return res;
00211 }
00212
00213 static int load_module(void)
00214 {
00215 int res;
00216
00217 res = ast_register_translator(&gsmtolin);
00218 if (!res)
00219 res=ast_register_translator(&lintogsm);
00220 else
00221 ast_unregister_translator(&gsmtolin);
00222 if (res)
00223 return AST_MODULE_LOAD_FAILURE;
00224 return AST_MODULE_LOAD_SUCCESS;
00225 }
00226
00227 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "GSM Coder/Decoder",
00228 .load = load_module,
00229 .unload = unload_module,
00230 .reload = reload,
00231 );