~aleteoryx/muditaos

bda18b5b5430523a879df2bb243c9d6dbc9dc34b — Marcin Smoczyński 5 years ago 2c3965d
[EGD-5706] Refactor creating audio device

Audio devices are created in the audio subsystem and it is not possible
to send a device to bt service upon creation.

Introduce hookable audio device factory to allow sharing bluetooth
audio device. Move audio devices from bsp to audio allowing removal of
unwanted bsp -> audio dependency.

Remove Bluetooth proxy device which turned out to be a dead end.

Signed-off-by: Marcin Smoczyński <smoczynski.marcin@gmail.com>
56 files changed, 679 insertions(+), 708 deletions(-)

M CMakeLists.txt
M module-apps/CMakeLists.txt
M module-audio/Audio/AudioCommon.cpp
M module-audio/Audio/AudioCommon.hpp
R {module-bsp/bsp/audio/bsp_audio => module-audio/Audio/AudioDevice}.hpp -rwxr-xr-x => -rw-r--r--
A module-audio/Audio/AudioDeviceFactory.cpp
A module-audio/Audio/AudioDeviceFactory.hpp
A module-audio/Audio/AudioPlatform.hpp
D module-audio/Audio/BluetoothProxyAudio.cpp
D module-audio/Audio/BluetoothProxyAudio.hpp
M module-audio/Audio/Operation/Operation.cpp
M module-audio/Audio/Operation/Operation.hpp
M module-audio/Audio/Operation/PlaybackOperation.cpp
M module-audio/Audio/Operation/RecorderOperation.cpp
M module-audio/Audio/Operation/RecorderOperation.hpp
M module-audio/Audio/Operation/RouterOperation.cpp
M module-audio/Audio/Operation/RouterOperation.hpp
M module-audio/Audio/Profiles/Profile.cpp
M module-audio/Audio/Profiles/Profile.hpp
M module-audio/Audio/Profiles/ProfileIdle.hpp
M module-audio/Audio/Profiles/ProfilePlaybackBluetoothA2DP.hpp
M module-audio/Audio/Profiles/ProfilePlaybackHeadphones.hpp
M module-audio/Audio/Profiles/ProfilePlaybackLoudspeaker.hpp
M module-audio/Audio/Profiles/ProfileRecordingBluetoothHSP.hpp
M module-audio/Audio/Profiles/ProfileRecordingHeadphones.hpp
M module-audio/Audio/Profiles/ProfileRecordingOnBoardMic.hpp
M module-audio/Audio/Profiles/ProfileRoutingBluetoothHSP.hpp
M module-audio/Audio/Profiles/ProfileRoutingEarspeaker.hpp
M module-audio/Audio/Profiles/ProfileRoutingHeadphones.hpp
M module-audio/Audio/Profiles/ProfileRoutingLoudspeaker.hpp
M module-audio/CMakeLists.txt
A module-audio/board/linux/CMakeLists.txt
A module-audio/board/linux/LinuxAudioPlatform.cpp
A module-audio/board/rt1051/CMakeLists.txt
R {module-bsp/board/rt1051/bsp/audio/RT1051Audiocodec => module-audio/board/rt1051/RT1051AudioCodec}.cpp
R {module-bsp/board/rt1051/bsp/audio/RT1051Audiocodec => module-audio/board/rt1051/RT1051AudioCodec}.hpp -rwxr-xr-x => -rw-r--r--
R {module-bsp/board/rt1051/bsp/audio => module-audio/board/rt1051}/RT1051CellularAudio.cpp
R {module-bsp/board/rt1051/bsp/audio => module-audio/board/rt1051}/RT1051CellularAudio.hpp -rwxr-xr-x => -rw-r--r--
A module-audio/board/rt1051/RT1051DeviceFactory.cpp
A module-audio/board/rt1051/RT1051DeviceFactory.hpp
A module-audio/board/rt1051/RT1051Platform.cpp
R {module-bsp/board/rt1051/bsp/audio => module-audio/board/rt1051}/SAIAudioDevice.cpp
R {module-bsp/board/rt1051/bsp/audio => module-audio/board/rt1051}/SAIAudioDevice.hpp
D module-audio/targets/Target_Cross.cmake
D module-audio/targets/Target_Linux.cmake
M module-bluetooth/Bluetooth/interface/profiles/Profile.hpp
M module-bsp/CMakeLists.txt
M module-bsp/board/rt1051/bsp/audio/CodecMAX98090.cpp
M module-bsp/board/rt1051/bsp/audio/CodecMAX98090.hpp
A module-bsp/board/rt1051/common/audio.cpp
A module-bsp/board/rt1051/common/audio.hpp
M module-bsp/board/rt1051/common/board.cpp
D module-bsp/bsp/audio/bsp_audio.cpp
M module-bsp/targets/Target_RT1051.cmake
M module-services/service-audio/ServiceAudio.cpp
M module-services/service-bluetooth/service-bluetooth/BluetoothMessage.hpp
M CMakeLists.txt => CMakeLists.txt +4 -0
@@ 22,6 22,10 @@ message("TARGET_COMPILE_DEFINITIONS: ${TARGET_COMPILE_OPTIONS}")
message("TARGET_LIBRARIES: ${TARGET_LIBRARIES}")
message("TARGET_LINKER_FLAGS: ${TARGET_LINKER_FLAGS}")

string(REPLACE "TARGET_" "" PROJECT_TARGET_NAME ${PROJECT_TARGET})
string(TOLOWER "${PROJECT_TARGET_NAME}" PROJECT_TARGET_NAME)
message("Project target name: ${PROJECT_TARGET_NAME}")

add_executable(${PROJECT_NAME} "" )

if (NOT ${PROJECT_TARGET} STREQUAL "TARGET_RT1051")

M module-apps/CMakeLists.txt => module-apps/CMakeLists.txt +5 -1
@@ 1,4 1,7 @@
cmake_minimum_required(VERSION 3.14)
# Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
# For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

cmake_minimum_required(VERSION 3.14)

project(module-apps VERSION 1.0
        DESCRIPTION "Library with all applications.")


@@ 112,6 115,7 @@ target_link_libraries(${PROJECT_NAME}
        service-db
        service-evtmgr
    PUBLIC
        module-audio
        module-bsp
        module-os
        module-sys

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

#include "AudioCommon.hpp"


@@ 8,9 8,9 @@

namespace audio
{
    audio::RetCode GetDeviceError(bsp::AudioDevice::RetCode retCode)
    audio::RetCode GetDeviceError(AudioDevice::RetCode retCode)
    {
        if (retCode == bsp::AudioDevice::RetCode::Success) {
        if (retCode == AudioDevice::RetCode::Success) {
            return RetCode::Success;
        }


M module-audio/Audio/AudioCommon.hpp => module-audio/Audio/AudioCommon.hpp +8 -7
@@ 1,16 1,17 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include "AudioDevice.hpp"
#include "Profiles/Profile.hpp"

#include <Service/Message.hpp>
#include <Utils.hpp>

#include <map>
#include <bitset>
#include <bsp/audio/bsp_audio.hpp>
#include <Utils.hpp>
#include <utility>
#include <Service/Message.hpp>

#include "Profiles/Profile.hpp"

namespace audio
{


@@ 243,7 244,7 @@ namespace audio
        friend class ::audio::AudioMux;
    };

    RetCode GetDeviceError(bsp::AudioDevice::RetCode retCode);
    RetCode GetDeviceError(AudioDevice::RetCode retCode);
    const std::string str(RetCode retcode);
    [[nodiscard]] auto GetVolumeText(const audio::Volume &volume) -> std::string;
} // namespace audio

R module-bsp/bsp/audio/bsp_audio.hpp => module-audio/Audio/AudioDevice.hpp +14 -18
@@ 1,3 1,6 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <Audio/Endpoint.hpp>


@@ 6,7 9,7 @@
#include <memory>
#include <functional>

namespace bsp
namespace audio
{

    class AudioDevice : public audio::IOProxy


@@ 27,35 30,30 @@ namespace bsp
            Bluetooth
        };

        enum class Flags
        {
            OutputMono   = 1 << 0,
            OutputStereo = 1 << 1,
            InputLeft    = 1 << 2,
            InputRight   = 1 << 3,
            InputStereo  = 1 << 4
        };

        enum class InputPath
        {
            Headphones,
            Microphone,
            BluetoothHSP,
            None
        };

        enum class OutputPath
        {
            Headphones,
            HeadphonesMono,
            Earspeaker,
            Loudspeaker,
            LoudspeakerMono,
            BluetoothA2DP,
            BluetoothHSP,
            None
        };

        enum class Flags
        {
            OutputMono   = 1 << 0,
            OutputStereo = 1 << 1,
            InputLeft    = 1 << 2,
            InputRight   = 1 << 3,
            InputStereo  = 1 << 4
        };

        using Format = struct
        {
            uint32_t sampleRate_Hz = 0; /*!< Sample rate of audio data */


@@ 75,8 73,6 @@ namespace bsp

        virtual ~AudioDevice() = default;

        static std::optional<std::unique_ptr<AudioDevice>> Create(Type type);

        virtual RetCode Start(const Format &format) = 0;
        virtual RetCode Stop()                      = 0;



@@ 116,4 112,4 @@ namespace bsp

        bool isInitialized = false;
    };
} // namespace bsp
} // namespace audio

A module-audio/Audio/AudioDeviceFactory.cpp => module-audio/Audio/AudioDeviceFactory.cpp +25 -0
@@ 0,0 1,25 @@
// Copyright (c) 2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "AudioDeviceFactory.hpp"

using namespace audio;

AudioDeviceFactory::AudioDeviceFactory(Observer *observer) : _observer(observer)
{}

std::shared_ptr<AudioDevice> AudioDeviceFactory::CreateDevice(AudioDevice::Type deviceType)
{
    std::shared_ptr<AudioDevice> device = getDeviceFromType(deviceType);

    if (_observer != nullptr && device) {
        _observer->onDeviceCreated(device);
    }

    return device;
}

void AudioDeviceFactory::setObserver(Observer *observer) noexcept
{
    _observer = observer;
}

A module-audio/Audio/AudioDeviceFactory.hpp => module-audio/Audio/AudioDeviceFactory.hpp +34 -0
@@ 0,0 1,34 @@
// Copyright (c) 2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include "AudioDevice.hpp"

#include <memory>

namespace audio
{

    class AudioDeviceFactory
    {
        class Observer
        {
          public:
            virtual void onDeviceCreated(std::shared_ptr<AudioDevice> device) = 0;
        };

      public:
        explicit AudioDeviceFactory(Observer *observer = nullptr);

        void setObserver(Observer *observer) noexcept;
        std::shared_ptr<AudioDevice> CreateDevice(AudioDevice::Type);

      protected:
        virtual std::shared_ptr<AudioDevice> getDeviceFromType(AudioDevice::Type) = 0;

      private:
        Observer *_observer = nullptr;
    };

}; // namespace audio

A module-audio/Audio/AudioPlatform.hpp => module-audio/Audio/AudioPlatform.hpp +18 -0
@@ 0,0 1,18 @@
// Copyright (c) 2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include "AudioDeviceFactory.hpp"

#include <memory>

namespace audio
{
    class AudioPlatform
    {
      public:
        static std::unique_ptr<AudioDeviceFactory> GetDeviceFactory();
    };

}; // namespace audio

D module-audio/Audio/BluetoothProxyAudio.cpp => module-audio/Audio/BluetoothProxyAudio.cpp +0 -93
@@ 1,93 0,0 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "BluetoothProxyAudio.hpp"
#include <service-bluetooth/BluetoothMessage.hpp>

namespace bsp
{
    BluetoothProxyAudio::BluetoothProxyAudio(AudioServiceMessage::Callback callback,
                                             audio::Stream &dataStreamOut,
                                             audio::Stream &dataStreamIn,
                                             AudioDevice::Format &format)
        : dataStreamOut(dataStreamOut), dataStreamIn(dataStreamIn), serviceCallback(std::move(callback)),
          audioFormat(format)
    {
        LOG_DEBUG("BluetoothProxyAudio created.");
    }

    AudioDevice::RetCode BluetoothProxyAudio::Start(const AudioDevice::Format &format)
    {
        auto msg = BluetoothProxyStartMessage(dataStreamOut, dataStreamIn, format);
        serviceCallback(&msg);
        return AudioDevice::RetCode::Success;
    }

    AudioDevice::RetCode BluetoothProxyAudio::Stop()
    {
        auto msg = BluetoothProxyStopMessage(audioFormat);
        serviceCallback(&msg);
        return AudioDevice::RetCode::Success;
    }

    AudioDevice::RetCode BluetoothProxyAudio::OutputVolumeCtrl(float vol)
    {
        audioFormat.outputVolume = vol;
        auto msg                 = BluetoothProxySetVolumeMessage(audioFormat);
        serviceCallback(&msg);
        return AudioDevice::RetCode::Success;
    }

    AudioDevice::RetCode BluetoothProxyAudio::InputGainCtrl(float gain)
    {
        audioFormat.inputGain = gain;
        auto msg              = BluetoothProxySetGainMessage(audioFormat);
        serviceCallback(&msg);
        return AudioDevice::RetCode::Success;
    }

    AudioDevice::RetCode BluetoothProxyAudio::OutputPathCtrl(AudioDevice::OutputPath outputPath)
    {
        audioFormat.outputPath = outputPath;
        auto msg               = BluetoothProxySetOutputPathMessage(audioFormat);
        serviceCallback(&msg);
        return AudioDevice::RetCode::Success;
    }

    AudioDevice::RetCode BluetoothProxyAudio::InputPathCtrl(AudioDevice::InputPath inputPath)
    {
        audioFormat.inputPath = inputPath;
        auto msg              = BluetoothProxySetInputPathMessage(audioFormat);
        serviceCallback(&msg);
        return AudioDevice::RetCode::Success;
    }

    bool BluetoothProxyAudio::IsFormatSupported(const AudioDevice::Format &format)
    {
        LOG_DEBUG("Format assumed to be supported");
        return true;
    }

    BluetoothProxyAudio::~BluetoothProxyAudio()
    {
        Stop();
    }

    void BluetoothProxyAudio::onDataReceive()
    {}

    void BluetoothProxyAudio::onDataSend()
    {}

    void BluetoothProxyAudio::enableInput()
    {}

    void BluetoothProxyAudio::enableOutput()
    {}

    void BluetoothProxyAudio::disableInput()
    {}

    void BluetoothProxyAudio::disableOutput()
    {}
} // namespace bsp

D module-audio/Audio/BluetoothProxyAudio.hpp => module-audio/Audio/BluetoothProxyAudio.hpp +0 -45
@@ 1,45 0,0 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include "AudioCommon.hpp"
#include "Stream.hpp"

#include "bsp/audio/bsp_audio.hpp"

namespace bsp
{
    class BluetoothProxyAudio final : public AudioDevice
    {
      public:
        BluetoothProxyAudio(AudioServiceMessage::Callback callback,
                            audio::Stream &dataStreamOut,
                            audio::Stream &dataStreamIn,
                            AudioDevice::Format &format);

        ~BluetoothProxyAudio() final;

        AudioDevice::RetCode Start(const Format &format) final;
        AudioDevice::RetCode Stop() final;
        AudioDevice::RetCode OutputVolumeCtrl(float vol) final;
        AudioDevice::RetCode InputGainCtrl(float gain) final;
        AudioDevice::RetCode OutputPathCtrl(OutputPath outputPath) final;
        AudioDevice::RetCode InputPathCtrl(InputPath inputPath) final;
        bool IsFormatSupported(const Format &format) final;

        void onDataReceive() final;
        void onDataSend() final;
        void enableInput() final;
        void enableOutput() final;
        void disableInput() final;
        void disableOutput() final;

      private:
        audio::Stream &dataStreamOut;
        audio::Stream &dataStreamIn;
        AudioServiceMessage::Callback serviceCallback;
        AudioDevice::Format audioFormat;
    };

} // namespace bsp

M module-audio/Audio/Operation/Operation.cpp => module-audio/Audio/Operation/Operation.cpp +8 -6
@@ 5,15 5,15 @@

#include <algorithm>

#include "Audio/AudioDevice.hpp"
#include "Audio/AudioDeviceFactory.hpp"
#include "Audio/AudioPlatform.hpp"

#include "IdleOperation.hpp"
#include "PlaybackOperation.hpp"
#include "RecorderOperation.hpp"
#include "RouterOperation.hpp"

#include "Audio/BluetoothProxyAudio.hpp"

#include <bsp/audio/bsp_audio.hpp>

namespace audio
{
    std::unique_ptr<Operation> Operation::Create(Operation::Type t,


@@ 94,8 94,10 @@ namespace audio
        supportedProfiles.emplace_back(Profile::Create(profile, volume, gain), isAvailable);
    }

    std::optional<std::unique_ptr<bsp::AudioDevice>> Operation::CreateDevice(bsp::AudioDevice::Type type)
    std::shared_ptr<AudioDevice> Operation::CreateDevice(AudioDevice::Type type)
    {
        return bsp::AudioDevice::Create(type).value_or(nullptr);
        auto factory = AudioPlatform::GetDeviceFactory();

        return factory->CreateDevice(type);
    }
} // namespace audio

M module-audio/Audio/Operation/Operation.hpp => module-audio/Audio/Operation/Operation.hpp +2 -3
@@ 4,7 4,6 @@
#pragma once

#include <memory>
#include <optional>
#include <functional>

#include <Audio/AudioCommon.hpp>


@@ 123,7 122,7 @@ namespace audio
        };

        std::shared_ptr<Profile> currentProfile;
        std::unique_ptr<bsp::AudioDevice> audioDevice;
        std::shared_ptr<AudioDevice> audioDevice;
        std::vector<SupportedProfile> supportedProfiles;

        State state = State::Idle;


