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