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

Last change on this file since 524 was 524, checked in by Sam Hocevar, 11 years ago

core: Get rid of mostly useless headers, move endianness handling to
common.h (and rewrite functions so that they do not need the SDL headers)
and move a few functions out of sdlport's video.cpp. These functions
were in the original video.cpp (which reappears) and shouldn't be part
of the SDL port.

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