mirror of
https://github.com/mudita/MuditaOS.git
synced 2026-01-20 11:59:12 -05:00
* Fix of the issue that 'File has been deleted' popup would show in Relaxation app at the end of playback if the playback was paused at least once, even though the file wasn't actually deleted. * Added very basic audio decoder error handling and propagation mechanism. * Minor refactor around several audio-related parts.
67 lines
2.0 KiB
C++
67 lines
2.0 KiB
C++
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
|
|
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
|
|
|
|
#include "DecoderWAV.hpp"
|
|
#include "DecoderCommon.hpp"
|
|
#include <log/log.hpp>
|
|
#include <memory>
|
|
|
|
#define DR_WAV_IMPLEMENTATION
|
|
#include <src/dr_wav.h>
|
|
|
|
namespace audio
|
|
{
|
|
DecoderWAV::DecoderWAV(const std::string &filePath) : Decoder(filePath), wav(std::make_unique<drwav>())
|
|
{
|
|
if (drwav_init_file(wav.get(), filePath.c_str(), nullptr) == DRWAV_FALSE) {
|
|
LOG_ERROR("Unable to init WAV decoder");
|
|
return;
|
|
}
|
|
|
|
/* NOTE: Always convert to S16LE as an internal format */
|
|
channelCount = wav->channels;
|
|
sampleRate = wav->sampleRate;
|
|
bitsPerSample = 16;
|
|
isInitialized = true;
|
|
}
|
|
|
|
DecoderWAV::~DecoderWAV()
|
|
{
|
|
if (isInitialized) {
|
|
drwav_uninit(wav.get());
|
|
}
|
|
}
|
|
|
|
std::int32_t DecoderWAV::decode(std::uint32_t samplesToRead, std::int16_t *pcmData)
|
|
{
|
|
if (!isInitialized) {
|
|
LOG_ERROR("WAV decoder not initialized");
|
|
return 0;
|
|
}
|
|
|
|
if (!fileExists(fd)) {
|
|
LOG_WARN("File '%s' was deleted during playback!", filePath.c_str());
|
|
return fileDeletedRetCode;
|
|
}
|
|
|
|
const auto samplesRead = drwav_read_pcm_frames_s16(wav.get(), samplesToRead / channelCount, pcmData);
|
|
if (samplesRead > 0) {
|
|
/* Calculate frame duration in seconds */
|
|
position += static_cast<float>(samplesRead) / static_cast<float>(sampleRate);
|
|
}
|
|
return samplesRead * channelCount;
|
|
}
|
|
|
|
void DecoderWAV::setPosition(float pos)
|
|
{
|
|
if (!isInitialized) {
|
|
LOG_ERROR("WAV decoder not initialized");
|
|
return;
|
|
}
|
|
drwav_seek_to_pcm_frame(wav.get(), wav->totalPCMFrameCount * pos);
|
|
|
|
/* Calculate new position */
|
|
position = static_cast<float>(wav->totalPCMFrameCount) * pos / static_cast<float>(sampleRate);
|
|
}
|
|
} // namespace audio
|