source: abuse/trunk/src/imlib/readwav.cpp @ 39

Last change on this file since 39 was 19, checked in by Sam Hocevar, 18 years ago
  • cosmetic: s/allign/align/
File size: 3.3 KB
Line 
1#include "readwav.hpp"
2#include "specs.hpp"
3#include "macs.hpp"
4#include "dprint.hpp"
5
6struct wav_chunk
7{
8  char id[4];
9  unsigned long size;
10  char type[4];
11} ;
12
13struct wav_tag
14{
15  char id[4];
16  unsigned long size;
17} ;
18
19
20struct wav_format
21{
22  unsigned short fmt_tag,channels;
23  unsigned long samplesps,avg_bytesps;
24  unsigned short align;
25} ;
26
27
28struct pcm_wave
29{
30  wav_format wf;
31  unsigned short bitsps;
32} ;
33
34
35
36
37void read_chunk(wav_chunk &chunk, bFILE *fp)
38{
39  fp->read(&chunk.id,4);
40  chunk.size=fp->read_uint32();
41  fp->read(&chunk.type,4); 
42}
43
44void read_tag(wav_tag &tag, bFILE *fp)
45{
46  fp->read(&tag.id,4);
47  tag.size=fp->read_uint32();
48}
49
50void read_wav_format(wav_format &fmt, bFILE *fp)
51{
52  fmt.fmt_tag=fp->read_uint16();
53  fmt.channels=fp->read_uint16();
54  fmt.samplesps=fp->read_uint32();
55  fmt.avg_bytesps=fp->read_uint32(); 
56  fmt.align=fp->read_uint16(); 
57}
58
59
60void read_pcm(pcm_wave &pcm, bFILE *fp)
61{
62  read_wav_format(pcm.wf,fp);
63  pcm.bitsps=fp->read_uint16(); 
64}
65
66
67
68void write_wav(char *filename, long sample_rate, long data_size, unsigned char *data)
69{
70  bFILE *fp=open_file(filename,"wb");
71  if (fp->open_failure())
72  {
73    printf("Unable to open %s for writing\n", filename);
74    delete fp;
75    exit(1);
76  }
77
78  /***************  Write the chunk ***************************/
79  fp->write((void *)"RIFF",4); 
80  fp->write_uint32(data_size+36);
81  fp->write((void *)"WAVE",4);
82
83
84  /************** Write the tag *******************************/
85  fp->write((void *)"fmt ",4);
86  fp->write_uint32(16);
87 
88 
89  /************** Write PCM ***********************************/
90  fp->write_uint16(1);          // format_tag
91  fp->write_uint16(1);          // mono recording
92  fp->write_uint32(sample_rate);
93  fp->write_uint32(sample_rate);   // average bytes per sec
94  fp->write_uint16(1);    // alignment? Don't know what this does?
95  fp->write_uint16(8);    // 8 bits per sample
96 
97  /************* Write data tag ******************************/
98  fp->write((void *)"data",4);
99  fp->write_uint32(data_size);
100
101  /************ Now write sample data ************************/
102  fp->write(data,data_size);
103
104  delete fp;
105}
106
107
108
109unsigned char *read_wav(char *filename, long &sample_rate, long &data_size)
110{
111  unsigned char *data;
112  wav_chunk chunk;
113  wav_tag tag;
114  pcm_wave pcm;
115
116  bFILE *fp=open_file(filename,"rb");
117  if (fp->open_failure())
118  { delete fp; return NULL; }
119  read_chunk(chunk,fp);     
120  if (memcmp(chunk.type,"WAVE",4)!=0)
121  {
122    printf("Bad WAV file (chunk) %s\n",filename);
123    delete fp;
124    return NULL;   
125  }
126 
127  read_tag(tag,fp);
128  if (memcmp(tag.id,"fmt ",4)!=0)
129  {
130    printf( "fmt tag missing, bad file (%s)\n",filename);
131    delete fp;
132    return NULL;
133  }
134
135
136  read_pcm(pcm,fp);
137
138  fp->seek(tag.size-16,SEEK_CUR);  // seek to offset of sample
139
140  read_tag(tag,fp);
141
142  if (memcmp(tag.id,"data",4)!=0)
143  {
144    printf("Bad Wav file (tag), %s\n",filename);
145    delete fp;
146    return NULL;
147  }
148 
149  data_size=tag.size; 
150  data=(unsigned char *)jmalloc(tag.size,"WAV data");
151  ERROR(data,"Malloc error");
152
153  sample_rate=pcm.wf.samplesps;     
154  ERROR((unsigned int)fp->read(data,tag.size)==tag.size,"Premature end of file");
155  ERROR(pcm.bitsps==8,"Only 8-bit samples supported");
156  ERROR(pcm.wf.channels==1,"Only mono samples supported"); 
157  ERROR(pcm.wf.align==1,"Bad block alignment");   
158  delete fp;
159  return data;
160}
161
162
163
Note: See TracBrowser for help on using the repository browser.