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: 279472 $")
00033
00034 #include "asterisk/mod_format.h"
00035 #include "asterisk/module.h"
00036 #include "asterisk/endian.h"
00037
00038 #include "msgsm.h"
00039
00040
00041
00042
00043
00044 #define GSM_FRAME_SIZE 33
00045 #define MSGSM_FRAME_SIZE 65
00046 #define MSGSM_DATA_OFFSET 60
00047 #define GSM_SAMPLES 160
00048 #define MSGSM_SAMPLES (2*GSM_SAMPLES)
00049
00050
00051 static char msgsm_silence[] =
00052 {0x48,0x17,0xD6,0x84,0x02,0x80,0x24,0x49,0x92,0x24,0x89,0x02,0x80,0x24,0x49
00053 ,0x92,0x24,0x89,0x02,0x80,0x24,0x49,0x92,0x24,0x89,0x02,0x80,0x24,0x49,0x92
00054 ,0x24,0x09,0x82,0x74,0x61,0x4D,0x28,0x00,0x48,0x92,0x24,0x49,0x92,0x28,0x00
00055 ,0x48,0x92,0x24,0x49,0x92,0x28,0x00,0x48,0x92,0x24,0x49,0x92,0x28,0x00,0x48
00056 ,0x92,0x24,0x49,0x92,0x00};
00057
00058
00059 struct wavg_desc {
00060
00061
00062 int secondhalf;
00063 };
00064
00065 #if __BYTE_ORDER == __LITTLE_ENDIAN
00066 #define htoll(b) (b)
00067 #define htols(b) (b)
00068 #define ltohl(b) (b)
00069 #define ltohs(b) (b)
00070 #else
00071 #if __BYTE_ORDER == __BIG_ENDIAN
00072 #define htoll(b) \
00073 (((((b) ) & 0xFF) << 24) | \
00074 ((((b) >> 8) & 0xFF) << 16) | \
00075 ((((b) >> 16) & 0xFF) << 8) | \
00076 ((((b) >> 24) & 0xFF) ))
00077 #define htols(b) \
00078 (((((b) ) & 0xFF) << 8) | \
00079 ((((b) >> 8) & 0xFF) ))
00080 #define ltohl(b) htoll(b)
00081 #define ltohs(b) htols(b)
00082 #else
00083 #error "Endianess not defined"
00084 #endif
00085 #endif
00086
00087
00088 static int check_header(FILE *f)
00089 {
00090 int type, size, formtype;
00091 int fmt, hsize, fact;
00092 short format, chans;
00093 int freq;
00094 int data;
00095 if (fread(&type, 1, 4, f) != 4) {
00096 ast_log(LOG_WARNING, "Read failed (type)\n");
00097 return -1;
00098 }
00099 if (fread(&size, 1, 4, f) != 4) {
00100 ast_log(LOG_WARNING, "Read failed (size)\n");
00101 return -1;
00102 }
00103 size = ltohl(size);
00104 if (fread(&formtype, 1, 4, f) != 4) {
00105 ast_log(LOG_WARNING, "Read failed (formtype)\n");
00106 return -1;
00107 }
00108 if (memcmp(&type, "RIFF", 4)) {
00109 ast_log(LOG_WARNING, "Does not begin with RIFF\n");
00110 return -1;
00111 }
00112 if (memcmp(&formtype, "WAVE", 4)) {
00113 ast_log(LOG_WARNING, "Does not contain WAVE\n");
00114 return -1;
00115 }
00116 if (fread(&fmt, 1, 4, f) != 4) {
00117 ast_log(LOG_WARNING, "Read failed (fmt)\n");
00118 return -1;
00119 }
00120 if (memcmp(&fmt, "fmt ", 4)) {
00121 ast_log(LOG_WARNING, "Does not say fmt\n");
00122 return -1;
00123 }
00124 if (fread(&hsize, 1, 4, f) != 4) {
00125 ast_log(LOG_WARNING, "Read failed (formtype)\n");
00126 return -1;
00127 }
00128 if (ltohl(hsize) != 20) {
00129 ast_log(LOG_WARNING, "Unexpected header size %d\n", ltohl(hsize));
00130 return -1;
00131 }
00132 if (fread(&format, 1, 2, f) != 2) {
00133 ast_log(LOG_WARNING, "Read failed (format)\n");
00134 return -1;
00135 }
00136 if (ltohs(format) != 49) {
00137 ast_log(LOG_WARNING, "Not a GSM file %d\n", ltohs(format));
00138 return -1;
00139 }
00140 if (fread(&chans, 1, 2, f) != 2) {
00141 ast_log(LOG_WARNING, "Read failed (format)\n");
00142 return -1;
00143 }
00144 if (ltohs(chans) != 1) {
00145 ast_log(LOG_WARNING, "Not in mono %d\n", ltohs(chans));
00146 return -1;
00147 }
00148 if (fread(&freq, 1, 4, f) != 4) {
00149 ast_log(LOG_WARNING, "Read failed (freq)\n");
00150 return -1;
00151 }
00152 if (ltohl(freq) != DEFAULT_SAMPLE_RATE) {
00153 ast_log(LOG_WARNING, "Unexpected frequency %d\n", ltohl(freq));
00154 return -1;
00155 }
00156
00157 if (fread(&freq, 1, 4, f) != 4) {
00158 ast_log(LOG_WARNING, "Read failed (X_1)\n");
00159 return -1;
00160 }
00161
00162 if (fread(&freq, 1, 4, f) != 4) {
00163 ast_log(LOG_WARNING, "Read failed (X_2/X_3)\n");
00164 return -1;
00165 }
00166
00167 if (fread(&freq, 1, 4, f) != 4) {
00168 ast_log(LOG_WARNING, "Read failed (Y_1)\n");
00169 return -1;
00170 }
00171
00172 if (fread(&fact, 1, 4, f) != 4) {
00173 ast_log(LOG_WARNING, "Read failed (fact)\n");
00174 return -1;
00175 }
00176 if (memcmp(&fact, "fact", 4)) {
00177 ast_log(LOG_WARNING, "Does not say fact\n");
00178 return -1;
00179 }
00180
00181 if (fread(&fact, 1, 4, f) != 4) {
00182 ast_log(LOG_WARNING, "Read failed (fact header)\n");
00183 return -1;
00184 }
00185 if (fread(&fact, 1, 4, f) != 4) {
00186 ast_log(LOG_WARNING, "Read failed (fact value)\n");
00187 return -1;
00188 }
00189
00190 if (fread(&data, 1, 4, f) != 4) {
00191 ast_log(LOG_WARNING, "Read failed (data)\n");
00192 return -1;
00193 }
00194 if (memcmp(&data, "data", 4)) {
00195 ast_log(LOG_WARNING, "Does not say data\n");
00196 return -1;
00197 }
00198
00199 if (fread(&data, 1, 4, f) != 4) {
00200 ast_log(LOG_WARNING, "Read failed (data)\n");
00201 return -1;
00202 }
00203 return 0;
00204 }
00205
00206 static int update_header(FILE *f)
00207 {
00208 off_t cur,end,bytes;
00209 int datalen, filelen, samples;
00210
00211 cur = ftello(f);
00212 fseek(f, 0, SEEK_END);
00213 end = ftello(f);
00214
00215 bytes = end - MSGSM_DATA_OFFSET;
00216 samples = htoll(bytes / MSGSM_FRAME_SIZE * MSGSM_SAMPLES);
00217 datalen = htoll(bytes);
00218 filelen = htoll(MSGSM_DATA_OFFSET - 8 + bytes);
00219 if (cur < 0) {
00220 ast_log(LOG_WARNING, "Unable to find our position\n");
00221 return -1;
00222 }
00223 if (fseek(f, 4, SEEK_SET)) {
00224 ast_log(LOG_WARNING, "Unable to set our position\n");
00225 return -1;
00226 }
00227 if (fwrite(&filelen, 1, 4, f) != 4) {
00228 ast_log(LOG_WARNING, "Unable to write file size\n");
00229 return -1;
00230 }
00231 if (fseek(f, 48, SEEK_SET)) {
00232 ast_log(LOG_WARNING, "Unable to set our position\n");
00233 return -1;
00234 }
00235 if (fwrite(&samples, 1, 4, f) != 4) {
00236 ast_log(LOG_WARNING, "Unable to write samples\n");
00237 return -1;
00238 }
00239 if (fseek(f, 56, SEEK_SET)) {
00240 ast_log(LOG_WARNING, "Unable to set our position\n");
00241 return -1;
00242 }
00243 if (fwrite(&datalen, 1, 4, f) != 4) {
00244 ast_log(LOG_WARNING, "Unable to write datalen\n");
00245 return -1;
00246 }
00247 if (fseeko(f, cur, SEEK_SET)) {
00248 ast_log(LOG_WARNING, "Unable to return to position\n");
00249 return -1;
00250 }
00251 return 0;
00252 }
00253
00254 static int write_header(FILE *f)
00255 {
00256
00257 unsigned int sample_rate = htoll(8000);
00258
00259 unsigned int byte_sample_rate = htoll(1625);
00260
00261 unsigned int fmtsize = htoll(20);
00262
00263 unsigned short fmt = htols(49);
00264
00265 unsigned short chans = htols(1);
00266
00267 unsigned int block_align = htoll(MSGSM_FRAME_SIZE);
00268
00269 unsigned short bits_per_sample = htols(2);
00270
00271 unsigned short extra_format = htols(MSGSM_SAMPLES);
00272
00273 unsigned int factsize = htoll(4);
00274
00275 unsigned int num_samples = htoll(0);
00276
00277 unsigned int size = htoll(0);
00278
00279
00280
00281 if (fwrite("RIFF", 1, 4, f) != 4) {
00282 ast_log(LOG_WARNING, "Unable to write header\n");
00283 return -1;
00284 }
00285
00286 if (fwrite(&size, 1, 4, f) != 4) {
00287 ast_log(LOG_WARNING, "Unable to write header\n");
00288 return -1;
00289 }
00290
00291 if (fwrite("WAVE", 1, 4, f) != 4) {
00292 ast_log(LOG_WARNING, "Unable to write header\n");
00293 return -1;
00294 }
00295
00296 if (fwrite("fmt ", 1, 4, f) != 4) {
00297 ast_log(LOG_WARNING, "Unable to write header\n");
00298 return -1;
00299 }
00300
00301 if (fwrite(&fmtsize, 1, 4, f) != 4) {
00302 ast_log(LOG_WARNING, "Unable to write header\n");
00303 return -1;
00304 }
00305
00306 if (fwrite(&fmt, 1, 2, f) != 2) {
00307 ast_log(LOG_WARNING, "Unable to write header\n");
00308 return -1;
00309 }
00310
00311 if (fwrite(&chans, 1, 2, f) != 2) {
00312 ast_log(LOG_WARNING, "Unable to write header\n");
00313 return -1;
00314 }
00315
00316 if (fwrite(&sample_rate, 1, 4, f) != 4) {
00317 ast_log(LOG_WARNING, "Unable to write header\n");
00318 return -1;
00319 }
00320
00321 if (fwrite(&byte_sample_rate, 1, 4, f) != 4) {
00322 ast_log(LOG_WARNING, "Unable to write header\n");
00323 return -1;
00324 }
00325
00326 if (fwrite(&block_align, 1, 4, f) != 4) {
00327 ast_log(LOG_WARNING, "Unable to write header\n");
00328 return -1;
00329 }
00330
00331 if (fwrite(&bits_per_sample, 1, 2, f) != 2) {
00332 ast_log(LOG_WARNING, "Unable to write header\n");
00333 return -1;
00334 }
00335
00336 if (fwrite(&extra_format, 1, 2, f) != 2) {
00337 ast_log(LOG_WARNING, "Unable to write header\n");
00338 return -1;
00339 }
00340
00341 if (fwrite("fact", 1, 4, f) != 4) {
00342 ast_log(LOG_WARNING, "Unable to write header\n");
00343 return -1;
00344 }
00345
00346 if (fwrite(&factsize, 1, 4, f) != 4) {
00347 ast_log(LOG_WARNING, "Unable to write header\n");
00348 return -1;
00349 }
00350
00351 if (fwrite(&num_samples, 1, 4, f) != 4) {
00352 ast_log(LOG_WARNING, "Unable to write header\n");
00353 return -1;
00354 }
00355
00356 if (fwrite("data", 1, 4, f) != 4) {
00357 ast_log(LOG_WARNING, "Unable to write header\n");
00358 return -1;
00359 }
00360
00361 if (fwrite(&size, 1, 4, f) != 4) {
00362 ast_log(LOG_WARNING, "Unable to write header\n");
00363 return -1;
00364 }
00365 return 0;
00366 }
00367
00368 static int wav_open(struct ast_filestream *s)
00369 {
00370
00371
00372
00373 struct wavg_desc *fs = (struct wavg_desc *)s->_private;
00374
00375 if (check_header(s->f))
00376 return -1;
00377 fs->secondhalf = 0;
00378 return 0;
00379 }
00380
00381 static int wav_rewrite(struct ast_filestream *s, const char *comment)
00382 {
00383
00384
00385
00386
00387 if (write_header(s->f))
00388 return -1;
00389 return 0;
00390 }
00391
00392 static struct ast_frame *wav_read(struct ast_filestream *s, int *whennext)
00393 {
00394
00395 struct wavg_desc *fs = (struct wavg_desc *)s->_private;
00396
00397 s->fr.frametype = AST_FRAME_VOICE;
00398 s->fr.subclass.codec = AST_FORMAT_GSM;
00399 s->fr.offset = AST_FRIENDLY_OFFSET;
00400 s->fr.samples = GSM_SAMPLES;
00401 s->fr.mallocd = 0;
00402 AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, GSM_FRAME_SIZE);
00403 if (fs->secondhalf) {
00404
00405 s->fr.data.ptr = (char *)s->fr.data.ptr + GSM_FRAME_SIZE;
00406 s->fr.offset += GSM_FRAME_SIZE;
00407 } else {
00408
00409 unsigned char msdata[MSGSM_FRAME_SIZE];
00410 int res;
00411
00412 if ((res = fread(msdata, 1, MSGSM_FRAME_SIZE, s->f)) != MSGSM_FRAME_SIZE) {
00413 if (res && (res != 1))
00414 ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
00415 return NULL;
00416 }
00417
00418 conv65(msdata, s->fr.data.ptr);
00419 }
00420 fs->secondhalf = !fs->secondhalf;
00421 *whennext = GSM_SAMPLES;
00422 return &s->fr;
00423 }
00424
00425 static int wav_write(struct ast_filestream *s, struct ast_frame *f)
00426 {
00427 int len;
00428 int size;
00429 struct wavg_desc *fs = (struct wavg_desc *)s->_private;
00430
00431 if (f->frametype != AST_FRAME_VOICE) {
00432 ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
00433 return -1;
00434 }
00435 if (f->subclass.codec != AST_FORMAT_GSM) {
00436 ast_log(LOG_WARNING, "Asked to write non-GSM frame (%s)!\n", ast_getformatname(f->subclass.codec));
00437 return -1;
00438 }
00439
00440
00441
00442 if (!(f->datalen % MSGSM_FRAME_SIZE)) {
00443 size = MSGSM_FRAME_SIZE;
00444 fs->secondhalf = 0;
00445 } else {
00446 size = GSM_FRAME_SIZE;
00447 }
00448 for (len = 0; len < f->datalen ; len += size) {
00449 int res;
00450 unsigned char *src, msdata[MSGSM_FRAME_SIZE];
00451 if (fs->secondhalf) {
00452 memcpy(s->buf + GSM_FRAME_SIZE, f->data.ptr + len, GSM_FRAME_SIZE);
00453 conv66((unsigned char *) s->buf, msdata);
00454 src = msdata;
00455 fs->secondhalf = 0;
00456 } else if (size == GSM_FRAME_SIZE) {
00457 memcpy(s->buf, f->data.ptr + len, GSM_FRAME_SIZE);
00458 src = NULL;
00459 fs->secondhalf = 1;
00460 } else {
00461 src = f->data.ptr + len;
00462 }
00463 if (src && (res = fwrite(src, 1, MSGSM_FRAME_SIZE, s->f)) != MSGSM_FRAME_SIZE) {
00464 ast_log(LOG_WARNING, "Bad write (%d/65): %s\n", res, strerror(errno));
00465 return -1;
00466 }
00467 update_header(s->f);
00468 }
00469 return 0;
00470 }
00471
00472 static int wav_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
00473 {
00474 off_t offset=0, distance, max;
00475 struct wavg_desc *s = (struct wavg_desc *)fs->_private;
00476
00477 off_t min = MSGSM_DATA_OFFSET;
00478 off_t cur = ftello(fs->f);
00479 fseek(fs->f, 0, SEEK_END);
00480 max = ftello(fs->f);
00481
00482 distance = (sample_offset/MSGSM_SAMPLES) * MSGSM_FRAME_SIZE;
00483 if (whence == SEEK_SET)
00484 offset = distance + min;
00485 else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
00486 offset = distance + cur;
00487 else if (whence == SEEK_END)
00488 offset = max - distance;
00489
00490 if (offset < min)
00491 offset = min;
00492 if (whence != SEEK_FORCECUR) {
00493 if (offset > max)
00494 offset = max;
00495 } else if (offset > max) {
00496 int i;
00497 fseek(fs->f, 0, SEEK_END);
00498 for (i=0; i< (offset - max) / MSGSM_FRAME_SIZE; i++) {
00499 if (!fwrite(msgsm_silence, 1, MSGSM_FRAME_SIZE, fs->f)) {
00500 ast_log(LOG_WARNING, "fwrite() failed: %s\n", strerror(errno));
00501 }
00502 }
00503 }
00504 s->secondhalf = 0;
00505 return fseeko(fs->f, offset, SEEK_SET);
00506 }
00507
00508 static int wav_trunc(struct ast_filestream *fs)
00509 {
00510 if (ftruncate(fileno(fs->f), ftello(fs->f)))
00511 return -1;
00512 return update_header(fs->f);
00513 }
00514
00515 static off_t wav_tell(struct ast_filestream *fs)
00516 {
00517 off_t offset;
00518 offset = ftello(fs->f);
00519
00520
00521 return (offset - MSGSM_DATA_OFFSET)/MSGSM_FRAME_SIZE*MSGSM_SAMPLES;
00522 }
00523
00524 static const struct ast_format wav49_f = {
00525 .name = "wav49",
00526 .exts = "WAV|wav49",
00527 .format = AST_FORMAT_GSM,
00528 .open = wav_open,
00529 .rewrite = wav_rewrite,
00530 .write = wav_write,
00531 .seek = wav_seek,
00532 .trunc = wav_trunc,
00533 .tell = wav_tell,
00534 .read = wav_read,
00535 .buf_size = 2*GSM_FRAME_SIZE + AST_FRIENDLY_OFFSET,
00536 .desc_size = sizeof(struct wavg_desc),
00537 };
00538
00539 static int load_module(void)
00540 {
00541 if (ast_format_register(&wav49_f))
00542 return AST_MODULE_LOAD_FAILURE;
00543 return AST_MODULE_LOAD_SUCCESS;
00544 }
00545
00546 static int unload_module(void)
00547 {
00548 return ast_format_unregister(wav49_f.name);
00549 }
00550
00551 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Microsoft WAV format (Proprietary GSM)",
00552 .load = load_module,
00553 .unload = unload_module,
00554 .load_pri = AST_MODPRI_APP_DEPEND
00555 );