/*
 * Copyright (C) 2020-2021 Aloysius Indrayanto
 *
 * This file is part of the eCxx library, see LICENSE file for the license details.
 */


#ifndef ECXX_PLATFORM_NODEMCU_I2SOUT_H
#define ECXX_PLATFORM_NODEMCU_I2SOUT_H


namespace eCxx {


//
// Forward declaration of the Application class
//
class Application;


//
// A simple NodeMCU I2S output wrapper
//
class I2SOut : public Uncopyable {
    public:
        using TxCallbackF = eCxx::VoidCallback;

    public:
        ~I2SOut();

        // NOTE : The I2S callback function must be in IRAM (declared using ICACHE_RAM_ATTR)
        bool begin(uint32_t rateHz, TxCallbackF callback, uint16_t bufferLength32 = 0, bool enableBitClock = false, bool enableWordSelect = false);
        void end();

        bool resetFinishedBuffer(bool enabled = true, uint32_t value = 0x00000000);

        void pause();
        void resume();

        bool isFull();
        bool isEmpty();
        uint16_t available();

        bool writeSample(uint32_t sample, bool nonBlocking = false);
        bool writeSampleLR(int16_t left, int16_t right);

        uint16_t writeBufferMono(int16_t* frames, uint16_t frameCount, bool nonBlocking = false);
        uint16_t writeBufferStereo(int16_t* frames, uint16_t frameCount, bool nonBlocking = false);

    private:
        I2SOut();

        friend class Application;

    private:
        TxCallbackF _callback;

        static void ICACHE_RAM_ATTR i2s_isr(void* arg) __ECXX_ATTR_OPTIMIZE_2;
};


} // namespace eCxx


#endif