@@ 142,7 141,7 @@ namespace audio
        virtual audio::RetCode SwitchProfile(const Profile::Type type) = 0;
        std::shared_ptr<Profile> GetProfile(const Profile::Type type);

        std::optional<std::unique_ptr<bsp::AudioDevice>> CreateDevice(bsp::AudioDevice::Type type);
        std::shared_ptr<AudioDevice> CreateDevice(AudioDevice::Type type);
    };

} // namespace audio

M module-audio/Audio/Operation/PlaybackOperation.cpp => module-audio/Audio/Operation/PlaybackOperation.cpp +3 -6
@@ 163,7 163,7 @@ namespace audio
        dec->stopDecodingWorker();
        audioDevice.reset();
        dataStreamOut.reset();
        audioDevice = CreateDevice(newProfile->GetAudioDeviceType()).value_or(nullptr);
        audioDevice = CreateDevice(newProfile->GetAudioDeviceType());
        if (audioDevice == nullptr) {
            LOG_ERROR("Error creating AudioDevice");
            return RetCode::Failed;


@@ 172,13 172,10 @@ namespace audio
        // adjust new profile with information from file's tags
        newProfile->SetSampleRate(tags->sample_rate);
        if (tags->num_channel == channel::stereoSound) {
            newProfile->SetInOutFlags(static_cast<uint32_t>(bsp::AudioDevice::Flags::OutputStereo));
            newProfile->SetInOutFlags(static_cast<uint32_t>(AudioDevice::Flags::OutputStereo));
        }
        else {
            newProfile->SetInOutFlags(static_cast<uint32_t>(bsp::AudioDevice::Flags::OutputMono));
            if (newProfile->GetOutputPath() == bsp::AudioDevice::OutputPath::Headphones) {
                newProfile->SetOutputPath(bsp::AudioDevice::OutputPath::HeadphonesMono);
            }
            newProfile->SetInOutFlags(static_cast<uint32_t>(AudioDevice::Flags::OutputMono));
        }

        // store profile

M module-audio/Audio/Operation/RecorderOperation.cpp => module-audio/Audio/Operation/RecorderOperation.cpp +3 -2
@@ 2,8 2,9 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "RecorderOperation.hpp"

#include "Audio/AudioDevice.hpp"
#include "Audio/encoder/Encoder.hpp"
#include "bsp/audio/bsp_audio.hpp"
#include "Audio/Profiles/Profile.hpp"
#include "Audio/Profiles/ProfileRecordingHeadphones.hpp"
#include "Audio/Profiles/ProfileRecordingOnBoardMic.hpp"


@@ 157,7 158,7 @@ namespace audio
            return RetCode::UnsupportedProfile;
        }

        audioDevice = CreateDevice(currentProfile->GetAudioDeviceType()).value_or(nullptr);
        audioDevice = CreateDevice(currentProfile->GetAudioDeviceType());
        if (audioDevice == nullptr) {
            LOG_ERROR("Error creating AudioDevice");
            return RetCode::Failed;

M module-audio/Audio/Operation/RecorderOperation.hpp => module-audio/Audio/Operation/RecorderOperation.hpp +2 -2
@@ 1,11 1,11 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include "Operation.hpp"
#include <Audio/encoder/Encoder.hpp>
#include <bsp/audio/bsp_audio.hpp>
#include <Audio/AudioDevice.hpp>

namespace audio
{

M module-audio/Audio/Operation/RouterOperation.cpp => module-audio/Audio/Operation/RouterOperation.cpp +5 -6
@@ 3,11 3,11 @@

#include "RouterOperation.hpp"

#include <Audio/AudioDevice.hpp>
#include <Audio/AudioCommon.hpp>
#include <Audio/Profiles/Profile.hpp>
#include <Audio/StreamFactory.hpp>

#include <bsp_audio.hpp>
#include <log/log.hpp>
#include <mutex.hpp>



@@ 60,13 60,12 @@ namespace audio
        }

        // try to run devices with the format
        if (auto ret = audioDevice->Start(currentProfile->GetAudioFormat());
            ret != bsp::AudioDevice::RetCode::Success) {
        if (auto ret = audioDevice->Start(currentProfile->GetAudioFormat()); ret != AudioDevice::RetCode::Success) {
            return GetDeviceError(ret);
        }

        if (auto ret = audioDeviceCellular->Start(currentProfile->GetAudioFormat());
            ret != bsp::AudioDevice::RetCode::Success) {
            ret != AudioDevice::RetCode::Success) {
            return GetDeviceError(ret);
        }



@@ 180,13 179,13 @@ namespace audio
            Stop();
        }

        audioDevice = CreateDevice(newProfile->GetAudioDeviceType()).value_or(nullptr);
        audioDevice = CreateDevice(newProfile->GetAudioDeviceType());
        if (audioDevice == nullptr) {
            LOG_ERROR("Error creating AudioDevice");
            return RetCode::Failed;
        }

        audioDeviceCellular = CreateDevice(bsp::AudioDevice::Type::Cellular).value_or(nullptr);
        audioDeviceCellular = CreateDevice(AudioDevice::Type::Cellular);
        if (audioDeviceCellular == nullptr) {
            LOG_ERROR("Error creating AudioDeviceCellular");
            return RetCode::Failed;

M module-audio/Audio/Operation/RouterOperation.hpp => module-audio/Audio/Operation/RouterOperation.hpp +3 -2
@@ 5,11 5,12 @@

#include "Operation.hpp"

#include <Audio/AudioDevice.hpp>
#include <Audio/encoder/Encoder.hpp>
#include <Audio/AudioCommon.hpp>
#include <Audio/Profiles/Profile.hpp>
#include <Audio/Endpoint.hpp>
#include <bsp/audio/bsp_audio.hpp>

#include <mutex.hpp>

#include <memory>


@@ 53,7 54,7 @@ namespace audio
        std::unique_ptr<Stream> dataStreamOut;
        std::unique_ptr<Stream> dataStreamIn;
        std::unique_ptr<Encoder> enc;
        std::unique_ptr<bsp::AudioDevice> audioDeviceCellular;
        std::shared_ptr<AudioDevice> audioDeviceCellular;
        std::unique_ptr<StreamConnection> outputConnection;
        std::unique_ptr<StreamConnection> inputConnection;
    };

M module-audio/Audio/Profiles/Profile.cpp => module-audio/Audio/Profiles/Profile.cpp +6 -8
@@ 1,4 1,4 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "Profile.hpp"


@@ 24,9 24,7 @@
namespace audio
{

    std::unique_ptr<Profile> Profile::Create(const Type t,
                                             std::optional<Volume> vol,
                                             std::optional<Gain> gain)
    std::unique_ptr<Profile> Profile::Create(const Type t, std::optional<Volume> vol, std::optional<Gain> gain)
    {
        std::unique_ptr<Profile> inst;



@@ 81,8 79,8 @@ namespace audio

    Profile::Profile(const std::string &name,
                     const Type type,
                     const bsp::AudioDevice::Format &fmt,
                     bsp::AudioDevice::Type devType)
                     const AudioDevice::Format &fmt,
                     AudioDevice::Type devType)
        : audioFormat(fmt), audioDeviceType(devType), name(name), type(type)
    {}



@@ 96,12 94,12 @@ namespace audio
        audioFormat.outputVolume = vol;
    }

    void Profile::SetInputPath(bsp::AudioDevice::InputPath path)
    void Profile::SetInputPath(AudioDevice::InputPath path)
    {
        audioFormat.inputPath = path;
    }

    void Profile::SetOutputPath(bsp::AudioDevice::OutputPath path)
    void Profile::SetOutputPath(AudioDevice::OutputPath path)
    {
        audioFormat.outputPath = path;
    }

M module-audio/Audio/Profiles/Profile.hpp => module-audio/Audio/Profiles/Profile.hpp +14 -17
@@ 1,14 1,14 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include "Audio/AudioDevice.hpp"

#include <memory>
#include <functional>
#include <string>

#include <bsp/audio/bsp_audio.hpp>

namespace audio
{
    using Volume      = uint32_t;


@@ 43,8 43,8 @@ namespace audio
        };

        static std::unique_ptr<Profile> Create(const Type t,
                                               std::optional<Volume> vol         = 0,
                                               std::optional<Gain> gain          = 0);
                                               std::optional<Volume> vol = 0,
                                               std::optional<Gain> gain  = 0);

        void SetOutputVolume(Volume vol);



