OpenWareLaboratory
WavFile.h
Go to the documentation of this file.
1 #ifndef __WavFile_h__
2 #define __WavFile_h__
3 
4 #include "IntArray.h"
5 #include "ShortArray.h"
6 #include "FloatArray.h"
7 
8 // http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html
9 
10 typedef struct {
11  char id[4];
12  uint32_t size;
13 } WavDataChunk;
14 
15 typedef struct {
16  char chunk_id[4];
17  uint32_t chunk_size;
18  char format[4];
19  char fmtchunk_id[4];
20  uint32_t fmtchunk_size; // Chunk size: 16, 18 or 40
21  uint16_t audio_format; // 1 = PCM, 3 = float
22  uint16_t num_channels;
23  uint32_t sample_rate;
24  uint32_t byte_rate;
25  uint16_t block_align;
26  uint16_t bps;
27 } WavHeader;
28 
29 class WavFile {
30  WavHeader* header;
31  WavDataChunk* datachunk;
32  size_t size;
33 public:
34  WavFile(void* data, size_t len) : header((WavHeader*)data), size(len) {
35  datachunk = (WavDataChunk*)(header->fmtchunk_id + 8 + header->fmtchunk_size);
36  void* end = (uint8_t*)data+len;
37  // iterate through data chunks to find one with id 'data'
38  while(datachunk->id + datachunk->size < end && strncmp(datachunk->id, "data", 4) != 0)
39  datachunk = (WavDataChunk*)(datachunk->id + sizeof(WavDataChunk) + datachunk->size);
40  }
42  return header;
43  }
44  bool isValid(){
45  if(!header || !datachunk ||
46  strncmp(header->chunk_id, "RIFF", 4) ||
47  strncmp(header->format, "WAVE", 4) ||
48  strncmp(datachunk->id, "data", 4) ||
49  datachunk->size == 0)
50  return false;
51  if(getNumberOfChannels() == 0 || getNumberOfSamples() == 0)
52  return false;
53  if(header->audio_format == 1 && header->bps == 8)
54  return true; // 8-bit PCM
55  if(header->audio_format == 1 && header->bps == 16)
56  return true; // 16-bit PCM
57  // if(header->audio_format == 1 && header->bps == 24)
58  // return true; // 24-bit PCM
59  if(header->audio_format == 3 && header->bps == 32)
60  return true; // 32-bit float
61  return false;
62  }
63 
65  return header->num_channels;
66  }
68  size_t total = datachunk->size/(header->bps/8);
69  return total/getNumberOfChannels();
70  }
71  size_t getSize(){
72  return size;
73  }
74  size_t getBitsPerSample(){
75  return header->bps;
76  }
77  int16_t getAudioFormat(){
78  return header->audio_format;
79  }
80  void* getData(){
81  return datachunk->id + sizeof(WavDataChunk);
82  }
83  void read(size_t channel, FloatArray output){
84  size_t channels = getNumberOfChannels();
85  size_t len = getNumberOfSamples();
86  if(len > output.getSize())
87  len = output.getSize();
88  size_t pos = channel % channels;
89  if(header->audio_format == 1 && header->bps == 8){ // WAVE_FORMAT_PCM 8-bit
90  int8_t* data = (int8_t*)getData();
91  for(size_t i=0; i<len; ++i){
92  output[i] = (float)data[pos] / 128.0f;
93  pos += channels;
94  }
95  }else if(header->audio_format == 1 && header->bps == 16){ // WAVE_FORMAT_PCM 16-bit
96  int16_t* data = (int16_t*)getData();
97  for(size_t i=0; i<len; ++i){
98  output[i] = (float)data[pos] / 32768.0f;
99  pos += channels;
100  }
101  // todo: 24-bit data needs decoding
102  // }else if(header->audio_format == 1 && header->bps == 24){ // WAVE_FORMAT_PCM 24-bit
103  // int32_t* data = (int32_t*)getData();
104  // for(size_t i=0; i<len; ++i){
105  // output[i] = (float)data[pos] / 8388608.0f;
106  // pos += channels;
107  // }
108  }else if(header->audio_format == 3 && header->bps == 32){ // WAVE_FORMAT_IEEE_FLOAT
109  float* data = (float*)getData();
110  for(size_t i=0; i<len; ++i){
111  output[i] = data[pos];
112  pos += channels;
113  }
114  }
115  }
116  FloatArray createFloatArray(size_t channel){
118  read(channel, output);
119  return output;
120  }
121 };
122 
123 #endif // __WavFile_h__
This class contains useful methods for manipulating arrays of floats.
Definition: FloatArray.h:12
static FloatArray create(int size)
Creates a new FloatArray.
Definition: FloatArray.cpp:466
size_t getSize() const
Definition: SimpleArray.h:31
size_t getNumberOfChannels()
Definition: WavFile.h:64
int16_t getAudioFormat()
Definition: WavFile.h:77
FloatArray createFloatArray(size_t channel)
Definition: WavFile.h:116
WavFile(void *data, size_t len)
Definition: WavFile.h:34
WavHeader * getHeader()
Definition: WavFile.h:41
size_t getBitsPerSample()
Definition: WavFile.h:74
void * getData()
Definition: WavFile.h:80
size_t getSize()
Definition: WavFile.h:71
size_t getNumberOfSamples()
Definition: WavFile.h:67
bool isValid()
Definition: WavFile.h:44
void read(size_t channel, FloatArray output)
Definition: WavFile.h:83
uint32_t size
Definition: WavFile.h:12
char id[4]
Definition: WavFile.h:11
uint16_t num_channels
Definition: WavFile.h:22
uint16_t audio_format
Definition: WavFile.h:21
uint32_t chunk_size
Definition: WavFile.h:17
uint32_t fmtchunk_size
Definition: WavFile.h:20
uint16_t block_align
Definition: WavFile.h:25
char fmtchunk_id[4]
Definition: WavFile.h:19
uint16_t bps
Definition: WavFile.h:26
uint32_t byte_rate
Definition: WavFile.h:24
char format[4]
Definition: WavFile.h:18
char chunk_id[4]
Definition: WavFile.h:16
uint32_t sample_rate
Definition: WavFile.h:23