#pragma once

#include "kpi_decoder.h"
#include "kpi_impl.h"
#include "../../kbmpg123/source/mp3info.h"
#include "config.h"
#include "libmad/mad.h" 

class KbMadDecoder : public KbKpiUnknownImpl<IKpiDecoder>
{
private:
    IKpiFile     *m_pFile;
    MP3Info       m_Mp3Info;
    mad_stream    m_stream;
    mad_header    m_header;
    mad_frame     m_frame;
    mad_synth     m_synth;
    union{
        BYTE      m_InputBuf[16384];    //ファイルから読み込んだバッファ
        BYTE      m_Dummy[16384 + 4096];//ファイルの終端まで読み込んだときだけ使用（後ろにダミーデータを入れないと最後のフレームが再生されない）
    };
    DWORD         m_dwInputBufLen;//読み込んだバッファのサイズ
    DWORD         m_dwBlockAlign;
    BOOL          m_bEof;
    KPI_MEDIAINFO m_MediaInfo;
    //ギャップレス再生用
    DWORD         m_dwStartSample;  //先頭(サンプル単位)(デコード結果はここから使用)
    UINT64        m_qwEndSample;    //終端(サンプル単位)(デコード結果はここまで使用)
                                    //(LAME タグの enc_delay/enc_padding 付きの場合のみ有効）
    UINT64        m_qwDecodedSample;//デコード済みサンプル数
    DWORD         m_dwSkipRemain;   //スキップサンプル数残り

    BYTE          m_OutputBuf[1152*2*sizeof(double)];//デコード結果を格納するバッファ
    DWORD         m_dwOutputRemain;       //m_OutputBuf のうち、未処理な部分のサイズ(サンプル単位)
    DWORD         m_dwOutputBufSizeSample;//m_OutputBuf の有効な部分のサイズ
    void __fastcall pack_pcm(unsigned char *data,
                             unsigned int nsamples,
                             mad_fixed_t const *left, 
                             mad_fixed_t const *right);
public:
    DWORD  __fastcall Open(const KPI_MEDIAINFO *cpRequest, IKpiFile *pFile, IKpiFolder *pFolder);
    DWORD  WINAPI Select(DWORD dwNumber,
                         const KPI_MEDIAINFO **ppMediaInfo,
                         IKpiTagInfo *pTagInfo,
                         DWORD dwTagGetFlags);
    DWORD  WINAPI Render(BYTE *pBuffer, DWORD dwSizeSample);
    UINT64 WINAPI Seek(UINT64 qwPosSample, DWORD dwFlag);
    DWORD  WINAPI UpdateConfig(void *pvReserved){return 0;}
    KbMadDecoder(void);
    ~KbMadDecoder(void);
};

