///////////////////////////////////////////////////////////////////////////////
// Copyright (c) Winnov L.P., 1997.  All rights reserved
// codec.c: codec class implementation.
//
// Modified : C++ -> C
///////////////////////////////////////////////////////////////////////////////

#include "common.h"
#include "io.h"
#include "codec.h"    

#undef PUBLIC
#undef PRIVATE
#define PUBLIC
#define PRIVATE static

PUBLIC void codecConstructor (PCODEC pCodec, PSHARED pShared, UINT nBoard, PHAL pHal)
{
    pCodec->m_nBoard = nBoard;
    pCodec->m_pShared = pShared;
    pCodec->m_pHal = pHal;
}

PUBLIC void codecDestructor (PCODEC pCodec)
{
}     


PUBLIC UINT codecInstanceSize(PCODEC pCodec)
{
	return sizeof(CODEC);
}


/////////////////////////////////////////////////////////////////////////////
// the mute control of the ASCO is used for multiple purposes.
// This routine makes the decision on how it should be set.
//
// Truth Table:
//
// MuteSpeaker	MuteWaveOut	MuteIn		0Gain    WOActive	ASCO Mute
//  0		0		0		0	    0		0
//  0		0		0		0	    1		0
//  0		0		0		1	    0		1
//  0		0		0		1	    1		0
//  0		0		1		0	    0		1
//  0		0		1		0	    1		0
//  0		0		1		1	    0		1
//  0		0		1		1	    1		0
//  0		1		0		0	    0		0
//  0		1		0		0	    1		1
//  0		1		0		1	    0		1
//  0		1		0		1	    1		1
//  0		1		1		0	    0		1
//  0		1		1		0	    1		1
//  0		1		1		1	    0		1
//  0		1		1		1	    1		1
//  1		X		X		X	    X		1

PUBLIC void codecUpdateMute (PCODEC pCodec)
{
    UINT nVal;
    BOOL fZeroGain;

    nVal = halReadGainReg (pCodec->m_pHal);	// read mut bit and gain values
    if (nVal & (HW_GAINLFFIELD | HW_GAINRTFIELD))
	fZeroGain = FALSE;
    else
	fZeroGain = TRUE;

    if ((!sharedGetMuteIn (pCodec->m_pShared) && fZeroGain && !sharedGetWaveOutState (pCodec->m_pShared))
     || ( sharedGetMuteIn (pCodec->m_pShared) && !sharedGetWaveOutState (pCodec->m_pShared))
     || ( sharedGetWaveOutState (pCodec->m_pShared) && sharedGetWaveOutMute (pCodec->m_pShared))
     || sharedGetSpeakerMute (pCodec->m_pShared))
	nVal |= HW_MUTBIT;	// mute ASCO
    else
	nVal &= ~HW_MUTBIT;	// unmute ASCO

    halWriteGainReg (pCodec->m_pHal, nVal);
	sharedSetCodecMute (pCodec->m_pShared, (nVal & HW_MUTBIT)?TRUE:FALSE);
}

PUBLIC void codecSetWaveOutState (PCODEC pCodec, BOOL fState)
{
    sharedSetWaveOutState (pCodec->m_pShared, fState);
    codecUpdateMute (pCodec);
}

PUBLIC BOOL codecGetWaveOutState (PCODEC pCodec)
{
    return sharedGetWaveOutState (pCodec->m_pShared);
}

PUBLIC void codecSetMuteIn (PCODEC pCodec, BOOL fMuteIn)
{
    sharedSetMuteIn (pCodec->m_pShared, !!fMuteIn);
    codecUpdateMute (pCodec);
}

PUBLIC BOOL codecGetMuteIn (PCODEC pCodec)
{
    return sharedGetMuteIn (pCodec->m_pShared);
}

PUBLIC void codecSetSpeakerMute (PCODEC pCodec, BOOL fMute)
{
    sharedSetSpeakerMute (pCodec->m_pShared, fMute);
    codecUpdateMute (pCodec);
}

PUBLIC BOOL codecGetSpeakerMute (PCODEC pCodec)
{
    return sharedGetSpeakerMute (pCodec->m_pShared);
}

PUBLIC void codecSetWaveOutMute (PCODEC pCodec, BOOL fMute)
{
    sharedSetWaveOutMute (pCodec->m_pShared, fMute);	// this is redundant
    codecUpdateMute (pCodec);
}

PUBLIC BOOL codecGetWaveOutMute (PCODEC pCodec)
{
    return sharedGetWaveOutMute (pCodec->m_pShared);
}

PUBLIC void codecSetRightGain (PCODEC pCodec, UINT nGain)
{
    halSetRightGain (pCodec->m_pHal, nGain);    
    codecUpdateMute (pCodec);
}

PUBLIC UINT codecGetRightGain (PCODEC pCodec)
{
    return halGetRightGain (pCodec->m_pHal);    
}

PUBLIC void codecSetLeftGain (PCODEC pCodec, UINT nGain)
{
    halSetLeftGain (pCodec->m_pHal, nGain);
    codecUpdateMute (pCodec);
}

PUBLIC UINT codecGetLeftGain (PCODEC pCodec)
{
    return halGetLeftGain (pCodec->m_pHal);
}

PUBLIC void codecSetRightAttenuation (PCODEC pCodec, UINT nAtten)
{
    halSetRightAttenuation (pCodec->m_pHal, nAtten);
}

PUBLIC void codecSetLeftAttenuation (PCODEC pCodec, UINT nAtten)
{
    halSetLeftAttenuation (pCodec->m_pHal, nAtten);
}

///////////////////////////////////////////////////////////////////////////////
////////////////////////////// End of File ////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
