~aleteoryx/muditaos

ref: 7d7003d62639426be8eb00f4fc288b68139f5566 muditaos/module-bsp/bsp/audio/bsp_audio.hpp -rwxr-xr-x 4.4 KiB
7d7003d6 — Marcin Smoczyński Merge branch 'master' into stable 5 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#pragma once

#include <Audio/Endpoint.hpp>

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

namespace bsp
{

    class AudioDevice : public audio::IOProxy
    {

      public:
        enum class RetCode
        {
            Success = 0,
            Failure
        };

        enum class Type
        {
            None,
            Audiocodec,
            Cellular,
            Bluetooth
        };

        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 */
            uint32_t bitWidth      = 0; /*!< Data length of audio data, usually 8/16/24/32 bits */
            uint32_t flags         = 0; /*!< In/Out configuration flags */
            float outputVolume     = 0.0f;
            float inputGain        = 0.0f;
            InputPath inputPath    = InputPath::None;
            OutputPath outputPath  = OutputPath::None;
        };

        /**
         * User defined callback.
         * It will be invoked when opened stream needs more frames to process( outputBuffer will be != NULL) or if
         * requested frames count are available to user( inputBuffer will be != NULL). From this callback you can safely
         * use file operations, system calls etc This is because audiostream callbacks are not invoked from IRQ context.
         *
         * If there is more data to process or read user should return:
         *  'AudiostreamCallbackContinue'
         *  if there is no more data to process or read user should return:
         *  'AudiostreamCallbackComplete'
         *  this will close stream and clean up all internally allocated resources.
         *  In case of error return:
         *  'AudiostreamCallbackAbort'
         *  this has the same effect as AudiostreamCallbackComplete.
         *
         * @param stream[in] - pointer to valid stream
         * @param inputBuffer[in] - pointer to buffer where user should copy PCM data
         * @param outputBuffer[out] - pointer to buffer containing valid PCM data
         * @param framesPerBuffer[in] - how many frames user should copy or read from buffer
         * @param userData[in] - user specified data
         * @return audiostream_callback_err_t
         */
        using audioCallback_t =
            std::function<int32_t(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer)>;

        explicit AudioDevice(audioCallback_t callback) : callback(callback)
        {}

        AudioDevice() = delete;

        virtual ~AudioDevice() = default;

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

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

        virtual RetCode OutputVolumeCtrl(float vol)           = 0;
        virtual RetCode InputGainCtrl(float gain)             = 0;
        virtual RetCode OutputPathCtrl(OutputPath outputPath) = 0;
        virtual RetCode InputPathCtrl(InputPath inputPath)    = 0;
        virtual bool IsFormatSupported(const Format &format)  = 0;

        float GetOutputVolume() const noexcept
        {
            return currentFormat.outputVolume;
        }

        float GetInputGain() const noexcept
        {
            return currentFormat.inputGain;
        }

        OutputPath GetOutputPath() const noexcept
        {
            return currentFormat.outputPath;
        }

        InputPath GetInputPath() const noexcept
        {
            return currentFormat.inputPath;
        }

        Format GetCurrentFormat() const noexcept
        {
            return currentFormat;
        }

        audioCallback_t GetAudioCallback()
        {
            return callback;
        }

      protected:
        Format currentFormat;
        audioCallback_t callback = nullptr;

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