// tDtmf.h: CtDtmf

#ifndef TDTMF_H
#define TDTMF_H

#include "twave.h"
#include "dtmf.h"

#ifndef DIM
#define DIM(rg) (sizeof(rg)/sizeof(*rg))
#endif

class CtDtmf : public CtWave
{
public:
    CtDtmf(CtWaveSink* pSink = 0) : CtWave(pSink) {}
    bool SetTone(char cTone);

private:
    bool Load(BYTE* prgDtmf, size_t nSize);
};

inline
bool CtDtmf::SetTone(char cTone)
{
    BYTE*   prgDtmf = 0;
    size_t  nSize = 0;

    switch( cTone )
    {
    case '0': prgDtmf = g_rgDtmf0; nSize = DIM(g_rgDtmf0); break;
    case '1': prgDtmf = g_rgDtmf1; nSize = DIM(g_rgDtmf1); break;
    case '2': prgDtmf = g_rgDtmf2; nSize = DIM(g_rgDtmf2); break;
    case '3': prgDtmf = g_rgDtmf3; nSize = DIM(g_rgDtmf3); break;
    case '4': prgDtmf = g_rgDtmf4; nSize = DIM(g_rgDtmf4); break;
    case '5': prgDtmf = g_rgDtmf5; nSize = DIM(g_rgDtmf5); break;
    case '6': prgDtmf = g_rgDtmf6; nSize = DIM(g_rgDtmf6); break;
    case '7': prgDtmf = g_rgDtmf7; nSize = DIM(g_rgDtmf7); break;
    case '8': prgDtmf = g_rgDtmf8; nSize = DIM(g_rgDtmf8); break;
    case '9': prgDtmf = g_rgDtmf9; nSize = DIM(g_rgDtmf9); break;
    case '#': prgDtmf = g_rgDtmfP; nSize = DIM(g_rgDtmfP); break;
    case '*': prgDtmf = g_rgDtmfS; nSize = DIM(g_rgDtmfS); break;
    case 'A': prgDtmf = g_rgDtmfA; nSize = DIM(g_rgDtmfA); break;
    case 'B': prgDtmf = g_rgDtmfB; nSize = DIM(g_rgDtmfB); break;
    case 'C': prgDtmf = g_rgDtmfC; nSize = DIM(g_rgDtmfC); break;
    case 'D': prgDtmf = g_rgDtmfD; nSize = DIM(g_rgDtmfD); break;
    case 'a': prgDtmf = g_rgDtmfA; nSize = DIM(g_rgDtmfA); break;
    case 'b': prgDtmf = g_rgDtmfB; nSize = DIM(g_rgDtmfB); break;
    case 'c': prgDtmf = g_rgDtmfC; nSize = DIM(g_rgDtmfC); break;
    case 'd': prgDtmf = g_rgDtmfD; nSize = DIM(g_rgDtmfD); break;
    default: return false; break;
    }

    return prgDtmf && Load(prgDtmf, nSize);
}

inline
bool CtDtmf::Load(BYTE* prgDtmf, size_t nSize)
{
    // Make sure we're not open
    Close();

    assert(!m_pFormat);
    assert(!m_nFormatSize);
    assert(!m_pData);
    assert(!m_nRecordedSize);

    WAVEFORMATEX*   pFormat = (WAVEFORMATEX*)(new BYTE[sizeof(WAVEFORMATEX)]);
    long            nFormatSize = sizeof(WAVEFORMATEX);
    if( !pFormat )
    {
        OutputDebugString("new[] -- Out of memory\n");
        return false;
    }

    pFormat->wFormatTag = WAVE_FORMAT_PCM;  // Pulse Code Modulation
    pFormat->nChannels = 1;                 // Mono
    pFormat->nSamplesPerSec = g_nSamplesPerSec; // dtmf.h
    pFormat->wBitsPerSample = g_wBitsPerSample; // dtmf.h

    // PCM required calculations
    assert(pFormat->wFormatTag == WAVE_FORMAT_PCM);
    pFormat->nBlockAlign = pFormat->nChannels * pFormat->wBitsPerSample/8;
    pFormat->nAvgBytesPerSec = pFormat->nSamplesPerSec * pFormat->nBlockAlign;

    // No user data (we're doing PCM)
    pFormat->cbSize = 0;

    // Update the object state
    m_pFormat = pFormat;
    m_nFormatSize = nFormatSize;
    m_nRecordedSize = nSize;
    m_pData = (HPSTR)prgDtmf;

    return true;
}

#endif  // TDTMF_H
