~aleteoryx/muditaos

bc4ff20d71e9edebe448372e44ee7d8c22448a4c — Lukasz Mastalerz 2 years ago f7f4adc
[BH-1836] Increase range of volume adjustment

Extended volume scale from 10 to 15 point scale
Modified volume approximation function for better user experience
M harmony_changelog.md => harmony_changelog.md +2 -0
@@ 21,6 21,8 @@
* Factory reset removes user files
* Changed countdown progress bar design in Relaxation, Meditation and Power Nap apps
* Removed minus sign in progress countdown timers in Relaxation, Meditation and Power Nap apps
* Extended volume scale from 10 to 15 point scale
* Modified volume approximation function for better user experience

## [2.2.3 2023-11-30]


M module-audio/Audio/Audio.cpp => module-audio/Audio/Audio.cpp +1 -9
@@ 34,15 34,7 @@ namespace audio

    audio::RetCode Audio::SetOutputVolume(float vol)
    {
        auto volToSet = vol;
        if (vol > maxVolume) {
            volToSet = maxVolume;
        }
        if (vol < minVolume) {
            volToSet = minVolume;
        }

        return currentOperation->SetOutputVolume(volToSet);
        return currentOperation->SetOutputVolume(static_cast<float>(vol));
    }

    audio::RetCode Audio::SetInputGain(Gain gain)

M module-audio/Audio/AudioCommon.hpp => module-audio/Audio/AudioCommon.hpp +0 -5
@@ 22,9 22,6 @@ namespace audio
namespace audio
{
    inline constexpr Volume defaultVolumeStep = 1;
    inline constexpr Gain defaultGainStep     = 10;
    inline constexpr Volume defaultVolume     = 5;
    inline constexpr Gain defaultGain         = 5;

    inline constexpr Volume maxVolume = 10;
    inline constexpr Volume minVolume = 0;


@@ 32,10 29,8 @@ namespace audio
    inline constexpr Gain maxGain = 100;
    inline constexpr Gain minGain = 0;

    inline constexpr auto audioOperationTimeout = 1000U;

    inline constexpr auto audioDbPrefix   = "audio";
    inline constexpr auto systemDbPrefix  = "system";
    inline constexpr auto dbPathSeparator = '/';

    enum class Setting

M module-audio/Audio/AudioDevice.hpp => module-audio/Audio/AudioDevice.hpp +1 -1
@@ 1,4 1,4 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

M module-audio/board/rt1051/SAIAudioDevice.cpp => module-audio/board/rt1051/SAIAudioDevice.cpp +2 -1
@@ 1,4 1,4 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "SAIAudioDevice.hpp"


@@ 109,6 109,7 @@ AudioDevice::RetCode SAIAudioDevice::setOutputVolume(float vol)
    volumeFactor = std::pow(1.0f * (vol / maxVolume), 2);
    return AudioDevice::RetCode::Success;
}