@@ 54,9 54,9 @@ namespace audio

        void SetSampleRate(uint32_t samplerate);

        void SetOutputPath(bsp::AudioDevice::OutputPath path);
        void SetOutputPath(AudioDevice::OutputPath path);

        void SetInputPath(bsp::AudioDevice::InputPath path);
        void SetInputPath(AudioDevice::InputPath path);

        Volume GetOutputVolume() const
        {


@@ 78,22 78,22 @@ namespace audio
            return audioFormat.flags;
        }

        bsp::AudioDevice::OutputPath GetOutputPath() const
        AudioDevice::OutputPath GetOutputPath() const
        {
            return audioFormat.outputPath;
        }

        bsp::AudioDevice::InputPath GetInputPath() const
        AudioDevice::InputPath GetInputPath() const
        {
            return audioFormat.inputPath;
        }

        bsp::AudioDevice::Type GetAudioDeviceType() const
        AudioDevice::Type GetAudioDeviceType() const
        {
            return audioDeviceType;
        }

        bsp::AudioDevice::Format GetAudioFormat()
        AudioDevice::Format GetAudioFormat()
        {
            return audioFormat;
        }


@@ 109,13 109,10 @@ namespace audio
        }

      protected:
        Profile(const std::string &name,
                const Type type,
                const bsp::AudioDevice::Format &fmt,
                bsp::AudioDevice::Type devType);
        Profile(const std::string &name, const Type type, const AudioDevice::Format &fmt, AudioDevice::Type devType);

        bsp::AudioDevice::Format audioFormat{};
        bsp::AudioDevice::Type audioDeviceType = bsp::AudioDevice::Type::Audiocodec;
        AudioDevice::Format audioFormat{};
        AudioDevice::Type audioDeviceType = AudioDevice::Type::Audiocodec;

        std::string name;
        Type type = Type::Idle;

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

#pragma once


@@ 11,7 11,7 @@ namespace audio
    class ProfileIdle : public Profile
    {
      public:
        ProfileIdle() : Profile("Idle", Type::Idle, bsp::AudioDevice::Format{}, bsp::AudioDevice::Type::None)
        ProfileIdle() : Profile("Idle", Type::Idle, AudioDevice::Format{}, AudioDevice::Type::None)
        {}
    };


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

#pragma once


@@ 14,14 14,14 @@ namespace audio
        ProfilePlaybackBluetoothA2DP(Volume volume)
            : Profile("Playback Bluetooth A2DP",
                      Type::PlaybackBluetoothA2DP,
                      bsp::AudioDevice::Format{.sampleRate_Hz = 44100,
                                               .bitWidth      = 16,
                                               .flags         = 0,
                                               .outputVolume  = static_cast<float>(volume),
                                               .inputGain     = 0,
                                               .inputPath     = bsp::AudioDevice::InputPath::None,
                                               .outputPath    = bsp::AudioDevice::OutputPath::BluetoothA2DP},
                      bsp::AudioDevice::Type::Bluetooth)
                      AudioDevice::Format{.sampleRate_Hz = 44100,
                                          .bitWidth      = 16,
                                          .flags         = 0,
                                          .outputVolume  = static_cast<float>(volume),
                                          .inputGain     = 0,
                                          .inputPath     = AudioDevice::InputPath::None,
                                          .outputPath    = AudioDevice::OutputPath::None},
                      AudioDevice::Type::Bluetooth)
        {}
    };


M module-audio/Audio/Profiles/ProfilePlaybackHeadphones.hpp => module-audio/Audio/Profiles/ProfilePlaybackHeadphones.hpp +9 -10
@@ 1,4 1,4 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once



@@ 13,16 13,15 @@ namespace audio
        ProfilePlaybackHeadphones(Volume volume)
            : Profile("Playback Headphones",
                      Type::PlaybackHeadphones,
                      bsp::AudioDevice::Format{.sampleRate_Hz = 0,
                                               .bitWidth      = 16,
                                               .flags         = 0,
                                               .outputVolume  = static_cast<float>(volume),
                                               .inputGain     = 0,
                                               .inputPath     = bsp::AudioDevice::InputPath::None,
                                               .outputPath    = bsp::AudioDevice::OutputPath::Headphones},
                      bsp::AudioDevice::Type::Audiocodec)
                      AudioDevice::Format{.sampleRate_Hz = 0,
                                          .bitWidth      = 16,
                                          .flags         = 0,
                                          .outputVolume  = static_cast<float>(volume),
                                          .inputGain     = 0,
                                          .inputPath     = AudioDevice::InputPath::None,
                                          .outputPath    = AudioDevice::OutputPath::Headphones},
                      AudioDevice::Type::Audiocodec)
        {}
    };

} // namespace audio


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

#pragma once


@@ 14,14 14,14 @@ namespace audio
        ProfilePlaybackLoudspeaker(Volume volume)
            : Profile("Playback Loudspeaker",
                      Type::PlaybackLoudspeaker,
                      bsp::AudioDevice::Format{.sampleRate_Hz = 0,
                                               .bitWidth      = 16,
                                               .flags         = 0,
                                               .outputVolume  = static_cast<float>(volume),
                                               .inputGain     = 0,
                                               .inputPath     = bsp::AudioDevice::InputPath::None,
                                               .outputPath    = bsp::AudioDevice::OutputPath::Loudspeaker},
                      bsp::AudioDevice::Type::Audiocodec)
                      AudioDevice::Format{.sampleRate_Hz = 0,
                                          .bitWidth      = 16,
                                          .flags         = 0,
                                          .outputVolume  = static_cast<float>(volume),
                                          .inputGain     = 0,
                                          .inputPath     = AudioDevice::InputPath::None,
                                          .outputPath    = AudioDevice::OutputPath::Loudspeaker},
                      AudioDevice::Type::Audiocodec)
        {}
    };


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

#pragma once


@@ 12,18 12,17 @@ namespace audio
    {
      public:
        ProfileRecordingBluetoothHSP(Gain gain)
            : Profile(
                  "Recording Bluetooth HSP",
                  Type::RecordingHeadphones,
                  bsp::AudioDevice::Format{.sampleRate_Hz = 8000,
                                           .bitWidth      = 16,
                                           .flags         = static_cast<uint32_t>(
                                               bsp::AudioDevice::Flags::InputLeft), // microphone use left audio channel
                                           .outputVolume = 0,
                                           .inputGain    = static_cast<float>(gain),
                                           .inputPath    = bsp::AudioDevice::InputPath::BluetoothHSP,
                                           .outputPath   = bsp::AudioDevice::OutputPath::None},
                  bsp::AudioDevice::Type::Bluetooth)
            : Profile("Recording Bluetooth HSP",
                      Type::RecordingHeadphones,
                      AudioDevice::Format{.sampleRate_Hz = 8000,
                                          .bitWidth      = 16,
                                          .flags         = static_cast<uint32_t>(
                                              AudioDevice::Flags::InputLeft), // microphone use left audio channel
                                          .outputVolume = 0,
                                          .inputGain    = static_cast<float>(gain),
                                          .inputPath    = AudioDevice::InputPath::None,
                                          .outputPath   = AudioDevice::OutputPath::None},
                      AudioDevice::Type::Bluetooth)
        {}
    };


M module-audio/Audio/Profiles/ProfileRecordingHeadphones.hpp => module-audio/Audio/Profiles/ProfileRecordingHeadphones.hpp +12 -13
@@ 1,4 1,4 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once



@@ 11,18 11,17 @@ namespace audio
    {
      public:
        ProfileRecordingHeadphones(Gain gain)
            : Profile(
                  "Recording Headset",
                  Type::RecordingHeadphones,
                  bsp::AudioDevice::Format{.sampleRate_Hz = 44100,
                                           .bitWidth      = 16,
                                           .flags         = static_cast<uint32_t>(
                                               bsp::AudioDevice::Flags::InputLeft), // microphone use left audio channel
                                           .outputVolume = 0,
                                           .inputGain    = static_cast<float>(gain),
                                           .inputPath    = bsp::AudioDevice::InputPath::Headphones,
                                           .outputPath   = bsp::AudioDevice::OutputPath::None},
                  bsp::AudioDevice::Type::Audiocodec)
            : Profile("Recording Headset",
                      Type::RecordingHeadphones,
                      AudioDevice::Format{.sampleRate_Hz = 44100,
                                          .bitWidth      = 16,
                                          .flags         = static_cast<uint32_t>(
                                              AudioDevice::Flags::InputLeft), // microphone use left audio channel
                                          .outputVolume = 0,
                                          .inputGain    = static_cast<float>(gain),
                                          .inputPath    = AudioDevice::InputPath::Headphones,
                                          .outputPath   = AudioDevice::OutputPath::None},
                      AudioDevice::Type::Audiocodec)
        {}
    };


M module-audio/Audio/Profiles/ProfileRecordingOnBoardMic.hpp => module-audio/Audio/Profiles/ProfileRecordingOnBoardMic.hpp +12 -13
@@ 1,4 1,4 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once



@@ 11,18 11,17 @@ namespace audio
    {
      public:
        ProfileRecordingOnBoardMic(Gain gain)
            : Profile(
                  "Recording On Board Microphone",
                  Type::RecordingBuiltInMic,
                  bsp::AudioDevice::Format{.sampleRate_Hz = 44100,
                                           .bitWidth      = 16,
                                           .flags         = static_cast<uint32_t>(
                                               bsp::AudioDevice::Flags::InputLeft), // microphone use left audio channel
                                           .outputVolume = 0,
                                           .inputGain    = static_cast<float>(gain),
                                           .inputPath    = bsp::AudioDevice::InputPath::Microphone,
                                           .outputPath   = bsp::AudioDevice::OutputPath::None},
                  bsp::AudioDevice::Type::Audiocodec)
            : Profile("Recording On Board Microphone",
                      Type::RecordingBuiltInMic,
                      AudioDevice::Format{.sampleRate_Hz = 44100,
                                          .bitWidth      = 16,
                                          .flags         = static_cast<uint32_t>(
                                              AudioDevice::Flags::InputLeft), // microphone use left audio channel
                                          .outputVolume = 0,
                                          .inputGain    = static_cast<float>(gain),
                                          .inputPath    = AudioDevice::InputPath::Microphone,
                                          .outputPath   = AudioDevice::OutputPath::None},
                      AudioDevice::Type::Audiocodec)
        {}
    };


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

#pragma once


@@ 11,19 11,19 @@ namespace audio
    {
      public:
        ProfileRoutingBluetoothHSP(Volume volume, Gain gain)
            : Profile("Routing Bluetooth HSP",
                      Type::RoutingBluetoothHSP,
                      bsp::AudioDevice::Format{
                          .sampleRate_Hz = 8000,
                          .bitWidth      = 16,
                          .flags         = static_cast<uint32_t>(
                                       bsp::AudioDevice::Flags::InputLeft) | // microphone use left audio channel
                                   static_cast<uint32_t>(bsp::AudioDevice::Flags::OutputMono),
                          .outputVolume = static_cast<float>(volume),
                          .inputGain    = static_cast<float>(gain),
                          .inputPath    = bsp::AudioDevice::InputPath::BluetoothHSP,
                          .outputPath   = bsp::AudioDevice::OutputPath::BluetoothHSP},
                      bsp::AudioDevice::Type::Bluetooth)
            : Profile(
                  "Routing Bluetooth HSP",
                  Type::RoutingBluetoothHSP,
                  AudioDevice::Format{.sampleRate_Hz = 8000,
                                      .bitWidth      = 16,
                                      .flags         = static_cast<uint32_t>(
                                                   AudioDevice::Flags::InputLeft) | // microphone use left audio channel
                                               static_cast<uint32_t>(AudioDevice::Flags::OutputMono),
                                      .outputVolume = static_cast<float>(volume),
                                      .inputGain    = static_cast<float>(gain),
                                      .inputPath    = AudioDevice::InputPath::None,
                                      .outputPath   = AudioDevice::OutputPath::None},
                  AudioDevice::Type::Bluetooth)
        {}
    };


M module-audio/Audio/Profiles/ProfileRoutingEarspeaker.hpp => module-audio/Audio/Profiles/ProfileRoutingEarspeaker.hpp +14 -15
@@ 1,4 1,4 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once



