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

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

style: remove trailing spaces, fix copyright statements.

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