- allow WavFileReader to read audio without resampling

This commit is contained in:
Dmytro Bogovych 2023-05-31 22:55:36 +03:00
parent 21fb865d80
commit 2aba79353a
2 changed files with 263 additions and 247 deletions

View File

@ -39,7 +39,7 @@ using namespace Audio;
// ---------------------- WavFileReader ------------------------- // ---------------------- WavFileReader -------------------------
WavFileReader::WavFileReader() WavFileReader::WavFileReader()
:mHandle(nullptr), mRate(0), mLastError(0) :mHandle(nullptr), mSamplerate(0), mLastError(0)
{ {
mDataOffset = 0; mDataOffset = 0;
} }
@ -133,8 +133,8 @@ bool WavFileReader::open(const std::tstring& filename)
if (fread(&mChannels, 2, 1, mHandle) < 1) if (fread(&mChannels, 2, 1, mHandle) < 1)
THROW_READERROR; THROW_READERROR;
mRate = 0; mSamplerate = 0;
if (fread(&mRate, 4, 1, mHandle) < 1) if (fread(&mSamplerate, 4, 1, mHandle) < 1)
THROW_READERROR; THROW_READERROR;
unsigned int avgbytespersec = 0; unsigned int avgbytespersec = 0;
@ -162,7 +162,7 @@ bool WavFileReader::open(const std::tstring& filename)
mFileName = filename; mFileName = filename;
mDataOffset = ftell(mHandle); mDataOffset = ftell(mHandle);
mResampler.start(AUDIO_CHANNELS, mRate, AUDIO_SAMPLERATE); mResampler.start(AUDIO_CHANNELS, mSamplerate, AUDIO_SAMPLERATE);
} }
catch(...) catch(...)
{ {
@ -181,25 +181,34 @@ void WavFileReader::close()
mHandle = nullptr; mHandle = nullptr;
} }
int WavFileReader::rate() const int WavFileReader::samplerate() const
{ {
return mRate; return mSamplerate;
} }
unsigned WavFileReader::read(void* buffer, unsigned bytes) int WavFileReader::channels() const
{ {
return read((short*)buffer, bytes / (AUDIO_CHANNELS * 2)) * AUDIO_CHANNELS * 2; return mChannels;
} }
unsigned WavFileReader::read(short* buffer, unsigned samples) unsigned WavFileReader::read(void* buffer, unsigned bytes, bool resample)
{
if (resample)
return read((short*)buffer, bytes / (AUDIO_CHANNELS * 2), true) * AUDIO_CHANNELS * 2;
else
return read((short*)buffer, bytes / channels() / sizeof(short), false) * channels() * sizeof(short);
}
unsigned WavFileReader::read(short* buffer, unsigned samples, bool resample)
{ {
LOCK; LOCK;
if (!mHandle) if (!mHandle)
return 0; return 0;
// Get number of samples that must be read from source file // Get number of samples that must be read from source file
int requiredBytes = mResampler.getSourceLength(samples) * mChannels * mBits / 8; int requiredBytes = resample ? mResampler.getSourceLength(samples) * mChannels * mBits / 8 : samples * mChannels * sizeof(short);
void* temp = alloca(requiredBytes); void* temp = alloca(requiredBytes);
memset(temp, 0, requiredBytes); memset(temp, 0, requiredBytes);
@ -214,12 +223,17 @@ unsigned WavFileReader::read(short* buffer, unsigned samples)
} }
/*int readSamples = */fread(temp, 1, requiredBytes, mHandle);// / mChannels / (mBits / 8); /*int readSamples = */fread(temp, 1, requiredBytes, mHandle);// / mChannels / (mBits / 8);
if (resample)
{
size_t processedBytes = 0; size_t processedBytes = 0;
size_t result = mResampler.processBuffer(temp, requiredBytes, processedBytes, size_t result = mResampler.processBuffer(temp, requiredBytes, processedBytes,
buffer, samples * 2 * AUDIO_CHANNELS); buffer, samples * 2 * AUDIO_CHANNELS);
return result / 2 / AUDIO_CHANNELS; return result / 2 / AUDIO_CHANNELS;
} }
else
return requiredBytes / channels() / sizeof(short);
}
bool WavFileReader::isOpened() bool WavFileReader::isOpened()
{ {

View File

@ -23,9 +23,10 @@ namespace Audio
FILE* mHandle; FILE* mHandle;
short mChannels; short mChannels;
short mBits; short mBits;
int mRate; int mSamplerate;
std::tstring mFileName; std::tstring mFileName;
mutable std::recursive_mutex mFileMtx; mutable std::recursive_mutex
mFileMtx;
unsigned mDataOffset; unsigned mDataOffset;
unsigned mDataLength; unsigned mDataLength;
Resampler mResampler; Resampler mResampler;
@ -40,13 +41,14 @@ namespace Audio
void close(); void close();
bool isOpened(); bool isOpened();
void rewind(); void rewind();
int rate() const; int samplerate() const;
int channels() const;
// This method returns number of read bytes // This method returns number of read bytes
unsigned read(void* buffer, unsigned bytes); unsigned read(void* buffer, unsigned bytes, bool resample = true);
// This method returns number of read samples // This method returns number of read samples
unsigned read(short* buffer, unsigned samples); unsigned read(short* buffer, unsigned samples, bool resample = true);
std::tstring filename() const; std::tstring filename() const;
unsigned size() const; unsigned size() const;