Eric Oulashin's C++ Audio Mixer 1.0
WAVFile.h
Go to the documentation of this file.
1#ifndef __EO_UTILS_WAVFILE_H__
2#define __EO_UTILS_WAVFILE_H__
3
4#include "AudioFile.h"
5#include "WAVFileInfo.h"
7#include "EOUtils.h"
8#include <string>
9#include <fstream>
10#include <sstream>
11
12
13namespace EOUtils
14{
15 class WAVFile : public AudioFile
16 {
17 public:
18 WAVFile(const std::string& pFilename);
19
20 WAVFile(const std::string& pFilename, const WAVFileInfo& pWAVFileInfo);
21
22 WAVFile(const std::string& pFilename, AudioFileModes pFileMode);
23
24 WAVFile(const WAVFile& pWAVFile);
25
26 ~WAVFile();
27
28 void setAudioFileInfo(const AudioFileInfo& pAudioFileInfo) override;
29
30 AudioFileResultType open(AudioFileModes pOpenMode) override;
31
35 void close() override;
36
40 const WAVFileInfo& getFileInfo() const;
41
49 AudioFileResultType getNextSample_int64(int64_t& pAudioSample) override;
50
59 AudioFileResultType writeSample_int64(int64_t pAudioSample) override;
60
68 AudioFileResultType getHighestSampleValue_int64(int64_t& pHighestAudioSample) override;
69
78 template <class SampleType>
79 AudioFileResultType getNextSample(SampleType& pAudioSample)
80 {
81 pAudioSample = 0;
82
84 if (!hasReadMode())
85 {
86 result.addError("Can't get next audio file sample: Not in read mode");
87 return result;
88 }
89
90 // If the audio sample size is more than the size of the data type being used, then return an error.
91 if ((size_t)(mWAVFileInfo.BitsPerSample() / BITS_PER_BYTE) > sizeof(pAudioSample))
92 {
93 std::ostringstream oss;
94 oss << "Audio sample size (" << mWAVFileInfo.BitsPerSample() << " bits) is more than data type size (" << (sizeof(SampleType) * BITS_PER_BYTE) << " bits)";
95 result.addError(oss.str());
96 return result;
97 }
98
99 // If the file isn't open, then return an error
100 if (!mFileStream.is_open())
101 {
102 result.addError("WAVFile::getNextSample(): The file is not open");
103 return result;
104 }
105
106 if (mFileStream.eof())
107 {
108 result.addError("At end of file");
109 return result;
110 }
111
112 // Note: Right after opening the file, the header should have been read, so the file should
113 // be ready for reading a sample.
114 const size_t sampleSize = (mWAVFileInfo.BytesPerSample() < sizeof(SampleType) ? mWAVFileInfo.BytesPerSample() : sizeof(SampleType));
115 mFileStream.read((char*)&pAudioSample, sampleSize);
116 if ((sizeof(pAudioSample) > 1) && machineIsBigEndian)
117 reverseBytes((void*)&pAudioSample, sizeof(pAudioSample));
118
119 return result;
120 }
121
130 template <class SampleType>
131 AudioFileResultType writeSample(SampleType pAudioSample)
132 {
134 if (!hasWriteMode())
135 {
136 result.addError("Can't write audio sample: Not in write mode");
137 return result;
138 }
139
140 if (mFileStream.is_open())
141 {
142 if ((sizeof(pAudioSample) > 1) && machineIsBigEndian)
143 reverseBytes((void*)&pAudioSample, sizeof(pAudioSample));
144 const size_t sampleSize = (mWAVFileInfo.BytesPerSample() < sizeof(pAudioSample) ? mWAVFileInfo.BytesPerSample() : sizeof(pAudioSample));
145 mFileStream.write((const char*)&pAudioSample, sampleSize);
146 mDataSizeBytes += sizeof(pAudioSample);
147 }
148 else
149 result.addError("WAVFile::writeSample(): The file is not open");
150
151 return result;
152 }
153
158
162 size_t numSamples() const override;
163
167 int64_t maxValueForSampleSize() const override;
168
169 void seekOutputToSampleNum(size_t pSampleNum) override;
170
179 template <class SampleType>
181 {
182 pAudioSample = 0;
183
185 if (!mFileStream.is_open())
186 {
187 result.addError("WAVFile::getHighestSamplevalue(): The file is not open");
188 return result;
189 }
190
191 // Seek to the end of the WAV header and read through to find the highest sample value
193 SampleType sampleValue = 0;
194 SampleType highestSampleValue = 0;
195 const size_t numAudioSamples = numSamples();
196 for (size_t i = 0; (i < numAudioSamples) && result; ++i)
197 {
198 result = getNextSample(sampleValue);
199 if (result)
200 {
201 if (sampleValue > highestSampleValue)
202 highestSampleValue = sampleValue;
203 }
204 }
205
206 if (result)
207 pAudioSample = highestSampleValue;
208
210
211 return result;
212 }
213
214 template <class SampleType>
215 static AudioFileResultType getHighestSampleValue(const char* pFilename, SampleType& pAudioSample)
216 {
217 pAudioSample = 0;
218 WAVFile inFile(pFilename);
220 if (result)
221 {
222 inFile.getHighestSampleValue(pAudioSample);
223 inFile.close();
224 }
225 return result;
226 }
227
228 AudioFileInfo getAudioFileInfo() const override;
229
230
231 private:
232 WAVFileInfo mWAVFileInfo;
233 };
234}
235
236#endif
#define BITS_PER_BYTE
Definition AudioFileInfo.h:11
AudioFileResultType * result
Definition FLACFileInfo.cpp:24
Definition AudioFileInfo.h:14
virtual size_t BytesPerSample() const
Definition AudioFileInfo.cpp:120
Definition AudioFileResultType.h:13
void addError(const std::string &pError)
Definition AudioFileResultType.cpp:19
Definition AudioFile.h:22
size_t mDataSizeBytes
Definition AudioFile.h:233
virtual bool hasWriteMode() const
Returns whether or not write mode is enabled for the file.
Definition AudioFile.cpp:64
virtual bool hasReadMode() const
Returns whether or not read mode is enabled for the file.
Definition AudioFile.cpp:59
std::fstream mFileStream
Definition AudioFile.h:231
Definition WAVFileInfo.h:15
int16_t BitsPerSample() const
Definition WAVFileInfo.cpp:258
Definition WAVFile.h:16
WAVFile(const std::string &pFilename)
AudioFileResultType goToAudioDataPos() override
Goes to the audio data position in the WAV file.
Definition WAVFile.cpp:220
const WAVFileInfo & getFileInfo() const
Returns a WAVFileInfo object with information about the WAV file.
Definition WAVFile.cpp:129
WAVFile(const std::string &pFilename, AudioFileModes pFileMode)
AudioFileResultType writeSample(SampleType pAudioSample)
Writes an audio sample to the file. This is templated so that the proper variable type can be used fo...
Definition WAVFile.h:131
void seekOutputToSampleNum(size_t pSampleNum) override
Definition WAVFile.cpp:259
~WAVFile()
Definition WAVFile.cpp:39
static AudioFileResultType getHighestSampleValue(const char *pFilename, SampleType &pAudioSample)
Definition WAVFile.h:215
AudioFileResultType open(AudioFileModes pOpenMode) override
Definition WAVFile.cpp:51
AudioFileResultType getNextSample_int64(int64_t &pAudioSample) override
Gets the next sample from the file, cast to a 64-bit integer.
Definition WAVFile.cpp:134
void close() override
Closes the WAV file.
Definition WAVFile.cpp:108
void setAudioFileInfo(const AudioFileInfo &pAudioFileInfo) override
Definition WAVFile.cpp:44
AudioFileResultType getHighestSampleValue(SampleType &pAudioSample)
Gets the highest audio sample value from the file. This is templated so that the proper variable type...
Definition WAVFile.h:180
AudioFileResultType writeSample_int64(int64_t pAudioSample) override
Writes an audio sample to the file. The parameter is a 64-bit integer but will be cast to the bitness...
Definition WAVFile.cpp:168
AudioFileInfo getAudioFileInfo() const override
Returns an AudioFile object with information about the audio file.
Definition WAVFile.cpp:265
AudioFileResultType getHighestSampleValue_int64(int64_t &pHighestAudioSample) override
Gets the highest audio sample value from the file, cast to a 64-bit integer.
Definition WAVFile.cpp:186
int64_t maxValueForSampleSize() const override
Returns the maximum possible positive value of the audio file's sample size.
Definition WAVFile.cpp:241
AudioFileResultType getNextSample(SampleType &pAudioSample)
Gets the next audio sample from the file. This is templated so that the proper variable type can be u...
Definition WAVFile.h:79
size_t numSamples() const override
Returns the number of audio samples in the WAV file.
Definition WAVFile.cpp:230
WAVFile(const std::string &pFilename, const WAVFileInfo &pWAVFileInfo)
Definition StringUtils.cpp:6
void reverseBytes(void *pStart, int pSize)
Definition EOUtils.cpp:18
AudioFileModes
Definition AudioFile.h:15
@ AUDIO_FILE_READ
Definition AudioFile.h:16
static bool machineIsBigEndian
Definition EOUtils.h:9