@@ 11,21 11,20 @@ namespace audio
    {
      public:
        ProfileRoutingEarspeaker(Volume volume, Gain gain)
            : Profile("Routing Earspeaker",
                      Type::RoutingEarspeaker,
                      bsp::AudioDevice::Format{
                          .sampleRate_Hz = 16000,
                          .bitWidth      = 16,
                          .flags         = static_cast<uint32_t>(
                                       bsp::AudioDevice::Flags::InputLeft) | // microphone use left audio channel
                                   static_cast<uint32_t>(bsp::AudioDevice::Flags::OutputMono),
                          .outputVolume = static_cast<float>(volume),
                          .inputGain    = static_cast<float>(gain),
                          .inputPath    = bsp::AudioDevice::InputPath::Microphone,
                          .outputPath   = bsp::AudioDevice::OutputPath::Earspeaker},
                      bsp::AudioDevice::Type::Audiocodec)
            : Profile(
                  "Routing Earspeaker",
                  Type::RoutingEarspeaker,
                  AudioDevice::Format{.sampleRate_Hz = 16000,
                                      .bitWidth      = 16,
                                      .flags         = static_cast<uint32_t>(
                                                   AudioDevice::Flags::InputLeft) | // microphone use left audio channel
                                               static_cast<uint32_t>(AudioDevice::Flags::OutputMono),
                                      .outputVolume = static_cast<float>(volume),
                                      .inputGain    = static_cast<float>(gain),
                                      .inputPath    = AudioDevice::InputPath::Microphone,
                                      .outputPath   = AudioDevice::OutputPath::Earspeaker},
                  AudioDevice::Type::Audiocodec)
        {}
    };

} // namespace audio


M module-audio/Audio/Profiles/ProfileRoutingHeadphones.hpp => module-audio/Audio/Profiles/ProfileRoutingHeadphones.hpp +14 -14
@@ 1,4 1,4 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once



@@ 11,19 11,19 @@ namespace audio
    {
      public:
        ProfileRoutingHeadphones(Volume volume, Gain gain)
            : Profile("Routing Headset",
                      Type::RoutingHeadphones,
                      bsp::AudioDevice::Format{
                          .sampleRate_Hz = 16000,
                          .bitWidth      = 16,
                          .flags         = static_cast<uint32_t>(
                                       bsp::AudioDevice::Flags::InputLeft) | // microphone use left audio channel
                                   static_cast<uint32_t>(bsp::AudioDevice::Flags::OutputMono),
                          .outputVolume = static_cast<float>(volume),
                          .inputGain    = static_cast<float>(gain),
                          .inputPath    = bsp::AudioDevice::InputPath::Headphones,
                          .outputPath   = bsp::AudioDevice::OutputPath::HeadphonesMono},
                      bsp::AudioDevice::Type::Audiocodec)
            : Profile(
                  "Routing Headset",
                  Type::RoutingHeadphones,
                  AudioDevice::Format{.sampleRate_Hz = 16000,
                                      .bitWidth      = 16,
                                      .flags         = static_cast<uint32_t>(
                                                   AudioDevice::Flags::InputLeft) | // microphone use left audio channel
                                               static_cast<uint32_t>(AudioDevice::Flags::OutputMono),
                                      .outputVolume = static_cast<float>(volume),
                                      .inputGain    = static_cast<float>(gain),
                                      .inputPath    = AudioDevice::InputPath::Headphones,
                                      .outputPath   = AudioDevice::OutputPath::Headphones},
                  AudioDevice::Type::Audiocodec)
        {}
    };


M module-audio/Audio/Profiles/ProfileRoutingLoudspeaker.hpp => module-audio/Audio/Profiles/ProfileRoutingLoudspeaker.hpp +14 -14
@@ 1,4 1,4 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once



@@ 11,19 11,19 @@ namespace audio
    {
      public:
        ProfileRoutingLoudspeaker(Volume volume, Gain gain)
            : Profile("Routing Speakerphone",
                      Type::RoutingLoudspeaker,
                      bsp::AudioDevice::Format{
                          .sampleRate_Hz = 16000,
                          .bitWidth      = 16,
                          .flags         = static_cast<uint32_t>(
                                       bsp::AudioDevice::Flags::InputLeft) | // microphone use left audio channel
                                   static_cast<uint32_t>(bsp::AudioDevice::Flags::OutputMono),
                          .outputVolume = static_cast<float>(volume),
                          .inputGain    = static_cast<float>(gain),
                          .inputPath    = bsp::AudioDevice::InputPath::Microphone,
                          .outputPath   = bsp::AudioDevice::OutputPath::LoudspeakerMono},
                      bsp::AudioDevice::Type::Audiocodec)
            : Profile(
                  "Routing Speakerphone",
                  Type::RoutingLoudspeaker,
                  AudioDevice::Format{.sampleRate_Hz = 16000,
                                      .bitWidth      = 16,
                                      .flags         = static_cast<uint32_t>(
                                                   AudioDevice::Flags::InputLeft) | // microphone use left audio channel
                                               static_cast<uint32_t>(AudioDevice::Flags::OutputMono),
                                      .outputVolume = static_cast<float>(volume),
                                      .inputGain    = static_cast<float>(gain),
                                      .inputPath    = AudioDevice::InputPath::Microphone,
                                      .outputPath   = AudioDevice::OutputPath::Loudspeaker},
                  AudioDevice::Type::Audiocodec)
        {}
    };


M module-audio/CMakeLists.txt => module-audio/CMakeLists.txt +14 -34
@@ 1,9 1,11 @@
cmake_minimum_required(VERSION 3.12)
# Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
# For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

cmake_minimum_required(VERSION 3.12)

project(module-audio VERSION 1.0
        DESCRIPTION "Audio module library")


set(SOURCES
        "${CMAKE_CURRENT_SOURCE_DIR}/Audio/decoder/Decoder.cpp"
        "${CMAKE_CURRENT_SOURCE_DIR}/Audio/decoder/DecoderWorker.cpp"


@@ 16,13 18,13 @@ set(SOURCES
        "${CMAKE_CURRENT_SOURCE_DIR}/Audio/encoder/EncoderWAV.cpp"

        "${CMAKE_CURRENT_SOURCE_DIR}/Audio/Audio.cpp"
        "${CMAKE_CURRENT_SOURCE_DIR}/Audio/AudioDeviceFactory.cpp"
        "${CMAKE_CURRENT_SOURCE_DIR}/Audio/AudioMux.cpp"
        "${CMAKE_CURRENT_SOURCE_DIR}/Audio/AudioCommon.cpp"
        "${CMAKE_CURRENT_SOURCE_DIR}/Audio/Endpoint.cpp"
        "${CMAKE_CURRENT_SOURCE_DIR}/Audio/Stream.cpp"
        "${CMAKE_CURRENT_SOURCE_DIR}/Audio/StreamFactory.cpp"
        "${CMAKE_CURRENT_SOURCE_DIR}/Audio/StreamQueuedEventsListener.cpp"
        "${CMAKE_CURRENT_SOURCE_DIR}/Audio/BluetoothProxyAudio.cpp"
        "${CMAKE_CURRENT_SOURCE_DIR}/Audio/Operation/Operation.cpp"
        "${CMAKE_CURRENT_SOURCE_DIR}/Audio/Operation/PlaybackOperation.cpp"
        "${CMAKE_CURRENT_SOURCE_DIR}/Audio/Operation/RecorderOperation.cpp"


@@ 31,51 33,30 @@ set(SOURCES
        "${CMAKE_CURRENT_SOURCE_DIR}/Audio/Profiles/Profile.cpp"
)

if(NOT ${PROJECT_TARGET} STREQUAL "TARGET_Linux")
    include(targets/Target_Cross.cmake)
else()
    include(targets/Target_Linux.cmake)
endif()


add_library(${PROJECT_NAME} STATIC ${SOURCES} ${BOARD_SOURCES})

target_include_directories( ${PROJECT_NAME} PRIVATE ${TAGLIB_INCLUDE_DIRS} )
# include target specific rules
set(AUDIO_BOARD_LIBRARY audio-${PROJECT_TARGET_NAME})
add_subdirectory(board/${PROJECT_TARGET_NAME})
target_include_directories(${AUDIO_BOARD_LIBRARY} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})


# Board specific compilation definitions,options,include directories and features
add_library(${PROJECT_NAME} STATIC ${SOURCES})
target_include_directories(${PROJECT_NAME} PRIVATE ${TAGLIB_INCLUDE_DIRS})
target_compile_definitions(${PROJECT_NAME} PUBLIC ${PROJECT_CONFIG_DEFINITIONS})
target_compile_definitions(${PROJECT_NAME} PUBLIC ${PROJECT_TARGET})
target_compile_definitions(${PROJECT_NAME} PUBLIC ${TARGET_COMPILE_DEFINITIONS})
target_include_directories(${PROJECT_NAME} PUBLIC ${BOARD_DIR_INCLUDES})
target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_INCLUDES})
target_compile_features(${PROJECT_NAME} PUBLIC ${TARGET_COMPILE_FEATURES})
target_link_options(${PROJECT_NAME} PUBLIC ${TARGET_LINK_OPTIONS})

target_include_directories(${PROJECT_NAME} PUBLIC "${CMAKE_CURRENT_LIST_DIR}/../module-bsp/bsp/audio")
target_include_directories(${PROJECT_NAME} INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})

# supress warning for flac decoder
set_source_files_properties(
        "${CMAKE_CURRENT_SOURCE_DIR}/Audio/decoder/decoderFLAC.cpp"
        PROPERTIES COMPILE_FLAGS
	    "-Wno-implicit-fallthrough -Wno-error=maybe-uninitialized"
)

target_compile_definitions(${PROJECT_NAME}

        PUBLIC

)

target_include_directories(${PROJECT_NAME}

        PUBLIC

        ${CMAKE_CURRENT_SOURCE_DIR}

	"-Wno-implicit-fallthrough -Wno-error=maybe-uninitialized"
)

