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

Last change on this file since 481 was 481, checked in by Sam Hocevar, 12 years ago

Fuck the history, I'm renaming all .hpp files to .h for my own sanity.

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