102 const bool debug =
false;
108 vector<AudioChannel> channels;
110 union ShortByteUnion {
111 signed short asShort;
112 unsigned char asBytes[2];
123 AudioClip(
int sampleCount,
int numChannels,
int sampleBits,
int sampleRate) {
124 if (sampleCount > 1000000000) {
125 throw "sampleCount must be less than 1 million";
128 if (sampleBits != 8 && sampleBits != 16 && sampleBits != 24 && sampleBits != 32) {
129 throw "sampleBits must be either 8, 16, 24, or 32";
132 if (numChannels <= 0) {
133 throw "numChannels should be positive";
136 if (sampleRate <= 0) {
137 throw "sampleRate should be positive";
140 this->sampleCount = sampleCount;
141 this->numChannels = numChannels;
142 this->channels = vector<AudioChannel>();
144 for (
int i = 0; i < numChannels; i++) {
147 for (
int j = 0; j < sampleCount; j++) {
148 this->channels[i].setSample(j, 0);
152 this->sampleRate = sampleRate;
153 this->sampleBits = sampleBits;
167 parseWaveFile (wave_file);
174 int len = numChannels * sampleCount * (sampleBits / 8);
175 std::vector<BYTE> byteBuff;
177 int checkSampleBits = sampleBits;
179 for (
int i = 0; i < sampleCount; i++) {
180 for (
int c = 0; c < numChannels; c++) {
183 if (this->sampleBits == 8) {
184 byteBuff.push_back(num & 0x000000FF);
186 else if (this->sampleBits == 16) {
188 sbu.asShort = (uint16_t)num;
189 byteBuff.push_back(sbu.asBytes[0]);
190 byteBuff.push_back(sbu.asBytes[1]);
192 else if (this->sampleBits == 32 || this->sampleBits == 24) {
194 int minmax = (int)((pow(2, sampleBits) / 2) - 1);
195 int minmax16 = (int)((pow(2, 16) / 2) - 1);
197 num = (int)((num / (
float)minmax) * minmax16) & 0xFFFF;
200 sbu.asShort = (uint16_t)num;
201 byteBuff.push_back(sbu.asBytes[0]);
202 byteBuff.push_back(sbu.asBytes[1]);
203 checkSampleBits = 16;
225 return this->numChannels;
233 return this->sampleRate;
244 return this->sampleCount;
261 return this->sampleBits;
265 if (bit_depth == 8 || bit_depth == 16 || bit_depth == 24 || bit_depth == 32)
266 this->sampleBits = bit_depth;
268 cerr <<
"Bit rate must 8,16,24 or 32!" <<
"\n";
280 int getSample(
int channelIndex,
int sampleIndex)
const {
281 return channels.at(channelIndex).getSample(sampleIndex);
291 void setSample(
int channelIndex,
int sampleIndex,
int value) {
294 throw "Audio value Out of Bound";
296 channels[channelIndex].setSample(sampleIndex, value);
307 void parseWaveFile (
const string & wave_file) {
313 std::cerr<<
"Opening "<<wave_file<<
"\n";
314 infile.open (wave_file.c_str(), ios::binary | ios::in);
316 throw "Could not open " + wave_file;
320 WaveHeader wave_header = readWaveHeader(infile);
322 long size_of_each_sample = (wave_header.
channels *
327 if (this->sampleCount > 1000000000) {
328 throw "sampleCount must be less than 1 million";
333 for (
int i = 0; i < numChannels; i++) {
334 this->channels.push_back(
AudioChannel(this->sampleCount));
341 std::vector<char> data_buffer (size_of_each_sample);
342 int size_is_correct =
true;
346 long bytes_in_each_channel = (size_of_each_sample / wave_header.
channels);
347 if ((bytes_in_each_channel * wave_header.
channels) != size_of_each_sample) {
348 cout <<
"Error: Incorrect chunk size.. " << bytes_in_each_channel
349 <<
", " << wave_header.
channels <<
", " << size_of_each_sample <<
"\n";
350 size_is_correct =
false;
353 if (size_is_correct) {
356 long high_limit = 0
l;
368 low_limit = -16777216;
369 high_limit = 16777215;
372 low_limit = -2147483648;
373 high_limit = 2147483647;
376 for (
int sample = 0; sample < this->sampleCount;
379 if (!infile.fail()) {
380 for (
int ch = 0; ch < wave_header.
channels;
383 infile.read(&(data_buffer[0]), bytes_in_each_channel);
386 switch (bytes_in_each_channel) {
388 amplitude = data_buffer[0] & 0x00ff;
393 (data_buffer[0] & 0x00ff) |
394 (data_buffer[1] << 8);
398 (data_buffer[0] & 0x00ff) |
399 ((data_buffer[1] & 0x00ff) << 8) |
400 (data_buffer[2] << 16);
404 (data_buffer[0] & 0x00ff) |
405 ((data_buffer[1] & 0x00ff) << 8) |
406 ((data_buffer[2] & 0x00ff) << 16) |
407 (data_buffer[3] << 24);
414 cout <<
"Error reading file\n.";
427 WaveHeader readWaveHeader(ifstream& infile) {
430 WaveHeader wave_header;
432 infile.read ((
char *)wave_header.riff, 4);
434 if (wave_header.riff[0] !=
'R' ||
435 wave_header.riff[1] !=
'I' ||
436 wave_header.riff[2] !=
'F' ||
437 wave_header.riff[3] !=
'F')
438 throw "malformed RIFF header";
440 unsigned char *buffer =
new unsigned char[4];
441 infile.read ((
char*) buffer, 4);
444 wave_header.
overall_size = buffer[0] | (buffer[1] << 8) |
445 (buffer[2] << 16) | (buffer[3] << 24);
448 std::cout <<
"overall size: " << wave_header.overall_size << std::endl;
450 infile.read ((
char*) wave_header.wave, 4);
452 if (wave_header.wave[0] !=
'W' ||
453 wave_header.wave[1] !=
'A' ||
454 wave_header.wave[2] !=
'V' ||
455 wave_header.wave[3] !=
'E')
456 throw "format is not WAVE";
458 infile.read ((
char*) wave_header.fmt_chunk_marker, 4);
459 if (wave_header.fmt_chunk_marker[0] !=
'f' ||
460 wave_header.fmt_chunk_marker[1] !=
'm' ||
461 wave_header.fmt_chunk_marker[2] !=
't' ||
462 wave_header.fmt_chunk_marker[3] !=
' ')
463 throw "malformed wave file";
465 infile.read ((
char *) buffer, 4);
466 wave_header.length_of_fmt = buffer[0] | (buffer[1] << 8) |
467 (buffer[2] << 16) | (buffer[3] << 24);
470 std::cout <<
"length of format: " << wave_header.length_of_fmt << std::endl;
472 char *buffer2 =
new char[2];
473 infile.read (buffer2, 2);
474 wave_header.format_type = buffer2[0] | (buffer2[1] << 8);
476 string format_name =
"";
477 switch (wave_header.format_type) {
482 format_name =
"A-law";
485 format_name =
"Mu-law";
488 throw "unsupported format";
492 infile.read (buffer2, 2);
493 wave_header.channels = buffer2[0] | (buffer2[1] << 8);
494 this->numChannels = wave_header.channels;
497 std::cout <<
"numChannels: " << numChannels << std::endl;
499 infile.read ((
char *) buffer, 4);
500 wave_header.sample_rate = buffer[0] | (buffer[1] << 8) |
501 (buffer[2] << 16) | (buffer[3] << 24);
502 this->sampleRate = wave_header.sample_rate;
505 std::cout <<
"sampleRate: " << sampleRate << std::endl;
507 infile.read ((
char *) buffer, 4);
508 wave_header.byterate = buffer[0] | (buffer[1] << 8) |
509 (buffer[2] << 16) | (buffer[3] << 24);
512 std::cout <<
"byte rate: " << wave_header.byterate << std::endl;
514 infile.read (buffer2, 2);
515 wave_header.block_align = buffer2[0] | (buffer2[1] << 8);
517 infile.read (buffer2, 2);
518 wave_header.bits_per_sample = buffer2[0] | (buffer2[1] << 8);
520 this->sampleBits = wave_header.bits_per_sample;
523 std::cout <<
"sample Bits: " << sampleBits << std::endl;
525 if (wave_header.byterate !=
526 wave_header.sample_rate * wave_header.channels * wave_header.bits_per_sample / 8)
527 throw "malformed wave file";
532 bool data_chunk_found =
false;
533 while (!data_chunk_found) {
534 if (! infile.good()) {
536 std::cerr<<
"somehow not good before data chunk is reached\n";
537 throw "malformed wave file";
539 infile.read ((
char *)wave_header.data_chunk_header, 4);
541 infile.read ((
char *) buffer, 4);
542 wave_header.data_size = buffer[0] | (buffer[1] << 8) |
543 (buffer[2] << 16) | (buffer[3] << 24);
545 if (wave_header.data_chunk_header[0] !=
'd' ||
546 wave_header.data_chunk_header[1] !=
'a' ||
547 wave_header.data_chunk_header[2] !=
't' ||
548 wave_header.data_chunk_header[3] !=
'a') {
550 std::cerr<<
"ignoring sub chunk "
551 <<wave_header.data_chunk_header[0]
552 <<wave_header.data_chunk_header[1]
553 <<wave_header.data_chunk_header[2]
554 <<wave_header.data_chunk_header[3]
557 int padding = (wave_header.data_size % 2 ? 1 : 0);
558 infile.ignore(wave_header.data_size + padding);
561 data_chunk_found =
true;
565 long num_samples = (8 * wave_header.data_size) /
566 (wave_header.channels * wave_header.bits_per_sample);
567 this->sampleCount = num_samples;
570 std::cout <<
"sample Count: " << this->sampleCount << std::endl;
572 long size_of_each_sample = (wave_header.channels *
573 wave_header.bits_per_sample) / 8;
579 throw "malformed RIFF header";