target_link_libraries(${PROJECT_NAME}
    ${AUDIO_BOARD_LIBRARY}
    module-bsp
    module-os
    module-utils


@@ 86,4 67,3 @@ target_link_libraries(${PROJECT_NAME}
if (${ENABLE_TESTS})
    add_subdirectory(Audio/test)
endif ()


A module-audio/board/linux/CMakeLists.txt => module-audio/board/linux/CMakeLists.txt +12 -0
@@ 0,0 1,12 @@
# Copyright (c) 2021, Mudita Sp. z.o.o. All rights reserved.
# For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

set(AUDIO_LINUX_SOURCES
	LinuxAudioPlatform.cpp
)

add_library(${AUDIO_BOARD_LIBRARY} STATIC ${AUDIO_LINUX_SOURCES})
target_include_directories(${AUDIO_BOARD_LIBRARY} INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(${AUDIO_BOARD_LIBRARY}
    module-os
)

A module-audio/board/linux/LinuxAudioPlatform.cpp => module-audio/board/linux/LinuxAudioPlatform.cpp +25 -0
@@ 0,0 1,25 @@
// Copyright (c) 2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <Audio/AudioPlatform.hpp>

#include <memory>
#include <utility>

using audio::AudioDevice;
using audio::AudioDeviceFactory;
using audio::AudioPlatform;

class DummyAudioFactory : public AudioDeviceFactory
{
  protected:
    std::shared_ptr<AudioDevice> getDeviceFromType([[maybe_unused]] AudioDevice::Type deviceType)
    {
        return nullptr;
    }
};

std::unique_ptr<AudioDeviceFactory> AudioPlatform::GetDeviceFactory()
{
    return std::make_unique<DummyAudioFactory>();
}

A module-audio/board/rt1051/CMakeLists.txt => module-audio/board/rt1051/CMakeLists.txt +17 -0
@@ 0,0 1,17 @@
# Copyright (c) 2021, Mudita Sp. z.o.o. All rights reserved.
# For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

set(AUDIO_RT1051_SOURCES
    "SAIAudioDevice.cpp"
    "RT1051AudioCodec.cpp"
    "RT1051CellularAudio.cpp"
    "RT1051DeviceFactory.cpp"
    "RT1051Platform.cpp"
)

add_library(${AUDIO_BOARD_LIBRARY} STATIC ${AUDIO_RT1051_SOURCES})
target_include_directories(${AUDIO_BOARD_LIBRARY} INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(${AUDIO_BOARD_LIBRARY}
    module-bsp
    module-os
)

R module-bsp/board/rt1051/bsp/audio/RT1051Audiocodec.cpp => module-audio/board/rt1051/RT1051AudioCodec.cpp +71 -94
@@ 1,43 1,68 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "RT1051Audiocodec.hpp"
#include "RT1051AudioCodec.hpp"
#include "board.h"
#include "dma_config.h"
#include "log/log.hpp"

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

#include <mutex.hpp>

namespace bsp
namespace audio
{
    sai_edma_handle_t RT1051AudioCodec::txHandle = {};
    sai_edma_handle_t RT1051AudioCodec::rxHandle = {};

    using namespace drivers;

    std::shared_ptr<drivers::DriverPLL> RT1051Audiocodec::pllAudio;
    std::shared_ptr<drivers::DriverDMAMux> RT1051Audiocodec::dmamux;
    std::shared_ptr<drivers::DriverDMA> RT1051Audiocodec::dma;
    std::unique_ptr<drivers::DriverDMAHandle> RT1051Audiocodec::rxDMAHandle;
    std::unique_ptr<drivers::DriverDMAHandle> RT1051Audiocodec::txDMAHandle;
    sai_config_t RT1051Audiocodec::config             = {};
    std::uint32_t RT1051Audiocodec::mclkSourceClockHz = 0;
    sai_edma_handle_t RT1051Audiocodec::txHandle      = {};
    sai_edma_handle_t RT1051Audiocodec::rxHandle      = {};

    RT1051Audiocodec::RT1051Audiocodec()
    RT1051AudioCodec::RT1051AudioCodec()
        : SAIAudioDevice(BOARD_AUDIOCODEC_SAIx, &rxHandle, &txHandle), saiInFormat{}, saiOutFormat{},
          codecParams{}, codec{}
    {
        isInitialized = true;
    }

    RT1051Audiocodec::~RT1051Audiocodec()
    RT1051AudioCodec::~RT1051AudioCodec()
    {
        Stop();
    }

    AudioDevice::RetCode RT1051Audiocodec::Start(const bsp::AudioDevice::Format &format)
    CodecParamsMAX98090::InputPath RT1051AudioCodec::getCodecInputPath(const AudioDevice::Format &format)
    {
        switch (format.inputPath) {
        case AudioDevice::InputPath::Headphones:
            return CodecParamsMAX98090::InputPath::Headphones;

        case AudioDevice::InputPath::Microphone:
            return CodecParamsMAX98090::InputPath::Microphone;

        default:
            return CodecParamsMAX98090::InputPath::None;
        };
    }

    CodecParamsMAX98090::OutputPath RT1051AudioCodec::getCodecOutputPath(const AudioDevice::Format &format)
    {
        auto mono = (format.flags & static_cast<std::uint32_t>(AudioDevice::Flags::OutputMono)) != 0;

        switch (format.outputPath) {
        case AudioDevice::OutputPath::Headphones:
            return mono ? CodecParamsMAX98090::OutputPath::HeadphonesMono : CodecParamsMAX98090::OutputPath::Headphones;

        case AudioDevice::OutputPath::Earspeaker:
            return CodecParamsMAX98090::OutputPath::Earspeaker;

        case AudioDevice::OutputPath::Loudspeaker:
            return mono ? CodecParamsMAX98090::OutputPath::LoudspeakerMono
                        : CodecParamsMAX98090::OutputPath::Loudspeaker;

        default:
            return CodecParamsMAX98090::OutputPath::None;
        }
    }

    AudioDevice::RetCode RT1051AudioCodec::Start(const AudioDevice::Format &format)
    {
        cpp_freertos::LockGuard lock(mutex);



@@ 78,8 103,8 @@ namespace bsp
            LOG_ERROR("Unsupported sample rate");
        }

        codecParams.inputPath  = format.inputPath;
        codecParams.outputPath = format.outputPath;
        codecParams.inputPath  = getCodecInputPath(format);
        codecParams.outputPath = getCodecOutputPath(format);
        codecParams.outVolume  = format.outputVolume;
        codecParams.inGain     = format.inputGain;
        codec.Start(codecParams);


@@ 92,7 117,7 @@ namespace bsp
        return AudioDevice::RetCode::Success;
    }

    AudioDevice::RetCode RT1051Audiocodec::Stop()
    AudioDevice::RetCode RT1051AudioCodec::Stop()
    {
        cpp_freertos::LockGuard lock(mutex);



@@ 111,7 136,7 @@ namespace bsp
        return AudioDevice::RetCode::Success;
    }

    AudioDevice::RetCode RT1051Audiocodec::OutputVolumeCtrl(float vol)
    AudioDevice::RetCode RT1051AudioCodec::OutputVolumeCtrl(float vol)
    {
        currentFormat.outputVolume = vol;
        CodecParamsMAX98090 params;


@@ 121,7 146,7 @@ namespace bsp
        return AudioDevice::RetCode::Success;
    }

    AudioDevice::RetCode RT1051Audiocodec::InputGainCtrl(float gain)
    AudioDevice::RetCode RT1051AudioCodec::InputGainCtrl(float gain)
    {
        currentFormat.inputGain = gain;
        CodecParamsMAX98090 params;


@@ 131,27 156,27 @@ namespace bsp
        return AudioDevice::RetCode::Success;
    }

    AudioDevice::RetCode RT1051Audiocodec::InputPathCtrl(InputPath inputPath)
    AudioDevice::RetCode RT1051AudioCodec::InputPathCtrl(InputPath inputPath)
    {
        currentFormat.inputPath = inputPath;
        CodecParamsMAX98090 params;
        params.inputPath = inputPath;
        params.inputPath = getCodecInputPath(currentFormat);
        params.opCmd     = CodecParamsMAX98090::Cmd::SetInput;
        codec.Ioctrl(params);
        return AudioDevice::RetCode::Success;
    }

    AudioDevice::RetCode RT1051Audiocodec::OutputPathCtrl(OutputPath outputPath)
    AudioDevice::RetCode RT1051AudioCodec::OutputPathCtrl(OutputPath outputPath)
    {
        currentFormat.outputPath = outputPath;
        CodecParamsMAX98090 params;
        params.outputPath = outputPath;
        params.outputPath = getCodecOutputPath(currentFormat);
        params.opCmd      = CodecParamsMAX98090::Cmd::SetOutput;
        codec.Ioctrl(params);
        return AudioDevice::RetCode::Success;
    }

    bool RT1051Audiocodec::IsFormatSupported(const bsp::AudioDevice::Format &format)
    bool RT1051AudioCodec::IsFormatSupported(const AudioDevice::Format &format)
    {

        if (CodecParamsMAX98090::ValToSampleRate(format.sampleRate_Hz) == CodecParamsMAX98090::SampleRate::Invalid) {


@@ 159,68 184,19 @@ namespace bsp
        }
        return true;
    }
    // INTERNALS

    void RT1051Audiocodec::Init()
    {

        pllAudio = DriverPLL::Create(static_cast<PLLInstances>(BoardDefinitions ::AUDIO_PLL), DriverPLLParams{});
        dmamux   = DriverDMAMux::Create(static_cast<DMAMuxInstances>(BoardDefinitions ::AUDIOCODEC_DMAMUX),
                                      DriverDMAMuxParams{});
        dma      = DriverDMA::Create(static_cast<DMAInstances>(BoardDefinitions ::AUDIOCODEC_DMA), DriverDMAParams{});

        // Enable MCLK clock
        IOMUXC_GPR->GPR1 |= BOARD_AUDIOCODEC_SAIx_MCLK_MASK;

        txDMAHandle = dma->CreateHandle(static_cast<uint32_t>(BoardDefinitions ::AUDIOCODEC_TX_DMA_CHANNEL));
        rxDMAHandle = dma->CreateHandle(static_cast<uint32_t>(BoardDefinitions ::AUDIOCODEC_RX_DMA_CHANNEL));
        dmamux->Enable(static_cast<uint32_t>(BoardDefinitions ::AUDIOCODEC_TX_DMA_CHANNEL),
                       BSP_AUDIOCODEC_SAIx_DMA_TX_SOURCE);
        dmamux->Enable(static_cast<uint32_t>(BoardDefinitions ::AUDIOCODEC_RX_DMA_CHANNEL),
                       BSP_AUDIOCODEC_SAIx_DMA_RX_SOURCE);

        mclkSourceClockHz = GetPerphSourceClock(PerphClock_SAI2);

        // Initialize SAI Tx module
        SAI_TxGetDefaultConfig(&config);
        config.masterSlave = kSAI_Slave;
        SAI_TxInit(BOARD_AUDIOCODEC_SAIx, &config);

        // Initialize SAI Rx module
        SAI_RxGetDefaultConfig(&config);

        config.masterSlave = kSAI_Slave;
        SAI_RxInit(BOARD_AUDIOCODEC_SAIx, &config);
    }

    void RT1051Audiocodec::Deinit()
    {
        memset(&config, 0, sizeof config);
        SAI_Deinit(BOARD_AUDIOCODEC_SAIx);
        if (dmamux) {
            dmamux->Disable(static_cast<uint32_t>(BoardDefinitions ::AUDIOCODEC_TX_DMA_CHANNEL));
            dmamux->Disable(static_cast<uint32_t>(BoardDefinitions ::AUDIOCODEC_RX_DMA_CHANNEL));
        }

        // force order of destruction
        txDMAHandle.reset();
        rxDMAHandle.reset();
        dma.reset();
        dmamux.reset();
        pllAudio.reset();
    }

    void RT1051Audiocodec::InStart()
    void RT1051AudioCodec::InStart()
    {
        sai_transfer_format_t sai_format = {0};
        sai_transfer_format_t sai_format;
        auto audioCfg = bsp::AudioConfig::get();

        /* Configure the audio format */
        sai_format.bitWidth           = saiInFormat.bitWidth;
        sai_format.channel            = 0U;
        sai_format.sampleRate_Hz      = saiInFormat.sampleRate_Hz;
        sai_format.masterClockHz      = mclkSourceClockHz;
        sai_format.masterClockHz      = audioCfg->mclkSourceClockHz;
        sai_format.isFrameSyncCompact = false;
        sai_format.protocol           = config.protocol;
        sai_format.protocol           = audioCfg->config.protocol;
        sai_format.stereo             = saiInFormat.stereo;
#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
        sai_format.watermark = FSL_FEATURE_SAI_FIFO_COUNT / 2U;


@@ 230,10 206,10 @@ namespace bsp
                                       &rxHandle,
                                       rxAudioCodecCallback,
                                       this,
                                       reinterpret_cast<edma_handle_t *>(rxDMAHandle->GetHandle()));
                                       reinterpret_cast<edma_handle_t *>(audioCfg->rxDMAHandle->GetHandle()));

        SAI_TransferRxSetFormatEDMA(
            BOARD_AUDIOCODEC_SAIx, &rxHandle, &sai_format, mclkSourceClockHz, mclkSourceClockHz);
            BOARD_AUDIOCODEC_SAIx, &rxHandle, &sai_format, audioCfg->mclkSourceClockHz, audioCfg->mclkSourceClockHz);

        DisableIRQ(BOARD_AUDIOCODEC_SAIx_RX_IRQ);



@@ 241,17 217,18 @@ namespace bsp
        SAI_RxSoftwareReset(BOARD_AUDIOCODEC_SAIx, kSAI_ResetTypeSoftware);
    }

    void RT1051Audiocodec::OutStart()
    void RT1051AudioCodec::OutStart()
    {
        sai_transfer_format_t sai_format = {0};
        sai_transfer_format_t sai_format;
        auto audioCfg = bsp::AudioConfig::get();

        /* Configure the audio format */
        sai_format.bitWidth           = saiOutFormat.bitWidth;
        sai_format.channel            = 0U;
        sai_format.sampleRate_Hz      = saiOutFormat.sampleRate_Hz;
        sai_format.masterClockHz      = mclkSourceClockHz;
        sai_format.masterClockHz      = audioCfg->mclkSourceClockHz;
        sai_format.isFrameSyncCompact = false;
        sai_format.protocol           = config.protocol;
        sai_format.protocol           = audioCfg->config.protocol;
        sai_format.stereo             = saiOutFormat.stereo;
#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
        sai_format.watermark = FSL_FEATURE_SAI_FIFO_COUNT / 2U;


@@ 261,9 238,9 @@ namespace bsp
                                       &txHandle,
                                       txAudioCodecCallback,
                                       this,
                                       reinterpret_cast<edma_handle_t *>(txDMAHandle->GetHandle()));
                                       reinterpret_cast<edma_handle_t *>(audioCfg->txDMAHandle->GetHandle()));
        SAI_TransferTxSetFormatEDMA(
            BOARD_AUDIOCODEC_SAIx, &txHandle, &sai_format, mclkSourceClockHz, mclkSourceClockHz);
            BOARD_AUDIOCODEC_SAIx, &txHandle, &sai_format, audioCfg->mclkSourceClockHz, audioCfg->mclkSourceClockHz);

        DisableIRQ(BOARD_AUDIOCODEC_SAIx_TX_IRQ);



