#ifndef IDEVICE_DATA_OBSERVER_H
#define IDEVICE_DATA_OBSERVER_H


#include <string>
#include <vector>
#include <queue>
#include <shared_mutex>
#include <memory>
#include <thread>

#include "dubbing_global.h"
#include "mini_audio.h"

#define AUDIO_FRAME_SIZE 1920

namespace DUBBING
{
    struct MiniDeviceInfo
    {
        ma_device_id m_id;
        std::string m_name;
    };

    struct AudioFrameData
    {
        char m_data[AUDIO_FRAME_SIZE * 4];
        int m_dataLen = 0;
    };

    class DUBBING_CLIENT_EXPORT AudioFrameQueue
    {
    public:
        AudioFrameQueue();
        ~AudioFrameQueue();

    public:
        void pushAudioFrame(std::shared_ptr<AudioFrameData> pAudioFrame);
        std::shared_ptr<AudioFrameData> popAudioFrame();
        void clearAudioFrame();

    private:
        std::queue<std::shared_ptr<AudioFrameData>> m_frameList;
        std::mutex m_mutex;
    };

    class DUBBING_CLIENT_EXPORT IDeviceDataObserver
    {
    public:
        IDeviceDataObserver();
        virtual ~IDeviceDataObserver();

        virtual void onCaptureDataEvent(ma_device* pDevice, const void* pInput, ma_uint32 frameCount);
        virtual void onPlaybackDataEvent(ma_device* pDevice, void* pOutput, ma_uint32 frameCount);
        virtual void onLoopbackDataEvent(ma_device* pDevice, const void* pInput, ma_uint32 frameCount);
        virtual void onStopDeviceEvent(ma_device* pDevice);
        virtual void onNotificationDeviceEvent(const ma_device_notification* pNotification);

        virtual void onCaptureDataEvent(ma_device* pDevice, std::shared_ptr<AudioFrameData> audioFramePtr);
        virtual void onPlaybackDataEvent(ma_device* pDevice, std::shared_ptr<AudioFrameData>& audioFramePtr);
        virtual void onLoopbackDataEvent(ma_device* pDevice, std::shared_ptr<AudioFrameData> audioFramePtr);

    };

}

#endif // IDEVICE_DATA_OBSERVER_H