void SAIAudioDevice::scaleOutputVolume(audio::Stream::Span &span)
{
    if (volumeFactor < 1.0) {

M module-audio/board/rt1051/SAIAudioDevice.hpp => module-audio/board/rt1051/SAIAudioDevice.hpp +2 -5
@@ 1,4 1,4 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 27,16 27,13 @@ namespace audio
        void initiateRxTransfer();
        void initiateTxTransfer();
        RetCode setOutputVolume(float vol) override;
        void scaleOutputVolume(audio::Stream::Span &span);

        I2S_Type *_base;
        sai_edma_handle_t *rx = nullptr;
        sai_edma_handle_t *tx = nullptr;
        bool txEnabled        = false;
        bool rxEnabled        = false;

      private:
        void scaleOutputVolume(audio::Stream::Span &span);

        float volumeFactor{1.0};
    };


M module-audio/board/rt1051/bellpx/BellPxAudioCodec.cpp => module-audio/board/rt1051/bellpx/BellPxAudioCodec.cpp +21 -2
@@ 1,15 1,22 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "BellPxAudioCodec.hpp"
#include "board.h"
#include <log/log.hpp>
#include <cmath>

#include "board/BoardDefinitions.hpp"
#include "board/rt1051/common/audio.hpp"

using audio::codec::Configuration;

namespace
{
    constexpr auto maxBellVolume = 15.0f;
    constexpr auto minBellVolume = 0.0f;
} // namespace

namespace audio
{
    sai_edma_handle_t BellPxAudioCodec::txHandle = {};


@@ 73,7 80,7 @@ namespace audio
        codecParams.sampleRate = sampleRate;
        /// Set the codec output volume to max possible value. Volume control is implemented
        /// using software scaling instead of hardware gain control.
        codecParams.outVolume = maxVolume;
        codecParams.outVolume = maxBellVolume;
        codecParams.inGain    = currentFormat.inputGain;

        /// Set the initial volume used by the software volume control


@@ 218,6 225,18 @@ namespace audio
        return audio::AudioFormat{currentFormat.sampleRate_Hz, currentFormat.bitWidth, isMono ? 1U : 2U};
    }

    AudioDevice::RetCode BellPxAudioCodec::setOutputVolume(float vol)
    {
        /// Calculated for a curve with a dynamic range of 52dB
        /// For more info check: https://www.dr-lex.be/info-stuff/volumecontrols.html
        constexpr auto a = 2.512e-3f;
        constexpr auto b = 5.986721f;

        vol          = std::clamp(vol, minBellVolume, maxBellVolume);
        volumeFactor = std::clamp(a * std::exp(b * (vol / maxBellVolume)), 0.f, 1.f);
        return AudioDevice::RetCode::Success;
    }

    void rxAudioCodecCallback(I2S_Type *base, sai_edma_handle_t *handle, status_t status, void *userData)
    {
        auto self = static_cast<BellPxAudioCodec *>(userData);

M module-audio/board/rt1051/bellpx/BellPxAudioCodec.hpp => module-audio/board/rt1051/bellpx/BellPxAudioCodec.hpp +4 -1
@@ 1,4 1,4 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 44,6 44,9 @@ namespace audio
        auto getTraits() const -> Traits final;
        auto getSourceFormat() -> AudioFormat final;

      protected:
        AudioDevice::RetCode setOutputVolume(float vol) final;

      private:
        constexpr static TickType_t codecSettleTime                               = 20 * portTICK_PERIOD_MS;
        constexpr static std::initializer_list<unsigned int> supportedSampleRates = {

M module-audio/board/rt1051/bellpx/CMakeLists.txt => module-audio/board/rt1051/bellpx/CMakeLists.txt +1 -1
@@ 2,7 2,7 @@ target_sources(${AUDIO_BOARD_LIBRARY}
    PRIVATE
        BellPxAudioDeviceFactory.cpp
        BellPxAudioCodec.cpp
    

    PUBLIC
        BellPxAudioCodec.hpp
        BellPxAudioDeviceFactory.hpp

M module-bsp/board/rt1051/bellpx/bsp/audio/CodecAW8898.cpp => module-bsp/board/rt1051/bellpx/bsp/audio/CodecAW8898.cpp +10 -9
@@ 1,4 1,4 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "CodecAW8898.hpp"


@@ 21,21 21,22 @@ using namespace bsp::audio;

namespace
{
    constexpr auto ReadStatusRetries = 5;
    constexpr auto OneByteAddressing = 1;
    constexpr auto PositiveLogic     = 0;
    constexpr auto maxInVolume       = 10;
    constexpr auto maxInVolume       = 15;
    constexpr auto minInVolume       = 0;

    /// Higher layers operate using 0-10 range. Here we are transforming it into more usable one.
    /// Anything above 9 is going to distort the speaker and values below 5 are too quiet.
    constexpr float transformVolumeLvl(float value)
    /// Higher layers operate using 0-15 range. Here we are transforming it into more usable one.
    /// Anything above 13.5 is going to distort the speaker and values below 7.5 are too quiet.

    float transformVolumeLvl(float value)
    {
        constexpr auto maxOutVolume = 9;
        constexpr auto minOutVolume = 5;
        constexpr auto maxOutVolume = 13.5f;
        constexpr auto minOutVolume = 7.5f;
        constexpr auto inputRange   = std::make_pair(minInVolume, maxInVolume);
        constexpr auto outputRange  = std::make_pair(minOutVolume, maxOutVolume);
        constexpr float slope = 1.0 * (outputRange.second - outputRange.first) / (inputRange.second - inputRange.first);
        constexpr float slope =
            1.0f * (outputRange.second - outputRange.first) / (inputRange.second - inputRange.first);
        return outputRange.first + slope * (value - inputRange.first);
    }
} // namespace

M products/BellHybrid/apps/application-bell-meditation-timer/presenter/SettingsPresenter.cpp => products/BellHybrid/apps/application-bell-meditation-timer/presenter/SettingsPresenter.cpp +5 -4
@@ 1,4 1,4 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "SettingsPresenter.hpp"


@@ 75,9 75,10 @@ namespace app::meditation
                                                     utils::translate("app_bell_meditation_start_delay"),
                                                     utils::translate("common_second_lower")};

        auto chimeVolume = new list_items::Numeric{list_items::Numeric::spinner_type::range{1, 10, 1},
                                                   chimeVolumeModel,
                                                   utils::translate("app_bell_meditation_chime_volume")};
        auto chimeVolume = new list_items::Numeric{
            list_items::Numeric::spinner_type::range{AbstractAudioModel::minVolume, AbstractAudioModel::maxVolume, 1},
            chimeVolumeModel,
            utils::translate("app_bell_meditation_chime_volume")};

        listItemsProvider =
            std::make_shared<BellListItemProvider>(BellListItemProvider::Items{startDelay, chimeInterval, chimeVolume});

M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/AlarmSettingsListItemProvider.cpp => products/BellHybrid/apps/application-bell-settings/models/alarm_settings/AlarmSettingsListItemProvider.cpp +3 -2
@@ 3,6 3,7 @@

#include "BellSettingsStyle.hpp"
#include "AlarmSettingsListItemProvider.hpp"
#include "common/models/AbstractAudioModel.hpp"
#include <common/models/FrontlightModel.hpp>
#include <common/widgets/ListItems.hpp>
#include <common/widgets/list_items/Text.hpp>


@@ 49,8 50,8 @@ namespace app::bell_settings
        internalData.emplace_back(alarmTone);

        constexpr auto volumeStep = 1U;
        constexpr auto volumeMin  = 1U;
        constexpr auto volumeMax  = 10U;
        constexpr auto volumeMin  = AbstractAudioModel::minVolume;
        constexpr auto volumeMax  = AbstractAudioModel::maxVolume;
        auto alarmVolume =
            new list_items::Numeric(list_items::Numeric::spinner_type::range{volumeMin, volumeMax, volumeStep},
                                    settingsModel.getAlarmVolume(),

M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/BedtimeSettingsListItemProvider.cpp => products/BellHybrid/apps/application-bell-settings/models/alarm_settings/BedtimeSettingsListItemProvider.cpp +4 -3
@@ 1,8 1,9 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "BedtimeSettingsListItemProvider.hpp"
#include "BellSettingsStyle.hpp"
#include "common/models/AbstractAudioModel.hpp"
#include <common/widgets/list_items/Numeric.hpp>
#include <common/widgets/list_items/Text.hpp>
#include <apps-common/ApplicationCommon.hpp>


@@ 44,8 45,8 @@ namespace app::bell_settings
        };
        internalData.emplace_back(chimeTone);
        constexpr auto volumeStep = 1U;
        constexpr auto volumeMin  = 1U;
        constexpr auto volumeMax  = 10U;
        constexpr auto volumeMin  = AbstractAudioModel::minVolume;
        constexpr auto volumeMax  = AbstractAudioModel::maxVolume;
        auto volume =
            new list_items::Numeric(list_items::Numeric::spinner_type::range{volumeMin, volumeMax, volumeStep},
                                    model->getBedtimeVolume(),

M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/PrewakeUpListItemProvider.cpp => products/BellHybrid/apps/application-bell-settings/models/alarm_settings/PrewakeUpListItemProvider.cpp +4 -3
@@ 1,7 1,8 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "PrewakeUpListItemProvider.hpp"
#include "common/models/AbstractAudioModel.hpp"
#include <common/models/FrontlightModel.hpp>
#include <common/widgets/list_items/NumberWithSuffix.hpp>
#include <common/widgets/list_items/Numeric.hpp>


@@ 70,8 71,8 @@ namespace app::bell_settings
        internalData.emplace_back(chimeTone);

        constexpr auto volumeStep = 1U;
        constexpr auto volumeMin  = 1U;
        constexpr auto volumeMax  = 10U;
        constexpr auto volumeMin  = AbstractAudioModel::minVolume;
        constexpr auto volumeMax  = AbstractAudioModel::maxVolume;
        auto volume =
            new list_items::Numeric(list_items::Numeric::spinner_type::range{volumeMin, volumeMax, volumeStep},
                                    settingsModel.getChimeVolume(),

M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/SnoozeListItemProvider.cpp => products/BellHybrid/apps/application-bell-settings/models/alarm_settings/SnoozeListItemProvider.cpp +4 -3
@@ 1,7 1,8 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "SnoozeListItemProvider.hpp"
#include "common/models/AbstractAudioModel.hpp"
#include <common/widgets/list_items/NumberWithSuffix.hpp>
#include <common/widgets/list_items/Numeric.hpp>
#include <common/widgets/list_items/Text.hpp>


@@ 142,8 143,8 @@ namespace app::bell_settings
        internalData.emplace_back(snoozeChimeTone);

        constexpr auto volumeStep = 1U;
        constexpr auto volumeMin  = 1U;
        constexpr auto volumeMax  = 10U;
        constexpr auto volumeMin  = AbstractAudioModel::minVolume;
        constexpr auto volumeMax  = AbstractAudioModel::maxVolume;
        auto snoozeChimeVolume =
            new list_items::Numeric(list_items::Numeric::spinner_type::range{volumeMin, volumeMax, volumeStep},
                                    model.getSnoozeChimeVolume(),

M products/BellHybrid/apps/common/include/common/models/AbstractAudioModel.hpp => products/BellHybrid/apps/common/include/common/models/AbstractAudioModel.hpp +2 -2
@@ 14,9 14,9 @@ namespace app
    class AbstractAudioModel
    {
      public:
        /// 0-10 range
        /// 0-15 range
        static constexpr auto minVolume  = 1;
        static constexpr auto maxVolume  = 10;
        static constexpr auto maxVolume  = 15;
        using Volume                     = std::uint32_t;
        using OnStateChangeCallback      = std::function<void(const audio::RetCode code)>;
        using OnGetValueCallback         = std::function<void(const audio::RetCode, Volume)>;

M products/BellHybrid/services/audio/ServiceAudio.cpp => products/BellHybrid/services/audio/ServiceAudio.cpp +5 -5
@@ 13,11 13,11 @@ namespace
    // 4kB is too small because internally drflac_open() uses cache which by default has 4kB.
    // Alternatively smaller DR_FLAC_BUFFER_SIZE could be defined.
    constexpr auto stackSize            = 1024 * 8;
    constexpr auto defaultVolume        = "5";
    constexpr auto defaultSnoozeVolume  = "4";
    constexpr auto defaultBedtimeVolume = "6";
    constexpr auto maxVolumeToSet       = 10.0f;
    constexpr auto minVolumeToSet       = 0.0f;
    constexpr auto defaultVolume        = "7";
    constexpr auto defaultSnoozeVolume  = "6";
    constexpr auto defaultBedtimeVolume = "8";
    constexpr auto maxVolumeToSet       = 15.f;
    constexpr auto minVolumeToSet       = 0.f;
    constexpr auto profileType          = audio::Profile::Type::PlaybackLoudspeaker;
    constexpr auto volumeSetting        = audio::Setting::Volume;