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

Last change on this file since 128 was 124, checked in by Sam Hocevar, 15 years ago
  • Get rid of ugly tabs and trailing spaces everywhere.
File size: 3.5 KB
RevLine 
[56]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
[2]12#include "readwav.hpp"
13#include "specs.hpp"
14#include "macs.hpp"
15#include "dprint.hpp"
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);
[17]51  chunk.size=fp->read_uint32();
[124]52  fp->read(&chunk.type,4);
[2]53}
54
55void read_tag(wav_tag &tag, bFILE *fp)
56{
57  fp->read(&tag.id,4);
[17]58  tag.size=fp->read_uint32();
[2]59}
60
61void read_wav_format(wav_format &fmt, bFILE *fp)
62{
[17]63  fmt.fmt_tag=fp->read_uint16();
[124]64  fmt.channels=fp->read_uint16();
[17]65  fmt.samplesps=fp->read_uint32();
[124]66  fmt.avg_bytesps=fp->read_uint32();
67  fmt.align=fp->read_uint16();
[2]68}
69
70
71void read_pcm(pcm_wave &pcm, bFILE *fp)
72{
73  read_wav_format(pcm.wf,fp);
[124]74  pcm.bitsps=fp->read_uint16();
[2]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 ***************************/
[124]90  fp->write((void *)"RIFF",4);
[17]91  fp->write_uint32(data_size+36);
[2]92  fp->write((void *)"WAVE",4);
93
94
95  /************** Write the tag *******************************/
96  fp->write((void *)"fmt ",4);
[17]97  fp->write_uint32(16);
[124]98
99
[2]100  /************** Write PCM ***********************************/
[17]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
[19]105  fp->write_uint16(1);    // alignment? Don't know what this does?
[17]106  fp->write_uint16(8);    // 8 bits per sample
[124]107
[2]108  /************* Write data tag ******************************/
109  fp->write((void *)"data",4);
[17]110  fp->write_uint32(data_size);
[2]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; }
[124]130  read_chunk(chunk,fp);
[2]131  if (memcmp(chunk.type,"WAVE",4)!=0)
132  {
133    printf("Bad WAV file (chunk) %s\n",filename);
134    delete fp;
[124]135    return NULL;
[2]136  }
[124]137
[2]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  }
[124]159
160  data_size=tag.size;
[2]161  data=(unsigned char *)jmalloc(tag.size,"WAV data");
162  ERROR(data,"Malloc error");
163
[124]164  sample_rate=pcm.wf.samplesps;
[2]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");
[124]167  ERROR(pcm.wf.channels==1,"Only mono samples supported");
168  ERROR(pcm.wf.align==1,"Bad block alignment");
[2]169  delete fp;
170  return data;
171}
172
173
174
Note: See TracBrowser for help on using the repository browser.