~aleteoryx/muditaos

cbbcbe2a04d8d4275b44b7e92f6f530ef3926537 — Lucjan Bryndza 4 years ago feb9fc5
[EGD-8076] Replace wav decoder by dr_wav

Replace plain straigh waw decoder by the dr_wav library.

Signed-off-by: Lucjan Bryndza <lucjan.bryndza@mudita.com>
M module-audio/Audio/decoder/DecoderWorker.hpp => module-audio/Audio/decoder/DecoderWorker.hpp +1 -1
@@ 40,7 40,7 @@ namespace audio
        auto disablePlayback() -> bool;

      private:
        static constexpr std::size_t stackDepth = 2 * 1024;
        static constexpr std::size_t stackDepth = 6 * 1024;

        virtual auto handleMessage(uint32_t queueID) -> bool override;
        void pushAudioData();

M module-audio/Audio/decoder/decoderWAV.cpp => module-audio/Audio/decoder/decoderWAV.cpp +43 -56
@@ 2,88 2,75 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "decoderWAV.hpp"

#include <log/log.hpp>
#include <memory>
#include "Audio/AudioCommon.hpp"

#include "riff/wav/wavfile.h"
#define DR_WAV_IMPLEMENTATION
#include <src/dr_wav.h>

namespace audio
{

    decoderWAV::decoderWAV(const char *fileName) : Decoder(fileName)
    namespace internal
    {

        if (fileSize == 0) {
            return;
        }

        if (fd == NULL) {
        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;
    }

        if (std::fread(&waveHeader, 1, sizeof(waveHeader), fd) != sizeof(WAVE_FormatTypeDef)) {
            return;
    decoderWAV::~decoderWAV()
    {
        if (isInitialized) {
            auto dwav = &decoderContext->wav;
            drwav_uninit(dwav);
        }

        // TODO:M.P; implement support for sample size different than 16bit
        // pcmsamplesbuffer.reserve(1024);

        sampleRate    = waveHeader.SampleRate;
        bitsPerSample = waveHeader.BitPerSample;
        chanNumber    = waveHeader.NbrChannels;

        isInitialized = true;
    }

    uint32_t decoderWAV::decode(uint32_t samplesToRead, int16_t *pcmData)
    {
        uint32_t samples_read = 0;

        /* TODO:M.P; implement support for sample size different than 16bit
            if(samplesToRead > pcmsamplesbuffer.max_size()){
                pcmsamplesbuffer.resize(samplesToRead);
            }*/

        switch (bitsPerSample) {
        case 8:
            // TODO:M.P not supported
            break;

        case 16:
            samples_read = std::fread(pcmData, sizeof(int16_t), samplesToRead, fd);
            break;

        case 24:
            // TODO:M.P not supported
            break;

        case 32:
            // TODO:M.P not supported
            break;
        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)((float)(chanNumber == 2 ? samplesToRead / chanNumber : samplesToRead) / (float)(sampleRate));
            position += float(samplesToRead) / float(sampleRate);
        }

        return samples_read;
        return samples_read * chanNumber;
    }

    void decoderWAV::setPosition(float pos)
    {

        std::fseek(fd, (fileSize * pos) + sizeof(WAVE_FormatTypeDef), SEEK_SET);
        // Calculate new position
        position = (float)((float)(std::ftell(fd) / sizeof(int16_t) / chanNumber) / (float)(sampleRate));
        if (!isInitialized) {
            LOG_ERROR("Wav decoder not initialized");
            return;
        }
        auto dwav = &decoderContext->wav;
        drwav_seek_to_pcm_frame(dwav, dwav->totalPCMFrameCount * pos);
    }

    auto decoderWAV::getBitWidth() -> unsigned int
    {
        TagLib::RIFF::WAV::File wavFile(filePath.c_str());
        auto properties = wavFile.audioProperties();
        return properties->bitsPerSample();
        return bitsPerSample;
    }

} // namespace audio

M module-audio/Audio/decoder/decoderWAV.hpp => module-audio/Audio/decoder/decoderWAV.hpp +7 -20
@@ 8,12 8,16 @@

namespace audio
{

    namespace internal
    {
        struct wavContext;
    }
    class decoderWAV : public Decoder
    {

      public:
        decoderWAV(const char *fileName);
        explicit decoderWAV(const char *fileName);
        virtual ~decoderWAV();

        uint32_t decode(uint32_t samplesToRead, int16_t *pcmData) override;



@@ 22,26 26,9 @@ namespace audio
      private:
        auto getBitWidth() -> unsigned int override;

        using WAVE_FormatTypeDef = struct
        {
            uint32_t ChunkID;       /* 0 */
            uint32_t FileSize;      /* 4 */
            uint32_t FileFormat;    /* 8 */
            uint32_t SubChunk1ID;   /* 12 */
            uint32_t SubChunk1Size; /* 16*/
            uint16_t AudioFormat;   /* 20 */
            uint16_t NbrChannels;   /* 22 */
            uint32_t SampleRate;    /* 24 */

            uint32_t ByteRate;      /* 28 */
            uint16_t BlockAlign;    /* 32 */
            uint16_t BitPerSample;  /* 34 */
            uint32_t SubChunk2ID;   /* 36 */
            uint32_t SubChunk2Size; /* 40 */
        };

        std::vector<int32_t> pcmsamplesbuffer;
        WAVE_FormatTypeDef waveHeader;
        std::unique_ptr<internal::wavContext> decoderContext;
        uint32_t bitsPerSample;
    };


M module-audio/CMakeLists.txt => module-audio/CMakeLists.txt +1 -0
@@ 73,6 73,7 @@ target_link_libraries(${PROJECT_NAME}
        PRIVATE
                utils-math
                tagsfetcher
                dr_libs
)

add_subdirectory(tags_fetcher)

M third-party/CMakeLists.txt => third-party/CMakeLists.txt +1 -1
@@ 23,7 23,7 @@ add_subdirectory(sml)
add_subdirectory(taglib)
add_subdirectory(tinyexpr)
add_subdirectory(utz)
#add_subdirectory(dr_libs)
add_subdirectory(dr_libs)

if (${PROJECT_TARGET} STREQUAL "TARGET_RT1051")
    add_subdirectory(CrashDebug)