1 /*
2  * Copyright (C) 2002-2003 Fhg Fokus
3  *
4  * This file is part of SEMS, a free SIP media server.
5  *
6  * SEMS is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version. This program is released under
10  * the GPL with the additional exemption that compiling, linking,
11  * and/or using OpenSSL is allowed.
12  *
13  * For a license to use the SEMS software under conditions
14  * other than those described here, or to purchase support for this
15  * software, please contact iptel.org by e-mail at the following addresses:
16  *    info@iptel.org
17  *
18  * SEMS is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26  */
27 
28 #include "wav_hdr.h"
29 #include "../../log.h"
30 
31 #include <errno.h>
32 #include <string.h>
33 #include <sys/types.h>
34 
35 #include <stdio.h>
36 #include <stdlib.h>
37 
38 #if (defined(__BYTE_ORDER) && (__BYTE_ORDER == __BIG_ENDIAN)) || (defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN))
39 #define bswap_16(A)  ((((u_int16_t)(A) & 0xff00) >> 8) | \
40                    (((u_int16_t)(A) & 0x00ff) << 8))
41 #define bswap_32(A)  ((((u_int32_t)(A) & 0xff000000) >> 24) | \
42                    (((u_int32_t)(A) & 0x00ff0000) >> 8)  | \
43                    (((u_int32_t)(A) & 0x0000ff00) << 8)  | \
44                    (((u_int32_t)(A) & 0x000000ff) << 24))
45 #define cpu_to_le16(x) bswap_16(x)
46 #define le_to_cpu16(x) bswap_16(x)
47 #define cpu_to_le32(x) bswap_32(x)
48 #define le_to_cpu32(x) bswap_32(x)
49 #elif (defined(__BYTE_ORDER) && (__BYTE_ORDER == __LITTLE_ENDIAN)) || defined(_LITTLE_ENDIAN) || defined(__LITTLE_ENDIAN) || (defined(BYTE_ORDER) && (BYTE_ORDER == LITTLE_ENDIAN))
50 #define cpu_to_le16(x) (x)
51 #define cpu_to_le32(x) (x)
52 #define le_to_cpu16(x) (x)
53 #define le_to_cpu32(x) (x)
54 #else
55 #error unknown endianness!
56 #endif
57 
58 
59 #define SAFE_READ(buf,s,fp,sr) \
60     sr = fread(buf,s,1,fp);\
61     if((sr != 1) || ferror(fp)) { \
62       ERROR("fread: %s (sr=%d)\n", strerror(errno), sr);	\
63     return -1;					\
64     }
65 \
66 
67 /** \brief The file header of RIFF-WAVE files (*.wav).
68  * Files are always in
69  * little-endian byte-order.
70  */
71 
72 struct wav_header
73 {
74   char      magic[4];
75   u_int32_t length;
76   char	    chunk_type[4];
77   char      chunk_format[4];
78   u_int32_t chunk_length;
79   u_int16_t format;
80   u_int16_t channels;
81   u_int32_t sample_rate;
82   u_int32_t bytes_per_second;
83   u_int16_t sample_size;
84   u_int16_t precision;
85   char      chunk_data[4];
86   u_int32_t data_length;
87 };
88 
89 //If wav_dummyread() had a problem, return code -1
wav_dummyread(FILE * fp,unsigned int size)90 int wav_dummyread(FILE *fp, unsigned int size)
91 {
92   unsigned int s;
93   char *dummybuf;
94 
95   DBG("Skip chunk by reading dummy bytes from stream\n");
96   dummybuf = (char*) malloc (size);
97   if(dummybuf==NULL) {
98       ERROR("Can't alloc memory for dummyread!\n");
99       return -1;
100   }
101 
102   SAFE_READ(dummybuf,size,fp,s);
103   free(dummybuf);
104   return 0;
105 }
106 
wav_read_header(FILE * fp,struct amci_file_desc_t * fmt_desc)107 static int wav_read_header(FILE* fp, struct amci_file_desc_t* fmt_desc)
108 {
109   unsigned int s;
110 
111   char tag[4]={'\0'};
112   unsigned int file_size=0;
113   unsigned int chunk_size=0;
114   unsigned short fmt=0;
115   unsigned short channels=0;
116   unsigned int rate=0;
117   unsigned short bits_per_sample=0;
118   unsigned short sample_size=0;
119   char dummy[6]={'\0'};
120   int is_seekable = 1;
121 
122   if(!fp)
123     return -1;
124   rewind(fp);
125 
126   DBG("trying to read WAV file\n");
127 
128   SAFE_READ(tag,4,fp,s);
129   DBG("tag = <%.4s>\n",tag);
130   if(strncmp(tag,"RIFF",4)){
131     DBG("wrong format !\n");
132     return -1;
133   }
134 
135   SAFE_READ(&file_size,4,fp,s);
136   file_size=le_to_cpu32(file_size);
137   DBG("file size = <%u>\n",file_size);
138 
139   SAFE_READ(tag,4,fp,s);
140   DBG("tag = <%.4s>\n",tag);
141   if(strncmp(tag,"WAVE",4)){
142     DBG("wrong format !\n");
143     return -1;
144   }
145 
146   SAFE_READ(tag,4,fp,s);
147   DBG("tag = <%.4s>\n",tag);
148   if(strncmp(tag,"fmt ",4)){
149     DBG("wrong format !\n");
150     return -1;
151   }
152 
153   SAFE_READ(&chunk_size,4,fp,s);
154   chunk_size=le_to_cpu32(chunk_size);
155   DBG("chunk_size = <%u>\n",chunk_size);
156 
157   SAFE_READ(&fmt,2,fp,s);
158   fmt=le_to_cpu16(fmt);
159   DBG("fmt = <%.2x>\n",fmt);
160 
161   SAFE_READ(&channels,2,fp,s);
162   channels=le_to_cpu16(channels);
163   DBG("channels = <%i>\n",channels);
164 
165   SAFE_READ(&rate,4,fp,s);
166   rate=le_to_cpu32(rate);
167   DBG("rate = <%i>\n",rate);
168 
169   /* do not read bytes/sec and block align */
170   SAFE_READ(&dummy,6,fp,s); // skip by reading into dummy buffer
171 
172   SAFE_READ(&bits_per_sample,2,fp,s);
173   bits_per_sample=le_to_cpu16(bits_per_sample);
174   DBG("bits/sample = <%i>\n",bits_per_sample);
175 
176   fmt_desc->subtype = fmt;
177   sample_size = bits_per_sample>>3;
178   fmt_desc->rate = rate;
179   fmt_desc->channels = channels;
180 
181   if( (fmt == 0x01) && (sample_size == 1)){
182     ERROR("Sorry, we don't support PCM 8 bit\n");
183     return -1;
184   }
185 
186   if ((fseek(fp,chunk_size-16,SEEK_CUR) < 0)
187       && errno == EBADF) {
188     is_seekable = 0;
189     wav_dummyread(fp,chunk_size-16);
190   }
191 
192   for(;;) {
193 
194     SAFE_READ(tag,4,fp,s);
195     DBG("tag = <%.4s>\n",tag);
196 
197     SAFE_READ(&chunk_size,4,fp,s);
198     chunk_size=le_to_cpu32(chunk_size);
199     DBG("chunk size = <%i>\n",chunk_size);
200 
201     if(!strncmp(tag,"data",4))
202       break;
203 
204     if (is_seekable)
205       fseek(fp,chunk_size,SEEK_CUR);
206     else
207       wav_dummyread(fp,chunk_size);
208   }
209   fmt_desc->data_size = chunk_size;
210 
211   return 0;
212 }
213 
wav_open(FILE * fp,struct amci_file_desc_t * fmt_desc,int options,long h_codec)214 int wav_open(FILE* fp, struct amci_file_desc_t* fmt_desc, int options, long h_codec)
215 {
216   if(options == AMCI_RDONLY){
217     return wav_read_header(fp,fmt_desc);
218   }
219   else {
220     /*  Reserve some space for the header */
221     /*  We need this, as information for headers  */
222     /*  like 'size' is not known yet */
223     fseek(fp,44L,SEEK_CUR);
224     return (ferror(fp) ? -1 : 0);
225   }
226 }
227 
wav_write_header(FILE * fp,struct amci_file_desc_t * fmt_desc,long h_codec,struct amci_codec_t * codec)228 int wav_write_header(FILE* fp, struct amci_file_desc_t* fmt_desc, long h_codec, struct amci_codec_t *codec)
229 {
230   struct wav_header hdr;
231   int sample_size;
232 
233   if (codec && codec->samples2bytes)
234     sample_size = codec->samples2bytes(h_codec, 1);
235   else {
236     ERROR("Cannot determine sample size\n");
237     sample_size = 2;
238   }
239   memcpy(hdr.magic, "RIFF",4);
240   hdr.length = cpu_to_le32(fmt_desc->data_size + 36);
241   memcpy(hdr.chunk_type, "WAVE",4);
242   memcpy(hdr.chunk_format, "fmt ",4);
243   hdr.chunk_length = cpu_to_le32(16);
244   hdr.format = cpu_to_le16(fmt_desc->subtype);
245   hdr.channels = cpu_to_le16((unsigned short)fmt_desc->channels);
246   hdr.sample_rate = cpu_to_le32((unsigned int)fmt_desc->rate);
247   hdr.sample_size = cpu_to_le16(hdr.channels * sample_size);
248   hdr.bytes_per_second = cpu_to_le32(hdr.sample_rate * (unsigned int)hdr.sample_size);
249   hdr.precision = cpu_to_le16((unsigned short)(sample_size * 8));
250   memcpy(hdr.chunk_data,"data",4);
251   hdr.data_length=cpu_to_le32(fmt_desc->data_size);
252 
253   fwrite(&hdr,sizeof(hdr),1,fp);
254   if(ferror(fp)) return -1;
255 
256   DBG("fmt = <%i>\n",le_to_cpu16(hdr.format));
257   DBG("channels = <%i>\n",le_to_cpu16(hdr.channels));
258   DBG("rate = <%i>\n",le_to_cpu32(hdr.sample_rate));
259   DBG("data_size = <%i>\n",le_to_cpu32(hdr.data_length));
260 
261   return 0;
262 }
263 
264 
wav_close(FILE * fp,struct amci_file_desc_t * fmt_desc,int options,long h_codec,struct amci_codec_t * codec)265 int wav_close(FILE* fp, struct amci_file_desc_t* fmt_desc, int options, long h_codec, struct amci_codec_t *codec)
266 {
267   if(options == AMCI_WRONLY){
268     rewind(fp);
269     return wav_write_header(fp, fmt_desc, h_codec, codec);
270   }
271   return 0;
272 }
273 
274 #define SAFE_MEM_READ(buf,s,mptr,pos,size) \
275     if (*pos+s>size) return -1; \
276     memcpy(buf,mptr+*pos,s); \
277     *pos+=s;
278 
wav_mem_open(unsigned char * mptr,unsigned long size,unsigned long * pos,struct amci_file_desc_t * fmt_desc,int options,long h_codec)279 int wav_mem_open(unsigned char* mptr, unsigned long size, unsigned long* pos,
280 		 struct amci_file_desc_t* fmt_desc, int options, long h_codec) {
281   if(options == AMCI_RDONLY){
282 
283     char tag[4]={'\0'};
284     unsigned int file_size=0;
285     unsigned int chunk_size=0;
286     unsigned short fmt=0;
287     unsigned short channels=0;
288     unsigned int rate=0;
289     unsigned short bits_per_sample=0;
290     unsigned short sample_size=0;
291 
292     if(!mptr)
293       return -1;
294     *pos=0;
295 
296     DBG("trying to read WAV file from memory\n");
297 
298     SAFE_MEM_READ(tag,4,mptr,pos,size);
299     DBG("tag = <%.4s>\n",tag);
300     if(strncmp(tag,"RIFF",4)){
301       DBG("wrong format !");
302       return -1;
303     }
304 
305     SAFE_MEM_READ(&file_size,4,mptr,pos,size);
306     DBG("file size = <%u>\n",file_size);
307 
308     SAFE_MEM_READ(tag,4,mptr,pos,size);
309     DBG("tag = <%.4s>\n",tag);
310     if(strncmp(tag,"WAVE",4)){
311       DBG("wrong format !");
312       return -1;
313     }
314 
315     SAFE_MEM_READ(tag,4,mptr,pos,size);
316     DBG("tag = <%.4s>\n",tag);
317     if(strncmp(tag,"fmt ",4)){
318       DBG("wrong format !");
319       return -1;
320     }
321 
322     SAFE_MEM_READ(&chunk_size,4,mptr,pos,size);
323     DBG("chunk_size = <%u>\n",chunk_size);
324 
325     SAFE_MEM_READ(&fmt,2,mptr,pos,size);
326     DBG("fmt = <%.2x>\n",fmt);
327 
328     SAFE_MEM_READ(&channels,2,mptr,pos,size);
329     DBG("channels = <%i>\n",channels);
330 
331     SAFE_MEM_READ(&rate,4,mptr,pos,size);
332     DBG("rate = <%i>\n",rate);
333 
334     /* do not read bytes/sec and block align */
335     *pos +=6;
336 
337     SAFE_MEM_READ(&bits_per_sample,2,mptr,pos,size);
338     DBG("bits/sample = <%i>\n",bits_per_sample);
339 
340     fmt_desc->subtype = fmt;
341     sample_size = bits_per_sample>>3;
342     fmt_desc->rate = rate;
343     fmt_desc->channels = channels;
344 
345     if( (fmt == 0x01) && (sample_size == 1)){
346       ERROR("Sorry, we don't support PCM 8 bit\n");
347       return -1;
348     }
349 
350     *pos+=chunk_size-16;
351 
352     for(;;) {
353 
354       SAFE_MEM_READ(tag,4,mptr,pos,size);
355       DBG("tag = <%.4s>\n",tag);
356 
357       SAFE_MEM_READ(&chunk_size,4,mptr,pos,size);
358       DBG("chunk size = <%i>\n",chunk_size);
359 
360       if(!strncmp(tag,"data",4))
361 	break;
362 
363       *pos += chunk_size;
364     }
365 
366     return 0;
367 
368   } else {
369     ERROR("write support for in-memory file not implemented!\n");
370     return -1;
371   }
372 }
373 
wav_mem_close(unsigned char * mptr,unsigned long * pos,struct amci_file_desc_t * fmt_desc,int options,long h_codec,struct amci_codec_t * codec)374 int wav_mem_close(unsigned char* mptr, unsigned long* pos,
375 		  struct amci_file_desc_t* fmt_desc, int options, long h_codec, struct amci_codec_t *codec) {
376   return 0;
377 }
378 
379 
380 
381 
382 
383 
384 
385