#include <windows.h>
#include <mmreg.h>
#include <ks.h>
#include <wchar.h>

#include "kbbenchmark_device.h"
#include "kbcomdlg.h"

///////////////////////////////////////////////////////////////////////////////
KbBenchmarkDevice::KbBenchmarkDevice(void)
{
    m_nSampleRate = 0;
    m_nChannels = 0;
    m_nBps = 0;
    m_nBufferSizeSample = 0;
    m_nBlockAlign = 0;
    m_qwCurSample = 0;
    m_liStart.QuadPart = 0;
    QueryPerformanceFrequency(&m_liFreq);
}
///////////////////////////////////////////////////////////////////////////////
KbBenchmarkDevice::~KbBenchmarkDevice(void)
{
    Stop();
}
///////////////////////////////////////////////////////////////////////////////
BOOL WINAPI KbBenchmarkDevice::Output(BYTE *pOutput, int nSizeSample)
{
    if(m_qwCurSample == 0){//計測開始
        QueryPerformanceCounter(&m_liStart);
    }
    m_qwCurSample += nSizeSample;
    return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
void WINAPI KbBenchmarkDevice::Stop(void)
{
    if(m_qwCurSample > 0){
        LARGE_INTEGER liStop;
        QueryPerformanceCounter(&liStop);
        double dElapsedSec = ((double)(liStop.QuadPart - m_liStart.QuadPart))/m_liFreq.QuadPart;
        double dDecodedSec = ((double)m_qwCurSample / m_nSampleRate);
        double dSecPerSec = dDecodedSec / dElapsedSec;
        wchar_t szMes[2048];
        _snwprintf_s(szMes, _TRUNCATE,
            L"デコードしたサンプル数=%lld(=%lf秒)\r\n"
            L"デコードに要した時間=%lf秒\r\n"
            L"デコード速度=%lf倍"
            , m_qwCurSample, dDecodedSec, dElapsedSec, dSecPerSec);
        m_qwCurSample = 0;
        m_liStart.QuadPart = 0;
        ShowMsgBox(NULL, szMes, L"計測結果", MB_OK|MB_TASKMODAL);
    }
}
///////////////////////////////////////////////////////////////////////////////
void WINAPI KbBenchmarkDevice::Pause(void)
{
}
///////////////////////////////////////////////////////////////////////////////
void WINAPI KbBenchmarkDevice::Restart(void)
{
}
///////////////////////////////////////////////////////////////////////////////
UINT64 WINAPI KbBenchmarkDevice::GetPosition(void)
{//デバイスの再生位置をサンプル単位で返す
    return m_qwCurSample;
}
///////////////////////////////////////////////////////////////////////////////
void WINAPI KbBenchmarkDevice::Wait(void)
{//次の書き込みが可能になるまで待つ
}
///////////////////////////////////////////////////////////////////////////////
BOOL WINAPI KbBenchmarkDevice::SetVolume(int nVolume)
{
    return false;
}
///////////////////////////////////////////////////////////////////////////////
BOOL WINAPI KbBenchmarkDevice::SetRate(int nRate)
{
    return false;
}
///////////////////////////////////////////////////////////////////////////////
BOOL __fastcall KbBenchmarkDevice::Open(IKpiConfig *pConfig,
                                       const wchar_t *cszDeviceName,
                                       const wchar_t  *cszId, 
                                       const KPI_DEVICE_FORMAT *cpFormat,
                                       int nBufferSizeSample)
{
    if(cpFormat->dwChannels != 1 &&
       cpFormat->dwChannels != 2){
        return false;
    }
    if(cpFormat->nBitsPerSample != 8 &&
       cpFormat->nBitsPerSample != 16 &&
       cpFormat->nBitsPerSample != 24 &&
       cpFormat->nBitsPerSample != 32 &&
       cpFormat->nBitsPerSample != -32 &&
       cpFormat->nBitsPerSample != -64){
        return false;
    }
    if(cpFormat->dwFormatType != KPI_MEDIAINFO::FORMAT_PCM){
        return false;
    }

    m_nSampleRate = cpFormat->dwSampleRate;
    m_nChannels = cpFormat->dwChannels;
    m_nBps = cpFormat->nBitsPerSample;
    m_nBufferSizeSample = nBufferSizeSample;
    m_nBlockAlign = (abs(m_nBps)/8) * m_nChannels;
    return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
