~aleteoryx/muditaos

ref: d5f84437cab54acb9fc0b8f96deb6f5d46fed3de muditaos/module-audio/Audio/decoder/decoderWAV.cpp -rw-r--r-- 2.1 KiB
d5f84437 — Lefucjusz [MOS-92] Fix continuing music playback after BT disconnection 3 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
73
// 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 <log/log.hpp>
#include <memory>
#include "Audio/AudioCommon.hpp"

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

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

    decoderWAV::decoderWAV(const char *fileName)
        : Decoder(fileName), decoderContext(std::make_unique<internal::wavContext>())
    {
        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