~aleteoryx/muditaos

ref: ca7de85fef97bb33c2158547dd38e60da7da2ae9 muditaos/module-audio/Audio/decoder/decoderWAV.cpp -rw-r--r-- 2.1 KiB
ca7de85f — Bartosz [MOS-853] Purge multimedia database when initializing indexer 2 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "decoderWAV.hpp"
#include <log/log.hpp>
#include <memory>

#define DR_WAV_IMPLEMENTATION
#include <src/dr_wav.h>

namespace audio
{
    namespace internal
    {
        struct wavContext
        {
            drwav wav;
        };
    } // namespace internal

    decoderWAV::decoderWAV(const std::string &filePath)
        : Decoder(filePath), decoderContext(std::make_unique<internal::wavContext>())
    {
        auto dwav = &decoderContext->wav;
        if (drwav_init_file(dwav, filePath.c_str(), nullptr) == DRWAV_FALSE) {
            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);
        }
    }

    std::uint32_t decoderWAV::decode(std::uint32_t samplesToRead, std::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 += static_cast<float>(samplesToRead) / static_cast<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 = static_cast<float>(dwav->totalPCMFrameCount) * pos / static_cast<float>(sampleRate);
    }
} // namespace audio