/*
   HARK Library
   Copyright (C) 2021 Honda Research Institute Japan Inc.
 */

#if !defined(_HARKLIB_NODE_AUDIO_STREAM_FROM_MEMORY_H_INCLUDED_)
#define _HARKLIB_NODE_AUDIO_STREAM_FROM_MEMORY_H_INCLUDED_ 1

#include "hark-lib/hark-lib.h"
#include "hark-lib/node.h"
#include "hark-lib/internal/thread.h"
#include "hark-lib/internal/mutex.h"
#include "hark-lib/internal/condition_variable.h"

#include <iostream>

namespace hark
{
namespace node
{
    class AudioStreamFromMemory: public NodeDef
    {
    public:
        AudioStreamFromMemory();
        virtual void reset();
        virtual bool operator () (size_t count, InputDataBundle &input, OutputDataBundle &output);

    private:
        void initialize(InputDataBundle &input);

        std::vector<float>::iterator
        convert_bytes_to_float(std::vector<std::istream::char_type>::iterator start,
                               std::vector<std::istream::char_type>::iterator end,
                               std::vector<float>::iterator into,
                               size_t bytes_per_sample);

        size_t unshift_audio(char *dst, size_t count, bool block = true);
        bool eof() const;

        size_t audio_buffer_available() const;

    public:
        size_t push_audio(const char *src, size_t count, bool block = true);
        void close_audio();

    private:
        // int _count;
        int _length, _advance, _channels, _bytes_per_sample, _sampling_rate;
        double _maximum_buffer_length;
        bool _use_wait;

        // size_t _last_input_count;
        // std::vector<unsigned char> _audio_buffer;
        // size_t _audio_buffer_offset;
        // size_t _audio_buffer_count;
        std::deque<unsigned char> _audio_buffer;
        bool _audio_closed;

        std::unique_ptr<Mutex> _mutex;
        std::unique_ptr<ConditionVariable> _condvar;

        std::vector<std::istream::char_type>_buffer;
        std::vector<float>_fbuffer;
    };
}
}

#endif /* #if !defined(_HARKLIB_NODE_AUDIO_STREAM_FROM_MEMORY_H_INCLUDED_) */

/* end of file */