@@ 271,7 248,7 @@ namespace bsp
        SAI_TxSoftwareReset(BOARD_AUDIOCODEC_SAIx, kSAI_ResetTypeSoftware);
    }

    void RT1051Audiocodec::OutStop()
    void RT1051AudioCodec::OutStop()
    {
        SAI_TxDisableInterrupts(BOARD_AUDIOCODEC_SAIx, kSAI_FIFOErrorInterruptEnable);
        if (txHandle.dmaHandle) {


@@ 280,7 257,7 @@ namespace bsp
        memset(&txHandle, 0, sizeof(txHandle));
    }

    void RT1051Audiocodec::InStop()
    void RT1051AudioCodec::InStop()
    {
        SAI_RxDisableInterrupts(BOARD_AUDIOCODEC_SAIx, kSAI_FIFOErrorInterruptEnable);
        if (rxHandle.dmaHandle) {


@@ 291,14 268,14 @@ namespace bsp

    void rxAudioCodecCallback(I2S_Type *base, sai_edma_handle_t *handle, status_t status, void *userData)
    {
        auto self = static_cast<RT1051Audiocodec *>(userData);
        auto self = static_cast<RT1051AudioCodec *>(userData);
        self->onDataReceive();
    }

    void txAudioCodecCallback(I2S_Type *base, sai_edma_handle_t *handle, status_t status, void *userData)
    {
        auto self = static_cast<RT1051Audiocodec *>(userData);
        auto self = static_cast<RT1051AudioCodec *>(userData);
        self->onDataSend();
    }

} // namespace bsp
} // namespace audio

R module-bsp/board/rt1051/bsp/audio/RT1051Audiocodec.hpp => module-audio/board/rt1051/RT1051AudioCodec.hpp +9 -19
@@ 10,7 10,7 @@
#include "task.h"
#include "macros.h"

#include "CodecMAX98090.hpp"
#include "board/rt1051/bsp/audio/CodecMAX98090.hpp"

#include "drivers/pll/DriverPLL.hpp"
#include "drivers/dmamux/DriverDMAMux.hpp"


@@ 18,24 18,21 @@

#include <mutex.hpp>

namespace bsp
namespace audio
{

    void txAudioCodecCallback(I2S_Type *base, sai_edma_handle_t *handle, status_t status, void *userData);
    void rxAudioCodecCallback(I2S_Type *base, sai_edma_handle_t *handle, status_t status, void *userData);

    class RT1051Audiocodec : public SAIAudioDevice
    class RT1051AudioCodec : public SAIAudioDevice
    {

      public:
        static void Init();
        static void Deinit();

        friend void txAudioCodecCallback(I2S_Type *base, sai_edma_handle_t *handle, status_t status, void *userData);
        friend void rxAudioCodecCallback(I2S_Type *base, sai_edma_handle_t *handle, status_t status, void *userData);

        RT1051Audiocodec();
        virtual ~RT1051Audiocodec();
        RT1051AudioCodec();
        virtual ~RT1051AudioCodec();

        AudioDevice::RetCode Start(const Format &format) override final;
        AudioDevice::RetCode Stop() override final;


@@ 63,22 60,12 @@ namespace bsp
            sai_mono_stereo_t stereo; /*!< Mono or stereo */
        };

        static sai_config_t config;
        static std::uint32_t mclkSourceClockHz;

        State state = State::Stopped;
        SAIFormat saiInFormat;
        SAIFormat saiOutFormat;
        CodecParamsMAX98090 codecParams;
        CodecMAX98090 codec;

        // M.P: It is important to destroy these drivers in specific order
        static std::shared_ptr<drivers::DriverPLL> pllAudio;
        static std::shared_ptr<drivers::DriverDMAMux> dmamux;
        static std::shared_ptr<drivers::DriverDMA> dma;
        static std::unique_ptr<drivers::DriverDMAHandle> rxDMAHandle;
        static std::unique_ptr<drivers::DriverDMAHandle> txDMAHandle;

        static AT_NONCACHEABLE_SECTION_INIT(sai_edma_handle_t txHandle);
        static AT_NONCACHEABLE_SECTION_INIT(sai_edma_handle_t rxHandle);



@@ 86,5 73,8 @@ namespace bsp
        void InStart();
        void OutStop();
        void InStop();

        CodecParamsMAX98090::InputPath getCodecInputPath(const AudioDevice::Format &format);
        CodecParamsMAX98090::OutputPath getCodecOutputPath(const AudioDevice::Format &format);
    };
} // namespace bsp
} // namespace audio

R module-bsp/board/rt1051/bsp/audio/RT1051CellularAudio.cpp => module-audio/board/rt1051/RT1051CellularAudio.cpp +6 -6
@@ 10,7 10,7 @@

#include <mutex.hpp>

namespace bsp
namespace audio
{

    using namespace drivers;


@@ 30,7 30,7 @@ namespace bsp
        Deinit();
    }

    AudioDevice::RetCode RT1051CellularAudio::Start(const bsp::AudioDevice::Format &format)
    AudioDevice::RetCode RT1051CellularAudio::Start(const AudioDevice::Format &format)
    {
        cpp_freertos::LockGuard lock(mutex);



@@ 118,7 118,7 @@ namespace bsp
        return AudioDevice::RetCode::Success;
    }

    bool RT1051CellularAudio::IsFormatSupported(const bsp::AudioDevice::Format &format)
    bool RT1051CellularAudio::IsFormatSupported(const AudioDevice::Format &format)
    {
        return true;
    }


@@ 172,7 172,7 @@ namespace bsp

    void RT1051CellularAudio::InStart()
    {
        sai_transfer_format_t sai_format = {0};
        sai_transfer_format_t sai_format;

        /* Configure the audio format */
        sai_format.bitWidth           = saiInFormat.bitWidth;


@@ 203,7 203,7 @@ namespace bsp

    void RT1051CellularAudio::OutStart()
    {
        sai_transfer_format_t sai_format = {0};
        sai_transfer_format_t sai_format;

        /* Configure the audio format */
        sai_format.bitWidth           = saiOutFormat.bitWidth;


@@ 263,4 263,4 @@ namespace bsp
        self->onDataSend();
    }

} // namespace bsp
} // namespace audio

R module-bsp/board/rt1051/bsp/audio/RT1051CellularAudio.hpp => module-audio/board/rt1051/RT1051CellularAudio.hpp +2 -2
@@ 17,7 17,7 @@

#include <mutex.hpp>

namespace bsp
namespace audio
{

    void txCellularCallback(I2S_Type *base, sai_edma_handle_t *handle, status_t status, void *userData);


@@ 80,6 80,6 @@ namespace bsp
        void OutStop();
        void InStop();
    };
} // namespace bsp
} // namespace audio

#endif // PUREPHONE_RT1051CELLULARAUDIO_HPP

A module-audio/board/rt1051/RT1051DeviceFactory.cpp => module-audio/board/rt1051/RT1051DeviceFactory.cpp +35 -0
@@ 0,0 1,35 @@
// Copyright (c) 2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "RT1051DeviceFactory.hpp"
#include "board/rt1051/RT1051AudioCodec.hpp"
#include "board/rt1051/RT1051CellularAudio.hpp"

using audio::AudioDevice;
using audio::RT1051AudioCodec;
using audio::RT1051CellularAudio;
using audio::RT1051DeviceFactory;

std::shared_ptr<AudioDevice> RT1051DeviceFactory::getDeviceFromType(AudioDevice::Type deviceType)
{
    std::shared_ptr<AudioDevice> device;
    switch (deviceType) {
    case AudioDevice::Type::Audiocodec: {
        device = std::make_unique<RT1051AudioCodec>();
    } break;

    case AudioDevice::Type::Bluetooth: {
        LOG_FATAL("Bluetooth audio is not yet supported");
        device = nullptr;
    } break;

    case AudioDevice::Type::Cellular: {
        device = std::make_unique<RT1051CellularAudio>();
    } break;

    default:
        break;
    };

    return device;
}

A module-audio/board/rt1051/RT1051DeviceFactory.hpp => module-audio/board/rt1051/RT1051DeviceFactory.hpp +17 -0
@@ 0,0 1,17 @@
// Copyright (c) 2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <Audio/AudioDeviceFactory.hpp>

namespace audio
{

    class RT1051DeviceFactory : public AudioDeviceFactory
    {
      protected:
        std::shared_ptr<AudioDevice> getDeviceFromType(AudioDevice::Type deviceType) override;
    };

}; // namespace audio

A module-audio/board/rt1051/RT1051Platform.cpp => module-audio/board/rt1051/RT1051Platform.cpp +16 -0
@@ 0,0 1,16 @@
// Copyright (c) 2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <Audio/AudioPlatform.hpp>

#include "RT1051DeviceFactory.hpp"

#include <utility>

using audio::AudioDeviceFactory;
using audio::AudioPlatform;

std::unique_ptr<AudioDeviceFactory> AudioPlatform::GetDeviceFactory()
{
    return std::make_unique<RT1051DeviceFactory>();
}

R module-bsp/board/rt1051/bsp/audio/SAIAudioDevice.cpp => module-audio/board/rt1051/SAIAudioDevice.cpp +1 -1
@@ 3,7 3,7 @@

#include "SAIAudioDevice.hpp"

using namespace bsp;
using namespace audio;

SAIAudioDevice::SAIAudioDevice(I2S_Type *base, sai_edma_handle_t *rxHandle, sai_edma_handle_t *txHandle)
    : AudioDevice(saiCapabilities, saiCapabilities), _base(base), rx(rxHandle), tx(txHandle)

R module-bsp/board/rt1051/bsp/audio/SAIAudioDevice.hpp => module-audio/board/rt1051/SAIAudioDevice.hpp +4 -4
@@ 3,14 3,14 @@

#pragma once

#include "bsp/audio/bsp_audio.hpp"
#include <Audio/AudioDevice.hpp>

#include "fsl_sai_edma.h"

namespace bsp
namespace audio
{

    class SAIAudioDevice : public bsp::AudioDevice
    class SAIAudioDevice : public AudioDevice
    {
      public:
        SAIAudioDevice(I2S_Type *base, sai_edma_handle_t *rxHandle, sai_edma_handle_t *txHandle);


@@ 34,4 34,4 @@ namespace bsp
        static constexpr Capabilities saiCapabilities = {.usesDMA = true};
    };

} // namespace bsp
} // namespace audio

D module-audio/targets/Target_Cross.cmake => module-audio/targets/Target_Cross.cmake +0 -9
@@ 1,9 0,0 @@
set(BOARD_SOURCES

        CACHE INTERNAL ""
        )

set(BOARD_DIR_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/board/cross CACHE INTERNAL "")




D module-audio/targets/Target_Linux.cmake => module-audio/targets/Target_Linux.cmake +0 -3
@@ 1,3 0,0 @@
set(BOARD_SOURCES  CACHE INTERNAL "")

set(BOARD_DIR_INCLUDES  ${CMAKE_CURRENT_SOURCE_DIR}/board/linux CACHE INTERNAL "")

M module-bluetooth/Bluetooth/interface/profiles/Profile.hpp => module-bluetooth/Bluetooth/interface/profiles/Profile.hpp +4 -4
@@ 1,4 1,4 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 12,13 12,13 @@ namespace bluetooth
    class Profile
    {
      public:
        virtual ~Profile()                           = default;
        virtual ~Profile()                                                   = default;
        virtual auto init() -> Error::Code                                   = 0;
        virtual void setDeviceAddress(uint8_t *addr) = 0;
        virtual void setDeviceAddress(uint8_t *addr)                         = 0;
        virtual void setOwnerService(const sys::Service *service)            = 0;
        virtual auto getStreamData() -> std::shared_ptr<BluetoothStreamData> = 0;
        virtual void connect()                                               = 0;
        virtual void disconnect()                                            = 0;
    };

} // namespace Bt
} // namespace bluetooth

M module-bsp/CMakeLists.txt => module-bsp/CMakeLists.txt +4 -2
@@ 1,11 1,13 @@
cmake_minimum_required(VERSION 3.12)
# Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
# For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

cmake_minimum_required(VERSION 3.12)

project(module-bsp VERSION 1.0
        DESCRIPTION "VFS module library")

