// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include "decoderWAV.hpp" #include #include #include "Audio/AudioCommon.hpp" #define DR_WAV_IMPLEMENTATION #include namespace audio { namespace internal { struct wavContext { drwav wav; }; } // namespace internal decoderWAV::decoderWAV(const char *fileName) : Decoder(fileName), decoderContext(std::make_unique()) { auto dwav = &decoderContext->wav; if (!drwav_init_file(dwav, fileName, NULL)) { LOG_ERROR("Unable to init wav decoder"); return; } sampleRate = dwav->sampleRate; // NOTE: Always convert to S16LE as internal format bitsPerSample = 16; // Number of channels chanNumber = dwav->channels; isInitialized = true; } decoderWAV::~decoderWAV() { if (isInitialized) { auto dwav = &decoderContext->wav; drwav_uninit(dwav); } } uint32_t decoderWAV::decode(uint32_t samplesToRead, int16_t *pcmData) { if (!isInitialized) { LOG_ERROR("Wav decoder not initialized"); return 0; } auto dwav = &decoderContext->wav; const auto samples_read = drwav_read_pcm_frames_s16(dwav, samplesToRead / chanNumber, pcmData); if (samples_read) { /* Calculate frame duration in seconds */ position += float(samplesToRead) / float(sampleRate); } return samples_read * chanNumber; } void decoderWAV::setPosition(float pos) { if (!isInitialized) { LOG_ERROR("Wav decoder not initialized"); return; } auto dwav = &decoderContext->wav; drwav_seek_to_pcm_frame(dwav, dwav->totalPCMFrameCount * pos); // Calculate new position position = float(dwav->totalPCMFrameCount) * pos / float(sampleRate); } } // namespace audio