~aleteoryx/muditaos

e46cb3e1a7b2d7d7854bc9e31b3da125488c8d90 — Lefucjusz 1 year, 9 months ago fd9d454
[BH-1888] Fix device freezing when changing volume intensively

Fix of the issue that intensive changing
volume in Relaxation app would result in
device freezing after some time of such
activity.
M harmony_changelog.md => harmony_changelog.md +1 -0
@@ 4,6 4,7 @@

### Fixed
* Fixed BIWIN eMMC memory errors
* Fixed freeze after changing Relaxation volume intensively

### Added
* Added new 32px and 170px fonts

M module-audio/Audio/decoder/DecoderFLAC.cpp => module-audio/Audio/decoder/DecoderFLAC.cpp +16 -6
@@ 10,6 10,7 @@
#define DR_FLAC_NO_OGG
#define DR_FLAC_NO_CRC
#define DR_FLAC_NO_SIMD

#include <src/dr_flac.h>

namespace audio


@@ 38,19 39,21 @@ namespace audio
        drflac_close(flac);
    }

    std::int32_t DecoderFLAC::decode(std::uint32_t samplesToRead, int16_t *pcmData)
    std::int32_t DecoderFLAC::decode(std::uint32_t samplesToRead, std::int16_t *pcmData)
    {
        if (!fileExists(fd)) {
            LOG_WARN("File '%s' was deleted during playback!", filePath.c_str());
            return fileDeletedRetCode;
        }

        const auto samplesRead =
            drflac_read_pcm_frames_s16(flac, samplesToRead / channelCount, reinterpret_cast<drflac_int16 *>(pcmData));
        if (samplesRead > 0) {
            /* Calculate frame duration in seconds */
            position += static_cast<float>(samplesRead) / static_cast<float>(sampleRate);
        }
        else if (!fileExists(fd)) {
            /* Unfortunately this second check of file existence is needed
             * to verify whether lack of new samples was caused by EOF or by
             * deletion of the file. */
            LOG_WARN("File '%s' was deleted during playback!", filePath.c_str());
            return fileDeletedRetCode;
        }
        return samplesRead * channelCount;
    }



@@ 79,6 82,13 @@ namespace audio
    std::size_t DecoderFLAC::drflacRead(void *pUserData, void *pBufferOut, std::size_t bytesToRead)
    {
        const auto decoderContext = reinterpret_cast<DecoderFLAC *>(pUserData);

        /* Check if the file exists - std::fread happily returns bytesToRead if
         * requested to read from deleted file, what causes decoding library
         * to enter infinite loop of reading. */
        if (!fileExists(decoderContext->fd)) {
            return 0;
        }
        return std::fread(pBufferOut, 1, bytesToRead, decoderContext->fd);
    }


M module-audio/Audio/decoder/DecoderMP3.cpp => module-audio/Audio/decoder/DecoderMP3.cpp +14 -5
@@ 96,23 96,32 @@ namespace audio

    std::int32_t DecoderMP3::decode(std::uint32_t samplesToRead, std::int16_t *pcmData)
    {
        if (!fileExists(fd)) {
            LOG_WARN("File '%s' was deleted during playback!", filePath.c_str());
            return fileDeletedRetCode;
        }

        const auto samplesRead = drmp3_read_pcm_frames_s16(
            mp3.get(), samplesToRead / channelCount, reinterpret_cast<drmp3_int16 *>(pcmData));
        if (samplesRead > 0) {
            /* Calculate frame duration in seconds */
            position += static_cast<float>(samplesRead) / static_cast<float>(sampleRate);
        }
        else if (!fileExists(fd)) {
            /* Unfortunately this second check of file existence is needed
             * to verify whether lack of new samples was caused by EOF or by
             * deletion of the file. */
            LOG_WARN("File '%s' was deleted during playback!", filePath.c_str());
            return fileDeletedRetCode;
        }
        return samplesRead * channelCount;
    }

    std::size_t DecoderMP3::drmp3Read(void *pUserData, void *pBufferOut, std::size_t bytesToRead)
    {
        const auto decoderContext = reinterpret_cast<DecoderMP3 *>(pUserData);

        /* Check if the file exists - std::fread happily returns bytesToRead if
         * requested to read from deleted file, what causes decoding library
         * to enter infinite loop of reading. */
        if (!fileExists(decoderContext->fd)) {
            return 0;
        }
        return std::fread(pBufferOut, 1, bytesToRead, decoderContext->fd);
    }


M module-audio/Audio/decoder/DecoderMP3.hpp => module-audio/Audio/decoder/DecoderMP3.hpp +4 -4
@@ 23,7 23,7 @@ namespace audio

        // Callback for when data needs to be read from the client.
        //
        // pUserData   [in]  The user data that was passed to drflac_open() and family.
        // pUserData   [in]  The user data that was passed to drmp3_init() and family.
        // pBufferOut  [out] The output buffer.
        // bytesToRead [in]  The number of bytes to read.
        //


@@ 35,15 35,15 @@ namespace audio

        // Callback for when data needs to be seeked.
        //
        // pUserData [in] The user data that was passed to drflac_open() and family.
        // pUserData [in] The user data that was passed to drmp3_init() and family.
        // offset    [in] The number of bytes to move, relative to the origin. Will never be negative.
        // origin    [in] The origin of the seek - the current position or the start of the stream.
        //
        // Returns whether the seek was successful.
        //
        // The offset will never be negative. Whether it is relative to the beginning or current position is
        // determined by the "origin" parameter which will be either drflac_seek_origin_start or
        // drflac_seek_origin_current.
        // determined by the "origin" parameter which will be either drmp3_seek_origin_start or
        // drmp3_seek_origin_current.
        static drmp3_bool32 drmp3Seek(void *pUserData, int offset, drmp3_seek_origin origin);
    };
} // namespace audio