set(SOURCES
        "${CMAKE_CURRENT_SOURCE_DIR}/bsp/cellular/bsp_cellular.cpp"
		"${CMAKE_CURRENT_SOURCE_DIR}/bsp/audio/bsp_audio.cpp"
        "${CMAKE_CURRENT_SOURCE_DIR}/bsp/lpm/bsp_lpm.cpp"
        "${CMAKE_CURRENT_SOURCE_DIR}/drivers/pll/DriverPLL.cpp"
        "${CMAKE_CURRENT_SOURCE_DIR}/drivers/dmamux/DriverDMAMux.cpp"

M module-bsp/board/rt1051/bsp/audio/CodecMAX98090.cpp => module-bsp/board/rt1051/bsp/audio/CodecMAX98090.cpp +30 -30
@@ 79,7 79,7 @@ CodecRetCode CodecMAX98090::Start(const CodecParams &param)
    i2c->Write(i2cAddr, (uint8_t *)&q_dai_setup, 1);

    // OUT configuration
    if (params.outputPath != bsp::AudioDevice::OutputPath::None) {
    if (params.outputPath != CodecParamsMAX98090::OutputPath::None) {

        // Control HP performance
        max98090_reg_dachp_perfmode_t dacperf = {0};


@@ 90,7 90,7 @@ CodecRetCode CodecMAX98090::Start(const CodecParams &param)

        switch (params.outputPath) {

        case bsp::AudioDevice::OutputPath::HeadphonesMono: {
        case CodecParamsMAX98090::OutputPath::HeadphonesMono: {
            max98090_reg_playback_quick_setup_t q_playback_setup = {0};
            q_playback_setup.dig2hp                              = 1;
            i2cAddr.subAddress                                   = MAX98090_REG_PLAYBACK_QUICK_SETUP;


@@ 99,12 99,12 @@ CodecRetCode CodecMAX98090::Start(const CodecParams &param)
            // Mix left DAC channel to left&right HP output
            max98090_reg_lhp_mixer_t lmixconf = {0};
            lmixconf.mixhpl                   = 1;
            i2cAddr.subAddress = MAX98090_REG_LHP_MIXER_CONF;
            i2cAddr.subAddress                = MAX98090_REG_LHP_MIXER_CONF;
            i2c->Write(i2cAddr, (uint8_t *)&lmixconf, 1);

            max98090_reg_rhp_mixer_t rmixconf = {0};
            rmixconf.mixhpr                   = 1;
            i2cAddr.subAddress = MAX98090_REG_RHP_MIXER_CONF;
            i2cAddr.subAddress                = MAX98090_REG_RHP_MIXER_CONF;
            i2c->Write(i2cAddr, (uint8_t *)&rmixconf, 1);

            // Use mixer outputs instead of direct DAC outputs


@@ 116,25 116,25 @@ CodecRetCode CodecMAX98090::Start(const CodecParams &param)

        } break;

        case bsp::AudioDevice::OutputPath::Headphones: {
        case CodecParamsMAX98090::OutputPath::Headphones: {
            max98090_reg_playback_quick_setup_t q_playback_setup = {0};
            q_playback_setup.dig2hp                              = 1;
            i2cAddr.subAddress = MAX98090_REG_PLAYBACK_QUICK_SETUP;
            i2cAddr.subAddress                                   = MAX98090_REG_PLAYBACK_QUICK_SETUP;
            i2c->Write(i2cAddr, (uint8_t *)&q_playback_setup, 1);

        } break;

        case bsp::AudioDevice::OutputPath::Earspeaker: {
        case CodecParamsMAX98090::OutputPath::Earspeaker: {
            max98090_reg_playback_quick_setup_t q_playback_setup = {0};
            q_playback_setup.dig2ear = 1;
            i2cAddr.subAddress       = MAX98090_REG_PLAYBACK_QUICK_SETUP;
            q_playback_setup.dig2ear                             = 1;
            i2cAddr.subAddress                                   = MAX98090_REG_PLAYBACK_QUICK_SETUP;
            i2c->Write(i2cAddr, (uint8_t *)&q_playback_setup, 1);

        } break;

        case bsp::AudioDevice::OutputPath::Loudspeaker: {
        case CodecParamsMAX98090::OutputPath::Loudspeaker: {
            max98090_reg_playback_quick_setup_t q_playback_setup = {0};
            q_playback_setup.dig2spk = 1;
            q_playback_setup.dig2spk                             = 1;
            i2cAddr.subAddress                                   = MAX98090_REG_PLAYBACK_QUICK_SETUP;
            i2c->Write(i2cAddr, (uint8_t *)&q_playback_setup, 1);



@@ 151,10 151,10 @@ CodecRetCode CodecMAX98090::Start(const CodecParams &param)

        } break;

        case bsp::AudioDevice::OutputPath::LoudspeakerMono: {
        case CodecParamsMAX98090::OutputPath::LoudspeakerMono: {
            max98090_reg_playback_quick_setup_t q_playback_setup = {0};
            q_playback_setup.dig2spk                             = 1;
            i2cAddr.subAddress = MAX98090_REG_PLAYBACK_QUICK_SETUP;
            i2cAddr.subAddress                                   = MAX98090_REG_PLAYBACK_QUICK_SETUP;
            i2c->Write(i2cAddr, (uint8_t *)&q_playback_setup, 1);

            // Turn off right speaker path


@@ 172,18 172,18 @@ CodecRetCode CodecMAX98090::Start(const CodecParams &param)
    }

    // IN configuration
    if (params.inputPath != bsp::AudioDevice::InputPath::None) {
    if (params.inputPath != CodecParamsMAX98090::InputPath::None) {
        // Set input path
        switch (params.inputPath) {

        case bsp::AudioDevice::InputPath::Headphones: {
        case CodecParamsMAX98090::InputPath::Headphones: {
            max98090_reg_input_to_record_quick_t q_input_setup = {0};
            q_input_setup.in34dan                              = 1;
            i2cAddr.subAddress                                 = MAX98090_REG_LINE_INPUT_TO_RECORD_QUICK;
            i2c->Write(i2cAddr, (uint8_t *)&q_input_setup, 1);
        } break;

        case bsp::AudioDevice::InputPath::Microphone: {
        case CodecParamsMAX98090::InputPath::Microphone: {
            max98090_reg_input_to_record_quick_t q_input_setup = {0};
            max98090_reg_digmic_enable_t digena                = {0};
            max98090_reg_digmic_conf_t digconf                 = {0};


@@ 334,8 334,8 @@ CodecRetCode CodecMAX98090::SetOutputVolume(const float vol)
    }

    switch (currentParams.outputPath) {
    case bsp::AudioDevice::OutputPath::Headphones:
    case bsp::AudioDevice::OutputPath::HeadphonesMono: {
    case CodecParamsMAX98090::OutputPath::Headphones:
    case CodecParamsMAX98090::OutputPath::HeadphonesMono: {
        // Scale input volume(range 0 - 100) to MAX98090 range(decibels hardcoded as specific hex values)
        constexpr float scale_factor     = .31f * 10.f;
        uint8_t volume                   = static_cast<float>(vol * scale_factor);


@@ 354,7 354,7 @@ CodecRetCode CodecMAX98090::SetOutputVolume(const float vol)

    } break;

    case bsp::AudioDevice::OutputPath::Earspeaker: {
    case CodecParamsMAX98090::OutputPath::Earspeaker: {
        // Scale input volume(range 0 - 100) to MAX98090 range(decibels hardcoded as specific hex values)
        constexpr float scale_factor     = .31f * 10.f;
        uint8_t volume                   = static_cast<float>(vol * scale_factor);


@@ 367,8 367,8 @@ CodecRetCode CodecMAX98090::SetOutputVolume(const float vol)
        i2c->Write(i2cAddr, (uint8_t *)&vol, 1);
    } break;

    case bsp::AudioDevice::OutputPath::Loudspeaker:
    case bsp::AudioDevice::OutputPath::LoudspeakerMono: {
    case CodecParamsMAX98090::OutputPath::Loudspeaker:
    case CodecParamsMAX98090::OutputPath::LoudspeakerMono: {
        // Scale input volume(range 0 - 100) to MAX98090 range(decibels hardcoded as specific hex values)
        constexpr float scale_factor = .39f * 10.f;
        uint8_t volume               = static_cast<float>(vol * scale_factor) + 0x18;


@@ 406,16 406,16 @@ CodecRetCode CodecMAX98090::SetInputGain(const float gain)
    }

    max98090_reg_lrec_dig_gain_t lgain = {0};
    lgain.avl = static_cast<uint8_t>(CodecParamsMAX98090::RecordPathDigitalFineGain::Gain_p3dB); // fine gain
    lgain.avlg                         = gainToSet * 0.7; // coarse gain (0.7 used as scaling factor)
    lgain.avl  = static_cast<uint8_t>(CodecParamsMAX98090::RecordPathDigitalFineGain::Gain_p3dB); // fine gain
    lgain.avlg = gainToSet * 0.7; // coarse gain (0.7 used as scaling factor)

    i2cAddr.subAddress = MAX98090_REG_LREC_DIG_GAIN;
    i2c->Write(i2cAddr, (uint8_t *)&lgain, 1);

    // coarse gain - 18dB, fine gain - 0dB
    max98090_reg_rrec_dig_gain_t rgain = {0};
    rgain.avr = static_cast<uint8_t>(CodecParamsMAX98090::RecordPathDigitalFineGain::Gain_p3dB); // fine gain
    rgain.avrg                         = gainToSet * 0.7; // coarse gain (0.7 used as scaling factor)
    rgain.avr  = static_cast<uint8_t>(CodecParamsMAX98090::RecordPathDigitalFineGain::Gain_p3dB); // fine gain
    rgain.avrg = gainToSet * 0.7; // coarse gain (0.7 used as scaling factor)

    i2cAddr.subAddress = MAX98090_REG_RREC_DIG_GAIN;
    i2c->Write(i2cAddr, (uint8_t *)&rgain, 1);


@@ 566,7 566,7 @@ CodecRetCode CodecMAX98090::Reset()
    return CodecRetCode::Success;
}

CodecRetCode CodecMAX98090::SetOutputPath(const bsp::AudioDevice::OutputPath path)
CodecRetCode CodecMAX98090::SetOutputPath(const CodecParamsMAX98090::OutputPath path)
{
    Reset();
    currentParams.outputPath = path;


@@ 575,7 575,7 @@ CodecRetCode CodecMAX98090::SetOutputPath(const bsp::AudioDevice::OutputPath pat
    return CodecRetCode::Success;
}

CodecRetCode CodecMAX98090::SetInputPath(const bsp::AudioDevice::InputPath path)
CodecRetCode CodecMAX98090::SetInputPath(const CodecParamsMAX98090::InputPath path)
{
    Reset();
    currentParams.inputPath = path;


@@ 591,17 591,17 @@ CodecRetCode CodecMAX98090::SetMute(const bool enable)
    uint8_t regl, regr = 0;

    switch (currentParams.outputPath) {
    case bsp::AudioDevice::OutputPath::Headphones: {
    case CodecParamsMAX98090::OutputPath::Headphones: {
        regl = MAX98090_REG_LHP_VOL_CTRL;
        regr = MAX98090_REG_RHP_VOL_CTRL;
    } break;

    case bsp::AudioDevice::OutputPath::Earspeaker: {
    case CodecParamsMAX98090::OutputPath::Earspeaker: {
        regl = MAX98090_REG_RECV_VOL_CTRL;
        regr = 0;
    } break;

    case bsp::AudioDevice::OutputPath::Loudspeaker: {
    case CodecParamsMAX98090::OutputPath::Loudspeaker: {
        regl = MAX98090_REG_LSPK_VOL_CTRL;
        regr = MAX98090_REG_RSPK_VOL_CTRL;
    } break;

M module-bsp/board/rt1051/bsp/audio/CodecMAX98090.hpp => module-bsp/board/rt1051/bsp/audio/CodecMAX98090.hpp +21 -5
@@ 6,7 6,6 @@

#include "Codec.hpp"
#include "drivers/i2c/DriverI2C.hpp"
#include "bsp/audio/bsp_audio.hpp"

class CodecParamsMAX98090 : public CodecParams
{


@@ 67,6 66,23 @@ class CodecParamsMAX98090 : public CodecParams
        Gain_n12dB
    };

    enum class InputPath
    {
        Headphones,
        Microphone,
        None
    };

    enum class OutputPath
    {
        Headphones,
        HeadphonesMono,
        Earspeaker,
        Loudspeaker,
        LoudspeakerMono,
        None
    };

    static SampleRate ValToSampleRate(uint32_t rate)
    {
        switch (rate) {


@@ 113,8 129,8 @@ class CodecParamsMAX98090 : public CodecParams
    bool muteEnable       = false;
    bool resetEnable      = false;
    bool micBiasEnable    = false;
    bsp::AudioDevice::InputPath inputPath   = bsp::AudioDevice::InputPath::None;
    bsp::AudioDevice::OutputPath outputPath = bsp::AudioDevice::OutputPath::None;
    InputPath inputPath   = InputPath::None;
    OutputPath outputPath = OutputPath::None;
    SampleRate sampleRate = SampleRate ::Rate44K1Hz;
};



@@ 144,8 160,8 @@ class CodecMAX98090 : public Codec
    CodecRetCode SetOutputVolume(const float vol);
    CodecRetCode SetInputGain(const float gain);
    CodecRetCode SetMute(const bool enable);
    CodecRetCode SetInputPath(const bsp::AudioDevice::InputPath path);
    CodecRetCode SetOutputPath(const bsp::AudioDevice::OutputPath path);
    CodecRetCode SetInputPath(const CodecParamsMAX98090::InputPath path);
    CodecRetCode SetOutputPath(const CodecParamsMAX98090::OutputPath path);
    CodecRetCode MicBias(const bool enable);
    CodecRetCode SetupEarspeakerEqualizer();
    CodecRetCode SetupLoudspeakerEqualizer();

A module-bsp/board/rt1051/common/audio.cpp => module-bsp/board/rt1051/common/audio.cpp +74 -0
@@ 0,0 1,74 @@
// Copyright (c) 2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "audio.hpp"

#include "BoardDefinitions.hpp"

extern "C"
{
#include "board.h"
#include "dma_config.h"
}

using namespace bsp;
using namespace drivers;

bsp::AudioConfig audioConfig;

void bsp::audioInit()
{
    audioConfig.pllAudio =
        DriverPLL::Create(static_cast<PLLInstances>(BoardDefinitions ::AUDIO_PLL), DriverPLLParams{});
    audioConfig.dmamux =
        DriverDMAMux::Create(static_cast<DMAMuxInstances>(BoardDefinitions ::AUDIOCODEC_DMAMUX), DriverDMAMuxParams{});
    audioConfig.dma =
        DriverDMA::Create(static_cast<DMAInstances>(BoardDefinitions ::AUDIOCODEC_DMA), DriverDMAParams{});

    // Enable MCLK clock
    IOMUXC_GPR->GPR1 |= BOARD_AUDIOCODEC_SAIx_MCLK_MASK;

    audioConfig.txDMAHandle =
        audioConfig.dma->CreateHandle(static_cast<uint32_t>(BoardDefinitions ::AUDIOCODEC_TX_DMA_CHANNEL));
    audioConfig.rxDMAHandle =
        audioConfig.dma->CreateHandle(static_cast<uint32_t>(BoardDefinitions ::AUDIOCODEC_RX_DMA_CHANNEL));
    audioConfig.dmamux->Enable(static_cast<uint32_t>(BoardDefinitions ::AUDIOCODEC_TX_DMA_CHANNEL),
                               BSP_AUDIOCODEC_SAIx_DMA_TX_SOURCE);
    audioConfig.dmamux->Enable(static_cast<uint32_t>(BoardDefinitions ::AUDIOCODEC_RX_DMA_CHANNEL),
                               BSP_AUDIOCODEC_SAIx_DMA_RX_SOURCE);

    audioConfig.mclkSourceClockHz = GetPerphSourceClock(PerphClock_SAI2);

    // Initialize SAI Tx module
    SAI_TxGetDefaultConfig(&audioConfig.config);
    audioConfig.config.masterSlave = kSAI_Slave;
    SAI_TxInit(BOARD_AUDIOCODEC_SAIx, &audioConfig.config);

    // Initialize SAI Rx module
    SAI_RxGetDefaultConfig(&audioConfig.config);

    audioConfig.config.masterSlave = kSAI_Slave;
    SAI_RxInit(BOARD_AUDIOCODEC_SAIx, &audioConfig.config);
}

void bsp::audioDeinit()
{
    memset(&audioConfig.config, 0, sizeof(audioConfig.config));
    SAI_Deinit(BOARD_AUDIOCODEC_SAIx);
    if (audioConfig.dmamux) {
        audioConfig.dmamux->Disable(static_cast<uint32_t>(BoardDefinitions ::AUDIOCODEC_TX_DMA_CHANNEL));
        audioConfig.dmamux->Disable(static_cast<uint32_t>(BoardDefinitions ::AUDIOCODEC_RX_DMA_CHANNEL));
    }

    // force order of destruction
    audioConfig.txDMAHandle.reset();
    audioConfig.rxDMAHandle.reset();
    audioConfig.dma.reset();
    audioConfig.dmamux.reset();
    audioConfig.pllAudio.reset();
}

AudioConfig *bsp::AudioConfig::get()
{
    return &audioConfig;
}

A module-bsp/board/rt1051/common/audio.hpp => module-bsp/board/rt1051/common/audio.hpp +32 -0
@@ 0,0 1,32 @@
// Copyright (c) 2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include "drivers/pll/DriverPLL.hpp"
#include "drivers/dmamux/DriverDMAMux.hpp"
#include "drivers/dma/DriverDMA.hpp"

#include "fsl_sai_edma.h"

#include <memory>

namespace bsp
{
    void audioInit();
    void audioDeinit();

    struct AudioConfig
    {
        sai_config_t config;
        std::uint32_t mclkSourceClockHz;

        std::shared_ptr<drivers::DriverPLL> pllAudio;
        std::shared_ptr<drivers::DriverDMAMux> dmamux;
        std::shared_ptr<drivers::DriverDMA> dma;
        std::unique_ptr<drivers::DriverDMAHandle> rxDMAHandle;
        std::unique_ptr<drivers::DriverDMAHandle> txDMAHandle;

        static AudioConfig *get();
    };
}; // namespace bsp

M module-bsp/board/rt1051/common/board.cpp => module-bsp/board/rt1051/common/board.cpp +2 -2
@@ 10,9 10,9 @@ extern "C"
#include "fsl_lpuart.h"
#endif
}
#include "audio.hpp"
#include "chip.hpp"
#include "irq/irq_gpio.hpp"
#include "audio/RT1051Audiocodec.hpp"

#include <cstdint>



@@ 193,7 193,7 @@ namespace bsp
        DCDC_BootIntoDCM(DCDC);

        // init audio
        RT1051Audiocodec::Init();
        audioInit();

        PrintSystemClocks();
        clearAndPrintBootReason();

D module-bsp/bsp/audio/bsp_audio.cpp => module-bsp/bsp/audio/bsp_audio.cpp +0 -52
@@ 1,52 0,0 @@
#include "bsp_audio.hpp"

#if defined(TARGET_RT1051)

#include "board/rt1051/bsp/audio/RT1051Audiocodec.hpp"
#include "board/rt1051/bsp/audio/RT1051CellularAudio.hpp"

#endif

#include <Audio/Stream.hpp>

#include <cassert>

namespace bsp
{

    std::optional<std::unique_ptr<AudioDevice>> AudioDevice::Create(bsp::AudioDevice::Type type)
    {
        std::unique_ptr<AudioDevice> inst;

        switch (type) {

        case Type ::Audiocodec: {
#if defined(TARGET_RT1051)
            inst = std::make_unique<bsp::RT1051Audiocodec>();
#else
            inst = nullptr;
#endif

        } break;

        case Type ::Bluetooth: {
            LOG_FATAL("Bluetooth audio is not yet supported");
            inst = nullptr;
        } break;

        case Type::Cellular: {
#if defined(TARGET_RT1051)
            inst = std::make_unique<bsp::RT1051CellularAudio>();
#else
            inst = nullptr;
#endif
        } break;
        }

        if (inst->isInitialized) {
            return inst;
        }

        return {};
    }
} // namespace bsp

M module-bsp/targets/Target_RT1051.cmake => module-bsp/targets/Target_RT1051.cmake +4 -3
@@ 1,3 1,6 @@
# Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
# For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

include(board/rt1051/bsp/usb/usb.cmake)

set(BOARD_SOURCES ${BOARD_SOURCES}


@@ 31,6 34,7 @@ set(BOARD_SOURCES ${BOARD_SOURCES}
	"${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/common/fsl_drivers/fsl_wdog.c"
	"${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/common/fsl_drivers/fsl_pwm.c"
	"${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/common/irq/irq_gpio.cpp"
	"${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/common/audio.cpp"
	"${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/common/board.cpp"
	"${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/common/chip.cpp"
	"${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/common/clock_config.cpp"


@@ 57,9 61,6 @@ set(BOARD_SOURCES ${BOARD_SOURCES}
	"${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/bluetooth/BlueKitchen.cpp"
	"${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/bsp/rtc/rtc.cpp"
	"${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/bsp/battery-charger/battery_charger.cpp"
	"${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/bsp/audio/RT1051Audiocodec.cpp"
	"${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/bsp/audio/RT1051CellularAudio.cpp"
	"${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/bsp/audio/SAIAudioDevice.cpp"
	"${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/bsp/audio/CodecMAX98090.cpp"
	"${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/bsp/audio/qfilter.c"
	"${USB_SRC}"

M module-services/service-audio/ServiceAudio.cpp => module-services/service-audio/ServiceAudio.cpp +1 -24
@@ 121,29 121,6 @@ std::optional<std::string> ServiceAudio::AudioServicesCallback(const sys::Messag
        }
        return settings_it->second;
    }
    else if (const auto *btReq = dynamic_cast<const BluetoothProxyMessage *>(msg); btReq) {
        std::shared_ptr<BluetoothProxyMessage> request;
        if (const auto *btStart = dynamic_cast<const BluetoothProxyStartMessage *>(msg); btStart) {
            request = std::make_shared<BluetoothProxyStartMessage>(*btStart);
        }
        else if (const auto *btVolume = dynamic_cast<const BluetoothProxySetVolumeMessage *>(msg); btVolume) {
            request = std::make_shared<BluetoothProxySetVolumeMessage>(*btVolume);
        }
        else if (const auto *btGain = dynamic_cast<const BluetoothProxySetGainMessage *>(msg); btGain) {
            request = std::make_shared<BluetoothProxySetGainMessage>(*btGain);
        }
        else if (const auto *btOutPath = dynamic_cast<const BluetoothProxySetOutputPathMessage *>(msg); btOutPath) {
            request = std::make_shared<BluetoothProxySetOutputPathMessage>(*btOutPath);
        }
        else if (const auto *btInPath = dynamic_cast<const BluetoothProxySetInputPathMessage *>(msg); btInPath) {
            request = std::make_shared<BluetoothProxySetInputPathMessage>(*btInPath);
        }
        else {
            LOG_DEBUG("BluetoothProxyMessage not supported.");
            return std::nullopt;
        }
        bus.sendUnicast(request, service::name::bluetooth);
    }
    else {
        LOG_DEBUG("Message received but not handled - no effect.");
    }


@@ 383,7 360,7 @@ std::unique_ptr<AudioResponseMessage> ServiceAudio::HandleStop(const std::vector
        for (auto &input : audioMux.GetAllInputs()) {
            const auto &currentOperation = input.audio->GetCurrentOperation();
            if (std::find(stopTypes.begin(), stopTypes.end(), currentOperation.GetPlaybackType()) != stopTypes.end()) {
                muted = true;
                muted  = true;
                auto t = input.token;
                retCodes.emplace_back(t, stopInput(&input));
            }

M module-services/service-bluetooth/service-bluetooth/BluetoothMessage.hpp => module-services/service-bluetooth/service-bluetooth/BluetoothMessage.hpp +0 -69
@@ 9,7 9,6 @@
#include <Service/Message.hpp>
#include <Audio/Stream.hpp>
#include <MessageType.hpp>
#include <bsp_audio.hpp>

#include <utility>
#include <vector>


@@ 121,71 120,3 @@ class BluetoothRequestStreamResultMessage : public sys::DataMessage
  private:
    std::shared_ptr<BluetoothStreamData> data;
};

class BluetoothProxyMessage : public sys::DataMessage
{
  public:
    BluetoothProxyMessage(MessageType messageType, bsp::AudioDevice::Format format)
        : DataMessage(messageType), format(format){};

    ~BluetoothProxyMessage() override = default;

    bsp::AudioDevice::Format format;
};

/// Bluetooth proxy messages

class BluetoothProxyStartMessage : public BluetoothProxyMessage
{
  public:
    BluetoothProxyStartMessage(audio::Stream &streamOut, audio::Stream &streamIn, bsp::AudioDevice::Format format)
        : BluetoothProxyMessage(MessageType::BluetoothProxyStart, format), audioStreamOut(streamOut),
          audioStreamIn(streamIn){};

    ~BluetoothProxyStartMessage() override = default;

    audio::Stream &audioStreamOut;
    audio::Stream &audioStreamIn;
};

class BluetoothProxyStopMessage : public BluetoothProxyMessage
{
  public:
    BluetoothProxyStopMessage(bsp::AudioDevice::Format format)
        : BluetoothProxyMessage(MessageType::BluetoothProxyStop, format){};
    ~BluetoothProxyStopMessage() override = default;
};

class BluetoothProxySetVolumeMessage : public BluetoothProxyMessage
{
  public:
    BluetoothProxySetVolumeMessage(bsp::AudioDevice::Format format)
        : BluetoothProxyMessage(MessageType::BluetoothProxyOutputVolumeCtrl, format){};
    ~BluetoothProxySetVolumeMessage() override = default;
};

class BluetoothProxySetGainMessage : public BluetoothProxyMessage
{
  public:
    BluetoothProxySetGainMessage(bsp::AudioDevice::Format format)
        : BluetoothProxyMessage(MessageType::BluetoothProxyInputGainCtrl, format){};
    ~BluetoothProxySetGainMessage() override = default;

    float value;
};

class BluetoothProxySetOutputPathMessage : public BluetoothProxyMessage
{
  public:
    BluetoothProxySetOutputPathMessage(bsp::AudioDevice::Format format)
        : BluetoothProxyMessage(MessageType::BluetoothProxyOutputPathCtrl, format){};
    ~BluetoothProxySetOutputPathMessage() override = default;
};

class BluetoothProxySetInputPathMessage : public BluetoothProxyMessage
{
  public:
    BluetoothProxySetInputPathMessage(bsp::AudioDevice::Format format)
        : BluetoothProxyMessage(MessageType::BluetoothProxyInputPathCtrl, format){};
    ~BluetoothProxySetInputPathMessage() override = default;
};