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