M module-audio/Audio/decoder/DecoderWAV.cpp => module-audio/Audio/decoder/DecoderWAV.cpp +38 -13
@@ 7,13 7,15 @@
#include <memory>

#define DR_WAV_IMPLEMENTATION
#define DR_MP3_NO_STDIO

#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) {
        if (drwav_init(wav.get(), drwavRead, drwavSeek, this, nullptr) == DRWAV_FALSE) {
            LOG_ERROR("Unable to init WAV decoder");
            return;
        }


@@ 32,16 34,23 @@ namespace audio
        }
    }

    std::int32_t DecoderWAV::decode(std::uint32_t samplesToRead, std::int16_t *pcmData)
    void DecoderWAV::setPosition(float pos)
    {
        if (!isInitialized) {
            LOG_ERROR("WAV decoder not initialized");
            return 0;
            return;
        }
        drwav_seek_to_pcm_frame(wav.get(), wav->totalPCMFrameCount * pos);

        if (!fileExists(fd)) {
            LOG_WARN("File '%s' was deleted during playback!", filePath.c_str());
            return fileDeletedRetCode;
        /* Calculate new position */
        position = static_cast<float>(wav->totalPCMFrameCount) * pos / static_cast<float>(sampleRate);
    }

    std::int32_t DecoderWAV::decode(std::uint32_t samplesToRead, std::int16_t *pcmData)
    {
        if (!isInitialized) {
            LOG_ERROR("WAV decoder not initialized");
            return 0;
        }

        const auto samplesRead = drwav_read_pcm_frames_s16(wav.get(), samplesToRead / channelCount, pcmData);


@@ 49,18 58,34 @@ namespace audio
            /* Calculate frame duration in seconds */
            position += static_cast<float>(samplesRead) / static_cast<float>(sampleRate);
        }
        else if (!fileExists(fd)) {
            /* Unfortunately this second check of file existence is needed
             * to verify whether lack of new samples was caused by EOF or by
             * deletion of the file. */
            LOG_WARN("File '%s' was deleted during playback!", filePath.c_str());
            return fileDeletedRetCode;
        }
        return samplesRead * channelCount;
    }

    void DecoderWAV::setPosition(float pos)
    std::size_t DecoderWAV::drwavRead(void *pUserData, void *pBufferOut, std::size_t bytesToRead)
    {
        if (!isInitialized) {
            LOG_ERROR("WAV decoder not initialized");
            return;
        const auto decoderContext = reinterpret_cast<DecoderWAV *>(pUserData);

        /* Check if the file exists - std::fread happily returns bytesToRead if
         * requested to read from deleted file, what causes decoding library
         * to enter infinite loop of reading. */
        if (!fileExists(decoderContext->fd)) {
            return 0;
        }
        drwav_seek_to_pcm_frame(wav.get(), wav->totalPCMFrameCount * pos);
        return std::fread(pBufferOut, 1, bytesToRead, decoderContext->fd);
    }

        /* Calculate new position */
        position = static_cast<float>(wav->totalPCMFrameCount) * pos / static_cast<float>(sampleRate);
    drwav_bool32 DecoderWAV::drwavSeek(void *pUserData, int offset, drwav_seek_origin origin)
    {
        const auto decoderContext = reinterpret_cast<DecoderWAV *>(pUserData);
        const auto seekError =
            std::fseek(decoderContext->fd, offset, origin == drwav_seek_origin_start ? SEEK_SET : SEEK_CUR);
        return (seekError == 0) ? DRWAV_TRUE : DRWAV_FALSE;
    }
} // namespace audio

M module-audio/Audio/decoder/DecoderWAV.hpp => module-audio/Audio/decoder/DecoderWAV.hpp +25 -0
@@ 20,5 20,30 @@ namespace audio

      private:
        std::unique_ptr<drwav> wav;

        // Callback for when data needs to be read from the client.
        //
        // pUserData   [in]  The user data that was passed to drwav_open() and family.
        // pBufferOut  [out] The output buffer.
        // bytesToRead [in]  The number of bytes to read.
        //
        // Returns the number of bytes actually read.
        //
        // A return value of less than bytesToRead indicates the end of the stream. Do _not_ return from this callback
        // until either the entire bytesToRead is filled or you have reached the end of the stream.
        static std::size_t drwavRead(void *pUserData, void *pBufferOut, std::size_t bytesToRead);

        // Callback for when data needs to be seeked.
        //
        // pUserData [in] The user data that was passed to drwav_init() and family.
        // offset    [in] The number of bytes to move, relative to the origin. Will never be negative.
        // origin    [in] The origin of the seek - the current position or the start of the stream.
        //
        // Returns whether the seek was successful.
        //
        // The offset will never be negative. Whether it is relative to the beginning or current position is
        // determined by the "origin" parameter which will be either drwav_seek_origin_start or
        // drwav_seek_origin_current.
        static drwav_bool32 drwavSeek(void *pUserData, int offset, drwav_seek_origin origin);
    };
} // namespace audio