include "logger.h" and errno.h from asterisk.h - usage shows that they
[asterisk/asterisk.git] / formats / format_wav_gsm.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  *
21  * \brief Save GSM in the proprietary Microsoft format.
22  * 
23  * Microsoft WAV format (Proprietary GSM)
24  * \arg File name extension: WAV,wav49  (Upper case WAV, lower case is another format)
25  * This format can be played on Windows systems, used for
26  * e-mail attachments mainly.
27  * \ingroup formats
28  */
29  
30 #include "asterisk.h"
31
32 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
33
34 #include <netinet/in.h>
35 #include <arpa/inet.h>
36 #include <sys/time.h>
37
38 #include "asterisk/lock.h"
39 #include "asterisk/channel.h"
40 #include "asterisk/file.h"
41 #include "asterisk/sched.h"
42 #include "asterisk/module.h"
43 #include "asterisk/endian.h"
44
45 #include "msgsm.h"
46
47 /* Some Ideas for this code came from makewave.c by Jeffrey Chilton */
48
49 /* Portions of the conversion code are by guido@sienanet.it */
50
51 #define GSM_FRAME_SIZE  33
52 #define MSGSM_FRAME_SIZE        65
53 #define MSGSM_DATA_OFFSET               60      /* offset of data bytes */
54 #define GSM_SAMPLES             160     /* samples in a GSM block */
55 #define MSGSM_SAMPLES           (2*GSM_SAMPLES) /* samples in an MSGSM block */
56
57 /* begin binary data: */
58 char msgsm_silence[] = /* 65 */
59 {0x48,0x17,0xD6,0x84,0x02,0x80,0x24,0x49,0x92,0x24,0x89,0x02,0x80,0x24,0x49
60 ,0x92,0x24,0x89,0x02,0x80,0x24,0x49,0x92,0x24,0x89,0x02,0x80,0x24,0x49,0x92
61 ,0x24,0x09,0x82,0x74,0x61,0x4D,0x28,0x00,0x48,0x92,0x24,0x49,0x92,0x28,0x00
62 ,0x48,0x92,0x24,0x49,0x92,0x28,0x00,0x48,0x92,0x24,0x49,0x92,0x28,0x00,0x48
63 ,0x92,0x24,0x49,0x92,0x00};
64 /* end binary data. size = 65 bytes */
65
66 struct wavg_desc {
67         /* Believe it or not, we must decode/recode to account for the
68            weird MS format */
69         int secondhalf;                                         /* Are we on the second half */
70 };
71
72 #if __BYTE_ORDER == __LITTLE_ENDIAN
73 #define htoll(b) (b)
74 #define htols(b) (b)
75 #define ltohl(b) (b)
76 #define ltohs(b) (b)
77 #else
78 #if __BYTE_ORDER == __BIG_ENDIAN
79 #define htoll(b)  \
80           (((((b)      ) & 0xFF) << 24) | \
81                ((((b) >>  8) & 0xFF) << 16) | \
82                    ((((b) >> 16) & 0xFF) <<  8) | \
83                    ((((b) >> 24) & 0xFF)      ))
84 #define htols(b) \
85           (((((b)      ) & 0xFF) << 8) | \
86                    ((((b) >> 8) & 0xFF)      ))
87 #define ltohl(b) htoll(b)
88 #define ltohs(b) htols(b)
89 #else
90 #error "Endianess not defined"
91 #endif
92 #endif
93
94
95 static int check_header(FILE *f)
96 {
97         int type, size, formtype;
98         int fmt, hsize, fact;
99         short format, chans;
100         int freq;
101         int data;
102         if (fread(&type, 1, 4, f) != 4) {
103                 ast_log(LOG_WARNING, "Read failed (type)\n");
104                 return -1;
105         }
106         if (fread(&size, 1, 4, f) != 4) {
107                 ast_log(LOG_WARNING, "Read failed (size)\n");
108                 return -1;
109         }
110         size = ltohl(size);
111         if (fread(&formtype, 1, 4, f) != 4) {
112                 ast_log(LOG_WARNING, "Read failed (formtype)\n");
113                 return -1;
114         }
115         if (memcmp(&type, "RIFF", 4)) {
116                 ast_log(LOG_WARNING, "Does not begin with RIFF\n");
117                 return -1;
118         }
119         if (memcmp(&formtype, "WAVE", 4)) {
120                 ast_log(LOG_WARNING, "Does not contain WAVE\n");
121                 return -1;
122         }
123         if (fread(&fmt, 1, 4, f) != 4) {
124                 ast_log(LOG_WARNING, "Read failed (fmt)\n");
125                 return -1;
126         }
127         if (memcmp(&fmt, "fmt ", 4)) {
128                 ast_log(LOG_WARNING, "Does not say fmt\n");
129                 return -1;
130         }
131         if (fread(&hsize, 1, 4, f) != 4) {
132                 ast_log(LOG_WARNING, "Read failed (formtype)\n");
133                 return -1;
134         }
135         if (ltohl(hsize) != 20) {
136                 ast_log(LOG_WARNING, "Unexpected header size %d\n", ltohl(hsize));
137                 return -1;
138         }
139         if (fread(&format, 1, 2, f) != 2) {
140                 ast_log(LOG_WARNING, "Read failed (format)\n");
141                 return -1;
142         }
143         if (ltohs(format) != 49) {
144                 ast_log(LOG_WARNING, "Not a GSM file %d\n", ltohs(format));
145                 return -1;
146         }
147         if (fread(&chans, 1, 2, f) != 2) {
148                 ast_log(LOG_WARNING, "Read failed (format)\n");
149                 return -1;
150         }
151         if (ltohs(chans) != 1) {
152                 ast_log(LOG_WARNING, "Not in mono %d\n", ltohs(chans));
153                 return -1;
154         }
155         if (fread(&freq, 1, 4, f) != 4) {
156                 ast_log(LOG_WARNING, "Read failed (freq)\n");
157                 return -1;
158         }
159         if (ltohl(freq) != DEFAULT_SAMPLE_RATE) {
160                 ast_log(LOG_WARNING, "Unexpected freqency %d\n", ltohl(freq));
161                 return -1;
162         }
163         /* Ignore the byte frequency */
164         if (fread(&freq, 1, 4, f) != 4) {
165                 ast_log(LOG_WARNING, "Read failed (X_1)\n");
166                 return -1;
167         }
168         /* Ignore the two weird fields */
169         if (fread(&freq, 1, 4, f) != 4) {
170                 ast_log(LOG_WARNING, "Read failed (X_2/X_3)\n");
171                 return -1;
172         }
173         /* Ignore the byte frequency */
174         if (fread(&freq, 1, 4, f) != 4) {
175                 ast_log(LOG_WARNING, "Read failed (Y_1)\n");
176                 return -1;
177         }
178         /* Check for the word fact */
179         if (fread(&fact, 1, 4, f) != 4) {
180                 ast_log(LOG_WARNING, "Read failed (fact)\n");
181                 return -1;
182         }
183         if (memcmp(&fact, "fact", 4)) {
184                 ast_log(LOG_WARNING, "Does not say fact\n");
185                 return -1;
186         }
187         /* Ignore the "fact value" */
188         if (fread(&fact, 1, 4, f) != 4) {
189                 ast_log(LOG_WARNING, "Read failed (fact header)\n");
190                 return -1;
191         }
192         if (fread(&fact, 1, 4, f) != 4) {
193                 ast_log(LOG_WARNING, "Read failed (fact value)\n");
194                 return -1;
195         }
196         /* Check for the word data */
197         if (fread(&data, 1, 4, f) != 4) {
198                 ast_log(LOG_WARNING, "Read failed (data)\n");
199                 return -1;
200         }
201         if (memcmp(&data, "data", 4)) {
202                 ast_log(LOG_WARNING, "Does not say data\n");
203                 return -1;
204         }
205         /* Ignore the data length */
206         if (fread(&data, 1, 4, f) != 4) {
207                 ast_log(LOG_WARNING, "Read failed (data)\n");
208                 return -1;
209         }
210         return 0;
211 }
212
213 static int update_header(FILE *f)
214 {
215         off_t cur,end,bytes;
216         int datalen, filelen, samples;
217
218         cur = ftello(f);
219         fseek(f, 0, SEEK_END);
220         end = ftello(f);
221         /* in a gsm WAV, data starts 60 bytes in */
222         bytes = end - MSGSM_DATA_OFFSET;
223         samples = htoll(bytes / MSGSM_FRAME_SIZE * MSGSM_SAMPLES);
224         datalen = htoll((bytes + 1) & ~0x1);
225         filelen = htoll(MSGSM_DATA_OFFSET - 8 + ((bytes + 1) & ~0x1));
226         if (cur < 0) {
227                 ast_log(LOG_WARNING, "Unable to find our position\n");
228                 return -1;
229         }
230         if (fseek(f, 4, SEEK_SET)) {
231                 ast_log(LOG_WARNING, "Unable to set our position\n");
232                 return -1;
233         }
234         if (fwrite(&filelen, 1, 4, f) != 4) {
235                 ast_log(LOG_WARNING, "Unable to write file size\n");
236                 return -1;
237         }
238         if (fseek(f, 48, SEEK_SET)) {
239                 ast_log(LOG_WARNING, "Unable to set our position\n");
240                 return -1;
241         }
242         if (fwrite(&samples, 1, 4, f) != 4) {
243                 ast_log(LOG_WARNING, "Unable to write samples\n");
244                 return -1;
245         }
246         if (fseek(f, 56, SEEK_SET)) {
247                 ast_log(LOG_WARNING, "Unable to set our position\n");
248                 return -1;
249         }
250         if (fwrite(&datalen, 1, 4, f) != 4) {
251                 ast_log(LOG_WARNING, "Unable to write datalen\n");
252                 return -1;
253         }
254         if (fseeko(f, cur, SEEK_SET)) {
255                 ast_log(LOG_WARNING, "Unable to return to position\n");
256                 return -1;
257         }
258         return 0;
259 }
260
261 static int write_header(FILE *f)
262 {
263         /* Samples per second (always 8000 for this format). */
264         unsigned int sample_rate = htoll(8000);
265         /* Bytes per second (always 1625 for this format). */
266         unsigned int byte_sample_rate = htoll(1625);
267         /* This is the size of the "fmt " subchunk */
268         unsigned int fmtsize = htoll(20);
269         /* WAV #49 */
270         unsigned short fmt = htols(49);
271         /* Mono = 1 channel */
272         unsigned short chans = htols(1);
273         /* Each block of data is exactly 65 bytes in size. */
274         unsigned int block_align = htoll(MSGSM_FRAME_SIZE);
275         /* Not actually 2, but rounded up to the nearest bit */
276         unsigned short bits_per_sample = htols(2);
277         /* Needed for compressed formats */
278         unsigned short extra_format = htols(MSGSM_SAMPLES);
279         /* This is the size of the "fact" subchunk */
280         unsigned int factsize = htoll(4);
281         /* Number of samples in the data chunk */
282         unsigned int num_samples = htoll(0);
283         /* Number of bytes in the data chunk */
284         unsigned int size = htoll(0);
285         /* Write a GSM header, ignoring sizes which will be filled in later */
286
287         /*  0: Chunk ID */
288         if (fwrite("RIFF", 1, 4, f) != 4) {
289                 ast_log(LOG_WARNING, "Unable to write header\n");
290                 return -1;
291         }
292         /*  4: Chunk Size */
293         if (fwrite(&size, 1, 4, f) != 4) {
294                 ast_log(LOG_WARNING, "Unable to write header\n");
295                 return -1;
296         }
297         /*  8: Chunk Format */
298         if (fwrite("WAVE", 1, 4, f) != 4) {
299                 ast_log(LOG_WARNING, "Unable to write header\n");
300                 return -1;
301         }
302         /* 12: Subchunk 1: ID */
303         if (fwrite("fmt ", 1, 4, f) != 4) {
304                 ast_log(LOG_WARNING, "Unable to write header\n");
305                 return -1;
306         }
307         /* 16: Subchunk 1: Size (minus 8) */
308         if (fwrite(&fmtsize, 1, 4, f) != 4) {
309                 ast_log(LOG_WARNING, "Unable to write header\n");
310                 return -1;
311         }
312         /* 20: Subchunk 1: Audio format (49) */
313         if (fwrite(&fmt, 1, 2, f) != 2) {
314                 ast_log(LOG_WARNING, "Unable to write header\n");
315                 return -1;
316         }
317         /* 22: Subchunk 1: Number of channels */
318         if (fwrite(&chans, 1, 2, f) != 2) {
319                 ast_log(LOG_WARNING, "Unable to write header\n");
320                 return -1;
321         }
322         /* 24: Subchunk 1: Sample rate */
323         if (fwrite(&sample_rate, 1, 4, f) != 4) {
324                 ast_log(LOG_WARNING, "Unable to write header\n");
325                 return -1;
326         }
327         /* 28: Subchunk 1: Byte rate */
328         if (fwrite(&byte_sample_rate, 1, 4, f) != 4) {
329                 ast_log(LOG_WARNING, "Unable to write header\n");
330                 return -1;
331         }
332         /* 32: Subchunk 1: Block align */
333         if (fwrite(&block_align, 1, 4, f) != 4) {
334                 ast_log(LOG_WARNING, "Unable to write header\n");
335                 return -1;
336         }
337         /* 36: Subchunk 1: Bits per sample */
338         if (fwrite(&bits_per_sample, 1, 2, f) != 2) {
339                 ast_log(LOG_WARNING, "Unable to write header\n");
340                 return -1;
341         }
342         /* 38: Subchunk 1: Extra format bytes */
343         if (fwrite(&extra_format, 1, 2, f) != 2) {
344                 ast_log(LOG_WARNING, "Unable to write header\n");
345                 return -1;
346         }
347         /* 40: Subchunk 2: ID */
348         if (fwrite("fact", 1, 4, f) != 4) {
349                 ast_log(LOG_WARNING, "Unable to write header\n");
350                 return -1;
351         }
352         /* 44: Subchunk 2: Size (minus 8) */
353         if (fwrite(&factsize, 1, 4, f) != 4) {
354                 ast_log(LOG_WARNING, "Unable to write header\n");
355                 return -1;
356         }
357         /* 48: Subchunk 2: Number of samples */
358         if (fwrite(&num_samples, 1, 4, f) != 4) {
359                 ast_log(LOG_WARNING, "Unable to write header\n");
360                 return -1;
361         }
362         /* 52: Subchunk 3: ID */
363         if (fwrite("data", 1, 4, f) != 4) {
364                 ast_log(LOG_WARNING, "Unable to write header\n");
365                 return -1;
366         }
367         /* 56: Subchunk 3: Size */
368         if (fwrite(&size, 1, 4, f) != 4) {
369                 ast_log(LOG_WARNING, "Unable to write header\n");
370                 return -1;
371         }
372         return 0;
373 }
374
375 static int wav_open(struct ast_filestream *s)
376 {
377         /* We don't have any header to read or anything really, but
378            if we did, it would go here.  We also might want to check
379            and be sure it's a valid file.  */
380         struct wavg_desc *fs = (struct wavg_desc *)s->private;
381
382         if (check_header(s->f))
383                 return -1;
384         fs->secondhalf = 0;     /* not strictly necessary */
385         return 0;
386 }
387
388 static int wav_rewrite(struct ast_filestream *s, const char *comment)
389 {
390         /* We don't have any header to read or anything really, but
391            if we did, it would go here.  We also might want to check
392            and be sure it's a valid file.  */
393
394         if (write_header(s->f))
395                 return -1;
396         return 0;
397 }
398
399 static void wav_close(struct ast_filestream *s)
400 {
401         char zero = 0;
402         /* Pad to even length */
403         fseek(s->f, 0, SEEK_END);
404         if (ftello(s->f) & 0x1)
405                 fwrite(&zero, 1, 1, s->f);
406 }
407
408 static struct ast_frame *wav_read(struct ast_filestream *s, int *whennext)
409 {
410         /* Send a frame from the file to the appropriate channel */
411         struct wavg_desc *fs = (struct wavg_desc *)s->private;
412
413         s->fr.frametype = AST_FRAME_VOICE;
414         s->fr.subclass = AST_FORMAT_GSM;
415         s->fr.offset = AST_FRIENDLY_OFFSET;
416         s->fr.samples = GSM_SAMPLES;
417         s->fr.mallocd = 0;
418         AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, GSM_FRAME_SIZE);
419         if (fs->secondhalf) {
420                 /* Just return a frame based on the second GSM frame */
421                 s->fr.data = (char *)s->fr.data + GSM_FRAME_SIZE;
422                 s->fr.offset += GSM_FRAME_SIZE;
423         } else {
424                 /* read and convert */
425                 unsigned char msdata[MSGSM_FRAME_SIZE];
426                 int res;
427                 
428                 if ((res = fread(msdata, 1, MSGSM_FRAME_SIZE, s->f)) != MSGSM_FRAME_SIZE) {
429                         if (res && (res != 1))
430                                 ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
431                         return NULL;
432                 }
433                 /* Convert from MS format to two real GSM frames */
434                 conv65(msdata, s->fr.data);
435         }
436         fs->secondhalf = !fs->secondhalf;
437         *whennext = GSM_SAMPLES;
438         return &s->fr;
439 }
440
441 static int wav_write(struct ast_filestream *s, struct ast_frame *f)
442 {
443         int len;
444         int size;
445         struct wavg_desc *fs = (struct wavg_desc *)s->private;
446
447         if (f->frametype != AST_FRAME_VOICE) {
448                 ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
449                 return -1;
450         }
451         if (f->subclass != AST_FORMAT_GSM) {
452                 ast_log(LOG_WARNING, "Asked to write non-GSM frame (%d)!\n", f->subclass);
453                 return -1;
454         }
455         /* XXX this might fail... if the input is a multiple of MSGSM_FRAME_SIZE
456          * we assume it is already in the correct format.
457          */
458         if (!(f->datalen % MSGSM_FRAME_SIZE)) {
459                 size = MSGSM_FRAME_SIZE;
460                 fs->secondhalf = 0;
461         } else {
462                 size = GSM_FRAME_SIZE;
463         }
464         for (len = 0; len < f->datalen ; len += size) {
465                 int res;
466                 unsigned char *src, msdata[MSGSM_FRAME_SIZE];
467                 if (fs->secondhalf) {   /* second half of raw gsm to be converted */
468                         memcpy(s->buf + GSM_FRAME_SIZE, f->data + len, GSM_FRAME_SIZE);
469                         conv66((unsigned char *) s->buf, msdata);
470                         src = msdata;
471                         fs->secondhalf = 0;
472                 } else if (size == GSM_FRAME_SIZE) {    /* first half of raw gsm */
473                         memcpy(s->buf, f->data + len, GSM_FRAME_SIZE);
474                         src = NULL;     /* nothing to write */
475                         fs->secondhalf = 1;
476                 } else {        /* raw msgsm data */
477                         src = f->data + len;
478                 }
479                 if (src && (res = fwrite(src, 1, MSGSM_FRAME_SIZE, s->f)) != MSGSM_FRAME_SIZE) {
480                         ast_log(LOG_WARNING, "Bad write (%d/65): %s\n", res, strerror(errno));
481                         return -1;
482                 }
483                 update_header(s->f); /* XXX inefficient! */
484         }
485         return 0;
486 }
487
488 static int wav_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
489 {
490         off_t offset=0, distance, max;
491         struct wavg_desc *s = (struct wavg_desc *)fs->private;
492
493         off_t min = MSGSM_DATA_OFFSET;
494         off_t cur = ftello(fs->f);
495         fseek(fs->f, 0, SEEK_END);
496         max = ftello(fs->f);    /* XXX ideally, should round correctly */
497         /* Compute the distance in bytes, rounded to the block size */
498         distance = (sample_offset/MSGSM_SAMPLES) * MSGSM_FRAME_SIZE;
499         if (whence == SEEK_SET)
500                 offset = distance + min;
501         else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
502                 offset = distance + cur;
503         else if (whence == SEEK_END)
504                 offset = max - distance;
505         /* always protect against seeking past end of header */
506         if (offset < min)
507                 offset = min;
508         if (whence != SEEK_FORCECUR) {
509                 if (offset > max)
510                         offset = max;
511         } else if (offset > max) {
512                 int i;
513                 fseek(fs->f, 0, SEEK_END);
514                 for (i=0; i< (offset - max) / MSGSM_FRAME_SIZE; i++) {
515                         fwrite(msgsm_silence, 1, MSGSM_FRAME_SIZE, fs->f);
516                 }
517         }
518         s->secondhalf = 0;
519         return fseeko(fs->f, offset, SEEK_SET);
520 }
521
522 static int wav_trunc(struct ast_filestream *fs)
523 {
524         if (ftruncate(fileno(fs->f), ftello(fs->f)))
525                 return -1;
526         return update_header(fs->f);
527 }
528
529 static off_t wav_tell(struct ast_filestream *fs)
530 {
531         off_t offset;
532         offset = ftello(fs->f);
533         /* since this will most likely be used later in play or record, lets stick
534          * to that level of resolution, just even frames boundaries */
535         return (offset - MSGSM_DATA_OFFSET)/MSGSM_FRAME_SIZE*MSGSM_SAMPLES;
536 }
537
538 static const struct ast_format wav49_f = {
539         .name = "wav49",
540         .exts = "WAV|wav49",
541         .format = AST_FORMAT_GSM,
542         .open = wav_open,
543         .rewrite = wav_rewrite,
544         .write = wav_write,
545         .seek = wav_seek,
546         .trunc = wav_trunc,
547         .tell = wav_tell,
548         .read = wav_read,
549         .close = wav_close,
550         .buf_size = 2*GSM_FRAME_SIZE + AST_FRIENDLY_OFFSET,
551         .desc_size = sizeof(struct wavg_desc),
552 };
553
554 static int load_module(void)
555 {
556         if (ast_format_register(&wav49_f))
557                 return AST_MODULE_LOAD_FAILURE;
558         return AST_MODULE_LOAD_SUCCESS;
559 }
560
561 static int unload_module(void)
562 {
563         return ast_format_unregister(wav49_f.name);
564 }       
565
566 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Microsoft WAV format (Proprietary GSM)");