5 #include "rapidjson/stringbuffer.h" 35 riff =
new unsigned char[4];
36 wave =
new unsigned char[4];
37 fmt_chunk_marker =
new unsigned char[4];
38 data_chunk_header =
new unsigned char[4];
44 delete[] fmt_chunk_marker;
45 delete[] data_chunk_header;
49 namespace datastructure {
121 vector<AudioChannel *> channels;
123 union ShortByteUnion {
124 signed short asShort;
125 unsigned char asBytes[2];
136 AudioClip(
int sampleCount,
int numChannels,
int sampleBits,
int sampleRate) {
137 if (sampleCount > 1000000000) {
138 throw "sampleCount must be less than 1 million";
142 if (sampleBits != 8 && sampleBits != 16 && sampleBits != 24 && sampleBits != 32) {
143 throw "sampleBits must be either 8, 16, 24, or 32";
146 if (numChannels <= 0) {
147 throw "numChannels should be positive";
150 if (sampleRate <= 0) {
151 throw "sampleRate should be positive";
156 this->sampleCount = sampleCount;
157 this->numChannels = numChannels;
158 this->channels = vector<AudioChannel *>(numChannels);
160 for (
int i = 0; i < numChannels; i++) {
163 for (
int j = 0; j < sampleCount; j++) {
164 this->channels[i]->setSample(j, 0);
168 this->sampleRate = sampleRate;
169 this->sampleBits = sampleBits;
183 parseWaveFile (wave_file);
188 for (
int i = 0; i < numChannels; i++) {
190 channels[i] =
nullptr;
197 int len = numChannels * sampleCount * (sampleBits / 8);
198 std::vector<BYTE> byteBuff;
200 int checkSampleBits = sampleBits;
202 for (
int i = 0; i < sampleCount; i++) {
203 for (
int c = 0; c < numChannels; c++) {
204 int num = getSample(c, i);
206 if (this->sampleBits == 8) {
207 byteBuff.push_back(num & 0x000000FF);
209 else if (this->sampleBits == 16) {
211 sbu.asShort = (uint16_t)num;
212 byteBuff.push_back(sbu.asBytes[0]);
213 byteBuff.push_back(sbu.asBytes[1]);
215 else if (this->sampleBits == 32 || this->sampleBits == 24) {
217 int minmax = (int)((pow(2, sampleBits) / 2) - 1);
218 int minmax16 = (int)((pow(2, 16) / 2) - 1);
220 num = (int)((num / (
float)minmax) * minmax16) & 0xFFFF;
223 sbu.asShort = (uint16_t)num;
224 byteBuff.push_back(sbu.asBytes[0]);
225 byteBuff.push_back(sbu.asBytes[1]);
226 checkSampleBits = 16;
248 return this->numChannels;
256 return this->sampleRate;
267 return this->sampleCount;
285 return this->sampleBits;
297 int getSample(
int channelIndex,
int sampleIndex)
const {
298 return channels.at(channelIndex)->getSample(sampleIndex);
308 void setSample(
int channelIndex,
int sampleIndex,
int value) {
309 if (value >= pow(2, getSampleBits() - 1) ||
310 value < -pow(2, getSampleBits() - 1))
311 throw "Audio value Out of Bound";
313 channels[channelIndex]->setSample(sampleIndex, value);
324 void parseWaveFile (
string wave_file) {
329 infile.open (wave_file.c_str(), ios::binary | ios::in);
331 cout <<
"Couldnt open " << wave_file << endl;
336 WaveHeader wave_header = readWaveHeader(infile);
338 long size_of_each_sample = (wave_header.
channels *
342 if (this->sampleCount > 1000000000) {
343 throw "sampleCount must be less than 1 million";
347 this->channels.resize(this->numChannels);
348 for (
int i = 0; i < numChannels; i++) {
349 this->channels[i] =
new AudioChannel(this->sampleCount);
355 char data_buffer[size_of_each_sample];
356 int size_is_correct =
true;
360 long bytes_in_each_channel = (size_of_each_sample / wave_header.
channels);
361 if ((bytes_in_each_channel * wave_header.
channels) != size_of_each_sample) {
362 cout <<
"Error: Incorrect chunk size.. " << bytes_in_each_channel
363 <<
", " << wave_header.
channels <<
", " << size_of_each_sample <<
"\n";
364 size_is_correct =
false;
367 if (size_is_correct) {
370 long high_limit = 0l;
382 low_limit = -16777216;
383 high_limit = 16777215;
386 low_limit = -2147483648;
387 high_limit = 2147483647;
390 for (
int sample = 0; sample < this->sampleCount;
393 if (!infile.fail()) {
394 for (
int ch = 0; ch < wave_header.
channels;
397 infile.read(data_buffer, bytes_in_each_channel);
400 switch (bytes_in_each_channel) {
402 amplitude = data_buffer[0] & 0x00ff;
407 (data_buffer[0] & 0x00ff) |
408 (data_buffer[1] << 8);
412 (data_buffer[0] & 0x00ff) |
413 ((data_buffer[1] & 0x00ff) << 8) |
414 (data_buffer[2] << 16);
418 (data_buffer[0] & 0x00ff) |
419 ((data_buffer[1] & 0x00ff) << 8) |
420 ((data_buffer[2] & 0x00ff) << 16) |
421 (data_buffer[3] << 24);
424 this->setSample(ch, sample, amplitude);
428 cout <<
"Error reading file\n.";
441 infile.read ((
char *)wave_header.
riff, 4);
443 unsigned char *buffer =
new unsigned char[4];
444 infile.read ((
char*) buffer, 4);
447 wave_header.
overall_size = buffer[0] | (buffer[1] << 8) |
448 (buffer[2] << 16) | (buffer[3] << 24);
451 infile.read ((
char*) wave_header.
wave, 4);
454 infile.read ((
char *) buffer, 4);
456 (buffer[2] << 16) | (buffer[3] << 24);
458 char *buffer2 =
new char[2];
459 infile.read (buffer2, 2);
460 wave_header.
format_type = buffer2[0] | (buffer2[1] << 8);
462 string format_name =
"";
468 format_name =
"A-law";
471 format_name =
"Mu-law";
475 infile.read (buffer2, 2);
476 wave_header.
channels = buffer2[0] | (buffer2[1] << 8);
477 this->numChannels = wave_header.
channels;
479 infile.read ((
char *) buffer, 4);
480 wave_header.
sample_rate = buffer[0] | (buffer[1] << 8) |
481 (buffer[2] << 16) | (buffer[3] << 24);
484 infile.read ((
char *) buffer, 4);
485 wave_header.
byterate = buffer[0] | (buffer[1] << 8) |
486 (buffer[2] << 16) | (buffer[3] << 24);
488 infile.read (buffer2, 2);
489 wave_header.
block_align = buffer2[0] | (buffer2[1] << 8);
491 infile.read (buffer2, 2);
498 infile.read ((
char *) buffer, 4);
499 wave_header.
data_size = buffer[0] | (buffer[1] << 8) |
500 (buffer[2] << 16) | (buffer[3] << 24);
503 long num_samples = (8 * wave_header.
data_size) /
505 this->sampleCount = num_samples;
507 long size_of_each_sample = (wave_header.
channels *
virtual const string getDataStructureRepresentation() const override final
Definition: AudioClip.h:194
This is the superclass of all data structure types in BRIDGES.
Definition: DataStructure.h:73
string encode(BYTE const *buf, unsigned int bufLen)
Definition: base64.h:59
const string COLON
Definition: DataStructure.h:51
Definition: AudioChannel.h:4
virtual const string getDStype() const override
Definition: AudioClip.h:172
virtual ~AudioClip()
Definition: AudioClip.h:187
This class provides support for reading, modifying, and playing audio waveforms.
Definition: AudioClip.h:115
const string CLOSE_CURLY
Definition: DataStructure.h:53
int getSampleCount() const
returns the number of samples in the clip
Definition: AudioClip.h:266
AudioClip(int sampleCount, int numChannels, int sampleBits, int sampleRate)
create an audio clip
Definition: AudioClip.h:136
these methods convert byte arrays in to base64 codes and are used in BRIDGES to represent the color a...
Definition: alltypes.h:4
int getSampleBits() const
returns the sampling depth.
Definition: AudioClip.h:284
void setSample(int channelIndex, int sampleIndex, int value)
change a particular sample
Definition: AudioClip.h:308
int getSampleRate() const
returns the sampling rate of the clip
Definition: AudioClip.h:255
const string COMMA
Definition: DataStructure.h:50
const string QUOTE
Definition: DataStructure.h:49
AudioClip(string wave_file)
create an audio clip from a File
Definition: AudioClip.h:182
int getSample(int channelIndex, int sampleIndex) const
access a particular sample
Definition: AudioClip.h:297
int getNumChannels() const
returns the number of channels of the clip
Definition: AudioClip.h:247
std::string JSONencode(const T &d)
Definition: JSONutil.h:37