diff --git a/examples/src/Main.cpp b/examples/src/Main.cpp index d6b4784..00eb184 100644 --- a/examples/src/Main.cpp +++ b/examples/src/Main.cpp @@ -40,8 +40,8 @@ int main(int argc, const char **argv) try // 1-channel wave //loader.Load(fileData.get(), "test_data/1ch/44100/8/test.wav"); //loader.Load(fileData.get(), "test_data/1ch/44100/16/test.wav"); - //loader.Load(fileData.get(), "test_data/1ch/44100/24/test.wav"); - loader.Load(fileData.get(), "test_data/1ch/44100/32/test.wav"); + loader.Load(fileData.get(), "test_data/1ch/44100/24/test.wav"); + //loader.Load(fileData.get(), "test_data/1ch/44100/32/test.wav"); //loader.Load(fileData.get(), "test_data/1ch/44100/64/test.wav"); // 2-channel wave @@ -104,6 +104,13 @@ int main(int argc, const char **argv) try std::cout << "[Warning - Sample Rate Mismatch] - file is sampled at " << fileData->sampleRate << " and output is " << desiredSampleRate << std::endl; } + std::vector outputBuffer; + outputBuffer.reserve(fileData->samples.size()); + linear_resample(44100.0 / 48000.0, fileData->samples, outputBuffer, fileData->samples.size()); + + std::cout << "Input Samples: " << fileData->samples.size() << std::endl; + std::cout << "Output Samples: " << outputBuffer.size() << std::endl; + // Convert mono to stereo for testing playback if (fileData->channelCount == 1) { @@ -118,6 +125,7 @@ int main(int argc, const char **argv) try myDevice.Play(fileData->samples); } + fileData->samples = outputBuffer; int encoderStatus = OggOpusEncoder::WriteFile({1, PCM_FLT, DITHER_NONE}, fileData.get(), "encoded.opus"); std::cout << "Encoder Status: " << encoderStatus << std::endl; diff --git a/include/libnyquist/WavEncoder.h b/include/libnyquist/WavEncoder.h index 43e974d..cb2c28e 100644 --- a/include/libnyquist/WavEncoder.h +++ b/include/libnyquist/WavEncoder.h @@ -33,32 +33,55 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace nqr { -enum EncoderError -{ - NoError, - InsufficientSampleData, - FileIOError, - UnsupportedSamplerate, - UnsupportedChannelConfiguration, - UnsupportedBitdepth, - UnsupportedChannelMix, - BufferTooBig, -}; + static inline void linear_resample(const double rate, const std::vector & input, std::vector & output, size_t samplesToProcess) + { + float * source = const_cast(input.data()); + + double virtualReadIndex = 0; + + // Linear Interpolate + int n = samplesToProcess - 1; + while (n--) + { + unsigned readIndex = static_cast(virtualReadIndex); + double interpolationFactor = virtualReadIndex - readIndex; + + double sample1 = source[readIndex]; + double sample2 = source[readIndex + 1]; + + double sample = (1.0 - interpolationFactor) * sample1 + interpolationFactor * sample2; + + output.push_back(sample); + + virtualReadIndex += rate; + } + } + + enum EncoderError + { + NoError, + InsufficientSampleData, + FileIOError, + UnsupportedSamplerate, + UnsupportedChannelConfiguration, + UnsupportedBitdepth, + UnsupportedChannelMix, + BufferTooBig, + }; + // A simplistic encoder that takes a blob of data, conforms it to the user's + // EncoderParams preference, and writes to disk. Be warned, does not support resampling! + // @todo support dithering, samplerate conversion, etc. + struct WavEncoder + { + // Assume data adheres to EncoderParams, except for bit depth and fmt + static int WriteFile(const EncoderParams p, const AudioData * d, const std::string & path); + }; -// A simplistic encoder that takes a blob of data, conforms it to the user's -// EncoderParams preference, and writes to disk. Be warned, does not support resampling! -// @todo support dithering, samplerate conversion, etc. -struct WavEncoder -{ - // Assume data adheres to EncoderParams, except for bit depth and fmt - static int WriteFile(const EncoderParams p, const AudioData * d, const std::string & path); -}; - -struct OggOpusEncoder -{ - static int WriteFile(const EncoderParams p, const AudioData * d, const std::string & path); -}; + struct OggOpusEncoder + { + static int WriteFile(const EncoderParams p, const AudioData * d, const std::string & path); + }; } // end namespace nqr diff --git a/src/WavEncoder.cpp b/src/WavEncoder.cpp index 3eb9375..4ec4bae 100644 --- a/src/WavEncoder.cpp +++ b/src/WavEncoder.cpp @@ -450,4 +450,4 @@ int OggOpusEncoder::WriteFile(const EncoderParams p, const AudioData * d, const return EncoderError::NoError; } -#undef OPUS_MAX_PACKET_SIZE +#undef OPUS_MAX_PACKET_SIZE \ No newline at end of file