source: abuse/tags/pd/macabuse/imlib/readwav.c @ 49

Last change on this file since 49 was 49, checked in by Sam Hocevar, 12 years ago
  • Imported original public domain release, for future reference.
  • Property svn:keywords set to Id
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_long();
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_long();
48}
49
50void read_wav_format(wav_format &fmt, bFILE *fp)
51{
52  fmt.fmt_tag=fp->read_short();
53  fmt.channels=fp->read_short();
54  fmt.samplesps=fp->read_long();
55  fmt.avg_bytesps=fp->read_long(); 
56  fmt.align=fp->read_short(); 
57}
58
59
60void read_pcm(pcm_wave &pcm, bFILE *fp)
61{
62  read_wav_format(pcm.wf,fp);
63  pcm.bitsps=fp->read_short(); 
64}
65
66
67
68void write_wav(char *filename, long sample_rate, long data_size, unsigned char *data)
69{
70  wav_chunk chunk;
71  wav_tag tag;
72  pcm_wave pcm; 
73
74 
75  bFILE *fp=open_file(filename,"wb");
76  if (fp->open_failure())
77  {
78    dprintf("Unable to open %s for writing\n");
79    delete fp;
80    exit(1);
81  }
82
83  /***************  Write the chunk ***************************/
84  fp->write("RIFF",4); 
85  fp->write_long(data_size+36);
86  fp->write("WAVE",4);
87
88
89  /************** Write the tag *******************************/
90  fp->write("fmt ",4);
91  fp->write_long(16);
92 
93 
94  /************** Write PCM ***********************************/
95  fp->write_short(1);          // format_tag
96  fp->write_short(1);          // mono recording
97  fp->write_long(sample_rate);
98  fp->write_long(sample_rate);   // average bytes per sec
99  fp->write_short(1);    // allignment? Don't know what this does?
100  fp->write_short(8);    // 8 bits per sample
101 
102  /************* Write data tag ******************************/
103  fp->write("data",4);
104  fp->write_long(data_size);
105
106  /************ Now write sample data ************************/
107  fp->write(data,data_size);
108
109  delete fp;
110}
111
112
113
114unsigned char *read_wav(char *filename, long &sample_rate, long &data_size)
115{
116  unsigned char *data;
117  wav_chunk chunk;
118  wav_tag tag;
119  pcm_wave pcm; 
120
121  bFILE *fp=open_file(filename,"rb");
122  if (fp->open_failure())
123  { delete fp; return NULL; }
124  read_chunk(chunk,fp);     
125  if (memcmp(chunk.type,"WAVE",4)!=0)
126  {
127    dprintf("Bad WAV file (chunk) %s\n",filename);
128    delete fp;
129    return NULL;   
130  }
131 
132  read_tag(tag,fp);
133  if (memcmp(tag.id,"fmt ",4)!=0)
134  {
135    dprintf( "fmt tag missing, bad file (%s)\n",filename);
136    delete fp;
137    return NULL;
138  }
139
140
141  read_pcm(pcm,fp);
142
143  fp->seek(tag.size-16,SEEK_CUR);  // seek to offset of sample
144
145  read_tag(tag,fp);
146
147  if (memcmp(tag.id,"data",4)!=0)
148  {
149    dprintf("Bad Wav file (tag), %s\n",filename);
150    delete fp;
151    return NULL;
152  }
153 
154  data_size=tag.size; 
155  data=(unsigned char *)jmalloc(tag.size,"WAV data");
156  ERROR(data,"Malloc error");
157
158  sample_rate=pcm.wf.samplesps;     
159  ERROR(fp->read(data,tag.size)==tag.size,"Premature end of file");
160  ERROR(pcm.bitsps==8,"Only 8-bit samples supported");
161  ERROR(pcm.wf.channels==1,"Only mono samples supported"); 
162  ERROR(pcm.wf.align==1,"Bad block allignment");   
163  delete fp;
164  return data;
165}
166
167
168
Note: See TracBrowser for help on using the repository browser.