-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAudioFile.h
172 lines (137 loc) · 6.65 KB
/
AudioFile.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
//=======================================================================
/** @file AudioFile.h
* @author Adam Stark
* @copyright Copyright (C) 2017 Adam Stark
*
* This file is part of the 'AudioFile' library
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//=======================================================================
#ifndef _AS_AudioFile_h
#define _AS_AudioFile_h
#include <iostream>
#include <vector>
#include <assert.h>
#include <string>
//=============================================================
/** The different types of audio file, plus some other types to
* indicate a failure to load a file, or that one hasn't been
* loaded yet
*/
enum class AudioFileFormat
{
Error,
NotLoaded,
Wave,
Aiff
};
//=============================================================
template <class T>
class AudioFile
{
public:
//=============================================================
typedef std::vector<std::vector<T> > AudioBuffer;
//=============================================================
/** Constructor */
AudioFile();
//=============================================================
/** Loads an audio file from a given file path.
* @Returns true if the file was successfully loaded
*/
bool load (std::string filePath);
/** Saves an audio file to a given file path.
* @Returns true if the file was successfully saved
*/
bool save (std::string filePath, AudioFileFormat format = AudioFileFormat::Wave);
//=============================================================
/** @Returns the sample rate */
uint32_t getSampleRate() const;
/** @Returns the number of audio channels in the buffer */
int getNumChannels() const;
/** @Returns true if the audio file is mono */
bool isMono() const;
/** @Returns true if the audio file is stereo */
bool isStereo() const;
/** @Returns the bit depth of each sample */
int getBitDepth() const;
/** @Returns the number of samples per channel */
int getNumSamplesPerChannel() const;
/** @Returns the length in seconds of the audio file based on the number of samples and sample rate */
double getLengthInSeconds() const;
/** Prints a summary of the audio file to the console */
void printSummary() const;
//=============================================================
/** Set the audio buffer for this AudioFile by copying samples from another buffer.
* @Returns true if the buffer was copied successfully.
*/
bool setAudioBuffer (AudioBuffer& newBuffer);
/** Sets the audio buffer to a given number of channels and number of samples per channel. This will try to preserve
* the existing audio, adding zeros to any new channels or new samples in a given channel.
*/
void setAudioBufferSize (int numChannels, int numSamples);
/** Sets the number of samples per channel in the audio buffer. This will try to preserve
* the existing audio, adding zeros to new samples in a given channel if the number of samples is increased.
*/
void setNumSamplesPerChannel (int numSamples);
/** Sets the number of channels. New channels will have the correct number of samples and be initialised to zero */
void setNumChannels (int numChannels);
/** Sets the bit depth for the audio file. If you use the save() function, this bit depth rate will be used */
void setBitDepth (int numBitsPerSample);
/** Sets the sample rate for the audio file. If you use the save() function, this sample rate will be used */
void setSampleRate (uint32_t newSampleRate);
//=============================================================
/** A vector of vectors holding the audio samples for the AudioFile. You can
* access the samples by channel and then by sample index, i.e:
*
* samples[channel][sampleIndex]
*/
AudioBuffer samples;
private:
//=============================================================
enum class Endianness
{
LittleEndian,
BigEndian
};
//=============================================================
AudioFileFormat determineAudioFileFormat (std::vector<uint8_t>& fileData);
bool decodeWaveFile (std::vector<uint8_t>& fileData);
bool decodeAiffFile (std::vector<uint8_t>& fileData);
//=============================================================
bool saveToWaveFile (std::string filePath);
bool saveToAiffFile (std::string filePath);
//=============================================================
void clearAudioBuffer();
//=============================================================
int32_t fourBytesToInt (std::vector<uint8_t>& source, int startIndex, Endianness endianness = Endianness::LittleEndian);
int16_t twoBytesToInt (std::vector<uint8_t>& source, int startIndex, Endianness endianness = Endianness::LittleEndian);
int getIndexOfString (std::vector<uint8_t>& source, std::string s);
T sixteenBitIntToSample (int16_t sample);
uint32_t getAiffSampleRate (std::vector<uint8_t>& fileData, int sampleRateStartIndex);
bool tenByteMatch (std::vector<uint8_t>& v1, int startIndex1, std::vector<uint8_t>& v2, int startIndex2);
void addSampleRateToAiffData (std::vector<uint8_t>& fileData, uint32_t sampleRate);
//=============================================================
void addStringToFileData (std::vector<uint8_t>& fileData, std::string s);
void addInt32ToFileData (std::vector<uint8_t>& fileData, int32_t i, Endianness endianness = Endianness::LittleEndian);
void addInt16ToFileData (std::vector<uint8_t>& fileData, int16_t i, Endianness endianness = Endianness::LittleEndian);
//=============================================================
bool writeDataToFile (std::vector<uint8_t>& fileData, std::string filePath);
//=============================================================
AudioFileFormat audioFileFormat;
uint32_t sampleRate;
int bitDepth;
};
#endif /* AudioFile_h */