#ifndef AVIFILE_AUDIOQUEUE_H
#define AVIFILE_AUDIOQUEUE_H

#include <default.h>
#include <formats.h>
#include <Locker.h>

class IAudioResampler;
class IAudioCleaner;

class IAudioMix
{
public:
    virtual void Mix(void* data, const void* src, size_t n) const = 0;
};

class AudioQueue
{
public:
    AudioQueue(WAVEFORMATEX& Iwf, WAVEFORMATEX& Owf);
    ~AudioQueue();
    void Clear();
    double GetBufferTime() const { return GetSize() / (double) m_uiBytesPerSec; }
    unsigned int GetBytesPerSec() const { return m_uiBytesPerSec; }
    int Push(const void* data, size_t count);
    int Read(void* data, size_t count, const IAudioMix* amix = 0);
    size_t Resample(void* dest, const void* src, size_t src_size);
    unsigned int GetSize() const { return m_uiFrameSize; }
    int Write(int fd);
    int Unread(size_t count);

    int Broadcast();
    int Wait() { return m_Cond.Wait(m_Mutex); }
    int Lock() { return m_Mutex.Lock(); }
    int Unlock() { return m_Mutex.Unlock(); }
protected:
    static const float BUFFER_TIME = 1.5; // buffer 1.5 seconds
    PthreadCond m_Cond;      	// Broadcast to notify audio_thread about
				// new available data OR about quit=1

    PthreadMutex m_Mutex;	// Controls access to audio buffer
    bool m_bCleared;            // cleared buffers
    unsigned int m_uiFrameMax;  // Max allowed frame_size
    unsigned int m_uiFrameSize;	// Current amount of data
    unsigned int m_uiFrameIn;
    unsigned int m_uiFrameOut;	// Input and output positions in queue
    unsigned int m_uiBytesPerSec; // Input and output positions in queue
    unsigned char* m_pcAudioFrame; // Audio queue
    double m_dRemains;          // Remainder for resampling
    IAudioResampler* m_pResampler;
    IAudioCleaner* m_pCleaner;
    WAVEFORMATEX m_Owf;		// format of data we get from audio stream
    WAVEFORMATEX m_Iwf;		// format of data we write to audio_fd
};

#endif // AVIFILE_AUDIOQUEUE_H
