1 |
//////////////////////////////////////////////////////////////////////////////// |
2 |
/// |
3 |
/// Classes for easy reading & writing of WAV sound files. |
4 |
/// |
5 |
/// For big-endian CPU, define BIG_ENDIAN during compile-time to correctly |
6 |
/// parse the WAV files with such processors. |
7 |
/// |
8 |
/// Admittingly, more complete WAV reader routines may exist in public domain, but |
9 |
/// the reason for 'yet another' one is that those generic WAV reader libraries are |
10 |
/// exhaustingly large and cumbersome! Wanted to have something simpler here, i.e. |
11 |
/// something that's not already larger than rest of the SoundTouch/SoundStretch program... |
12 |
/// |
13 |
/// Author : Copyright (c) Olli Parviainen |
14 |
/// Author e-mail : oparviai 'at' iki.fi |
15 |
/// SoundTouch WWW: http://www.surina.net/soundtouch |
16 |
/// |
17 |
//////////////////////////////////////////////////////////////////////////////// |
18 |
// |
19 |
// Last changed : $Date: 2009-02-21 18:00:14 +0200 (Sat, 21 Feb 2009) $ |
20 |
// File revision : $Revision: 4 $ |
21 |
// |
22 |
// $Id: WavFile.h 63 2009-02-21 16:00:14Z oparviai $ |
23 |
// |
24 |
//////////////////////////////////////////////////////////////////////////////// |
25 |
// |
26 |
// License : |
27 |
// |
28 |
// SoundTouch audio processing library |
29 |
// Copyright (c) Olli Parviainen |
30 |
// |
31 |
// This library is free software; you can redistribute it and/or |
32 |
// modify it under the terms of the GNU Lesser General Public |
33 |
// License as published by the Free Software Foundation; either |
34 |
// version 2.1 of the License, or (at your option) any later version. |
35 |
// |
36 |
// This library is distributed in the hope that it will be useful, |
37 |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
38 |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
39 |
// Lesser General Public License for more details. |
40 |
// |
41 |
// You should have received a copy of the GNU Lesser General Public |
42 |
// License along with this library; if not, write to the Free Software |
43 |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
44 |
// |
45 |
//////////////////////////////////////////////////////////////////////////////// |
46 |
|
47 |
#ifndef WAVFILE_H |
48 |
#define WAVFILE_H |
49 |
|
50 |
#include <stdio.h> |
51 |
|
52 |
#ifndef uint |
53 |
typedef unsigned int uint; |
54 |
#endif |
55 |
|
56 |
|
57 |
/// WAV audio file 'riff' section header |
58 |
typedef struct |
59 |
{ |
60 |
char riff_char[4]; |
61 |
int package_len; |
62 |
char wave[4]; |
63 |
} WavRiff; |
64 |
|
65 |
/// WAV audio file 'format' section header |
66 |
typedef struct |
67 |
{ |
68 |
char fmt[4]; |
69 |
int format_len; |
70 |
short fixed; |
71 |
short channel_number; |
72 |
int sample_rate; |
73 |
int byte_rate; |
74 |
short byte_per_sample; |
75 |
short bits_per_sample; |
76 |
} WavFormat; |
77 |
|
78 |
/// WAV audio file 'data' section header |
79 |
typedef struct |
80 |
{ |
81 |
char data_field[4]; |
82 |
uint data_len; |
83 |
} WavData; |
84 |
|
85 |
|
86 |
/// WAV audio file header |
87 |
typedef struct |
88 |
{ |
89 |
WavRiff riff; |
90 |
WavFormat format; |
91 |
WavData data; |
92 |
} WavHeader; |
93 |
|
94 |
|
95 |
/// Class for reading WAV audio files. |
96 |
class WavInFile |
97 |
{ |
98 |
private: |
99 |
/// File pointer. |
100 |
FILE *fptr; |
101 |
|
102 |
/// Counter of how many bytes of sample data have been read from the file. |
103 |
uint dataRead; |
104 |
|
105 |
/// WAV header information |
106 |
WavHeader header; |
107 |
|
108 |
/// Init the WAV file stream |
109 |
void init(); |
110 |
|
111 |
/// Read WAV file headers. |
112 |
/// \return zero if all ok, nonzero if file format is invalid. |
113 |
int readWavHeaders(); |
114 |
|
115 |
/// Checks WAV file header tags. |
116 |
/// \return zero if all ok, nonzero if file format is invalid. |
117 |
int checkCharTags() const; |
118 |
|
119 |
/// Reads a single WAV file header block. |
120 |
/// \return zero if all ok, nonzero if file format is invalid. |
121 |
int readHeaderBlock(); |
122 |
|
123 |
/// Reads WAV file 'riff' block |
124 |
int readRIFFBlock(); |
125 |
|
126 |
public: |
127 |
/// Constructor: Opens the given WAV file. If the file can't be opened, |
128 |
/// throws 'runtime_error' exception. |
129 |
WavInFile(const char *filename); |
130 |
|
131 |
WavInFile(FILE *file); |
132 |
|
133 |
/// Destructor: Closes the file. |
134 |
~WavInFile(); |
135 |
|
136 |
/// Rewind to beginning of the file |
137 |
void rewind(); |
138 |
|
139 |
/// Get sample rate. |
140 |
uint getSampleRate() const; |
141 |
|
142 |
/// Get number of bits per sample, i.e. 8 or 16. |
143 |
uint getNumBits() const; |
144 |
|
145 |
/// Get sample data size in bytes. Ahem, this should return same information as |
146 |
/// 'getBytesPerSample'... |
147 |
uint getDataSizeInBytes() const; |
148 |
|
149 |
/// Get total number of samples in file. |
150 |
uint getNumSamples() const; |
151 |
|
152 |
/// Get number of bytes per audio sample (e.g. 16bit stereo = 4 bytes/sample) |
153 |
uint getBytesPerSample() const; |
154 |
|
155 |
/// Get number of audio channels in the file (1=mono, 2=stereo) |
156 |
uint getNumChannels() const; |
157 |
|
158 |
/// Get the audio file length in milliseconds |
159 |
uint getLengthMS() const; |
160 |
|
161 |
/// Reads audio samples from the WAV file. This routine works only for 8 bit samples. |
162 |
/// Reads given number of elements from the file or if end-of-file reached, as many |
163 |
/// elements as are left in the file. |
164 |
/// |
165 |
/// \return Number of 8-bit integers read from the file. |
166 |
int read(char *buffer, int maxElems); |
167 |
|
168 |
/// Reads audio samples from the WAV file to 16 bit integer format. Reads given number |
169 |
/// of elements from the file or if end-of-file reached, as many elements as are |
170 |
/// left in the file. |
171 |
/// |
172 |
/// \return Number of 16-bit integers read from the file. |
173 |
int read(short *buffer, ///< Pointer to buffer where to read data. |
174 |
int maxElems ///< Size of 'buffer' array (number of array elements). |
175 |
); |
176 |
|
177 |
/// Reads audio samples from the WAV file to floating point format, converting |
178 |
/// sample values to range [-1,1[. Reads given number of elements from the file |
179 |
/// or if end-of-file reached, as many elements as are left in the file. |
180 |
/// |
181 |
/// \return Number of elements read from the file. |
182 |
int read(float *buffer, ///< Pointer to buffer where to read data. |
183 |
int maxElems ///< Size of 'buffer' array (number of array elements). |
184 |
); |
185 |
|
186 |
/// Check end-of-file. |
187 |
/// |
188 |
/// \return Nonzero if end-of-file reached. |
189 |
int eof() const; |
190 |
}; |
191 |
|
192 |
|
193 |
|
194 |
/// Class for writing WAV audio files. |
195 |
class WavOutFile |
196 |
{ |
197 |
private: |
198 |
/// Pointer to the WAV file |
199 |
FILE *fptr; |
200 |
|
201 |
/// WAV file header data. |
202 |
WavHeader header; |
203 |
|
204 |
/// Counter of how many bytes have been written to the file so far. |
205 |
int bytesWritten; |
206 |
|
207 |
/// Fills in WAV file header information. |
208 |
void fillInHeader(const uint sampleRate, const uint bits, const uint channels); |
209 |
|
210 |
/// Finishes the WAV file header by supplementing information of amount of |
211 |
/// data written to file etc |
212 |
void finishHeader(); |
213 |
|
214 |
/// Writes the WAV file header. |
215 |
void writeHeader(); |
216 |
|
217 |
public: |
218 |
/// Constructor: Creates a new WAV file. Throws a 'runtime_error' exception |
219 |
/// if file creation fails. |
220 |
WavOutFile(const char *fileName, ///< Filename |
221 |
int sampleRate, ///< Sample rate (e.g. 44100 etc) |
222 |
int bits, ///< Bits per sample (8 or 16 bits) |
223 |
int channels ///< Number of channels (1=mono, 2=stereo) |
224 |
); |
225 |
|
226 |
WavOutFile(FILE *file, int sampleRate, int bits, int channels); |
227 |
|
228 |
/// Destructor: Finalizes & closes the WAV file. |
229 |
~WavOutFile(); |
230 |
|
231 |
/// Write data to WAV file. This function works only with 8bit samples. |
232 |
/// Throws a 'runtime_error' exception if writing to file fails. |
233 |
void write(const char *buffer, ///< Pointer to sample data buffer. |
234 |
int numElems ///< How many array items are to be written to file. |
235 |
); |
236 |
|
237 |
/// Write data to WAV file. Throws a 'runtime_error' exception if writing to |
238 |
/// file fails. |
239 |
void write(const short *buffer, ///< Pointer to sample data buffer. |
240 |
int numElems ///< How many array items are to be written to file. |
241 |
); |
242 |
|
243 |
/// Write data to WAV file in floating point format, saturating sample values to range |
244 |
/// [-1..+1[. Throws a 'runtime_error' exception if writing to file fails. |
245 |
void write(const float *buffer, ///< Pointer to sample data buffer. |
246 |
int numElems ///< How many array items are to be written to file. |
247 |
); |
248 |
}; |
249 |
|
250 |
#endif |