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