#include "CEchoGals.h"
#include "CLaylaDspCommObject.h"
#include "Layla20DSP.c"
#include "LaylaASIC.c"
#define LAYLA_ASIC_SIZE 32385
Construction and destruction
****************************************************************************/
CLaylaDspCommObject::CLaylaDspCommObject
(
PDWORD pdwRegBase,
PCOsSupport pOsSupport
) : CDspCommObject( pdwRegBase, pOsSupport )
{
strcpy( m_szCardName, "Layla" );
m_pdwDspRegBase = pdwRegBase;
m_wNumPipesOut = 12;
m_wNumPipesIn = 10;
m_wNumBussesOut = 12;
m_wNumBussesIn = 10;
m_wFirstDigitalBusOut = 10;
m_wFirstDigitalBusIn = 8;
m_fHasVmixer = FALSE;
m_wNumMidiOut = 1;
m_wNumMidiIn = 1;
m_bHasASIC = TRUE;
m_pwDspCodeToLoad = pwLayla20DSP;
}
CLaylaDspCommObject::~CLaylaDspCommObject()
{
ECHO_DEBUGPRINTF( ( "CLaylaDspCommObject::~CLaylaDspCommObject() is toast!\n" ) );
}
Hardware setup and config
****************************************************************************/
BOOL CLaylaDspCommObject::LoadASIC()
{
if ( m_bASICLoaded == TRUE )
return TRUE;
if ( !CDspCommObject::LoadASIC( DSP_FNC_LOAD_LAYLA_ASIC,
pbLaylaASIC,
LAYLA_ASIC_SIZE ) )
return FALSE;
return( CheckAsicStatus() );
}
DWORD CLaylaDspCommObject::SetSampleRate( DWORD dwNewSampleRate )
{
if ( GetInputClock() != ECHO_CLOCK_INTERNAL )
{
ECHO_DEBUGPRINTF( ( "SetSampleRate: Cannot set sample rate because "
"Layla clock NOT set to CLK_CLOCKININTERNAL\n" ) );
m_pDspCommPage->dwSampleRate = SWAP( dwNewSampleRate );
return GetSampleRate();
}
if ( ( dwNewSampleRate < 8000 ) ||
( dwNewSampleRate > 50000 ) )
{
ECHO_DEBUGPRINTF( ( "SetSampleRate: Layla sample rate %ld out of range, "
"no change made\n",
dwNewSampleRate) );
return 0xffffffff;
}
if ( !WaitForHandshake() )
return 0xffffffff;
m_pDspCommPage->dwSampleRate = SWAP( dwNewSampleRate );
ClearHandshake();
SendVector( DSP_VC_SET_LAYLA_SAMPLE_RATE );
ECHO_DEBUGPRINTF( ( "SetSampleRate: Layla sample rate changed to %ld\n",
dwNewSampleRate ) );
return( dwNewSampleRate );
}
ECHOSTATUS CLaylaDspCommObject::SetInputClock(WORD wClock)
{
BOOL bSetRate;
WORD wNewClock;
ECHO_DEBUGPRINTF( ( "CLaylaDspCommObject::SetInputClock:\n" ) );
bSetRate = FALSE;
switch ( wClock )
{
case ECHO_CLOCK_INTERNAL :
ECHO_DEBUGPRINTF( ( "\tSet Layla24 clock to INTERNAL\n" ) );
if ( ( GetSampleRate() < 8000 ) ||
( GetSampleRate() > 50000 ) )
{
m_pDspCommPage->dwSampleRate = SWAP( (DWORD) 48000 );
}
bSetRate = TRUE;
wNewClock = LAYLA20_CLOCK_INTERNAL;
break;
case ECHO_CLOCK_SPDIF:
ECHO_DEBUGPRINTF( ( "\tSet Layla20 clock to SPDIF\n" ) );
wNewClock = LAYLA20_CLOCK_SPDIF;
break;
case ECHO_CLOCK_WORD:
ECHO_DEBUGPRINTF( ( "\tSet Layla20 clock to WORD\n" ) );
wNewClock = LAYLA20_CLOCK_WORD;
break;
case ECHO_CLOCK_SUPER:
ECHO_DEBUGPRINTF( ( "\tSet Layla20 clock to SUPER\n" ) );
wNewClock = LAYLA20_CLOCK_SUPER;
break;
default :
ECHO_DEBUGPRINTF(("Input clock 0x%x not supported for Layla24\n",wClock));
ECHO_DEBUGBREAK();
return ECHOSTATUS_CLOCK_NOT_SUPPORTED;
}
m_wInputClock = wClock;
m_pDspCommPage->wInputClock = SWAP(wNewClock);
ClearHandshake();
SendVector( DSP_VC_UPDATE_CLOCKS );
if ( bSetRate )
SetSampleRate();
return ECHOSTATUS_OK;
}
ECHOSTATUS CLaylaDspCommObject::SetOutputClock(WORD wClock)
{
WORD wLaylaOutClock;
if (FALSE == m_bASICLoaded)
return ECHOSTATUS_ASIC_NOT_LOADED;
if (!WaitForHandshake())
return ECHOSTATUS_DSP_DEAD;
ECHO_DEBUGPRINTF( ("CDspCommObject::SetOutputClock:\n") );
switch (wClock)
{
case ECHO_CLOCK_SUPER :
wLaylaOutClock = LAYLA20_OUTPUT_CLOCK_SUPER;
break;
case ECHO_CLOCK_WORD :
wLaylaOutClock = LAYLA20_OUTPUT_CLOCK_WORD;
break;
default :
return ECHOSTATUS_INVALID_PARAM;
}
m_pDspCommPage->wOutputClock = SWAP(wLaylaOutClock);
m_wOutputClock = wClock;
ClearHandshake();
ECHOSTATUS Status = SendVector(DSP_VC_UPDATE_CLOCKS);
return Status;
}
ECHOSTATUS CLaylaDspCommObject::SetBusInGain( WORD wBusIn, INT32 iGain)
{
ECHO_DEBUGPRINTF(("CLaylaDspCommObject::SetBusInGain\n"));
if (wBusIn >= LAYLA20_INPUT_TRIMS)
return ECHOSTATUS_INVALID_CHANNEL;
m_byInputTrims[wBusIn] = (BYTE) iGain;
BYTE byMinus10;
GetNominalLevel( wBusIn + m_wNumBussesOut, &byMinus10);
if (0 == byMinus10)
{
iGain -= 12 << 1;
}
return CDspCommObject::SetBusInGain(wBusIn,iGain);
}
ECHOSTATUS CLaylaDspCommObject::GetBusInGain( WORD wBusIn, INT32 &iGain)
{
if (wBusIn >= LAYLA20_INPUT_TRIMS)
return ECHOSTATUS_INVALID_CHANNEL;
iGain = (INT32) m_byInputTrims[wBusIn];
return ECHOSTATUS_OK;
}
ECHOSTATUS CLaylaDspCommObject::SetNominalLevel
(
WORD wBus,
BOOL bState
)
{
ECHO_DEBUGPRINTF(("CLaylaDspCommObject::SetNominalLevel\n"));
if (wBus < m_wNumBussesOut)
{
return CDspCommObject::SetNominalLevel(wBus,bState);
}
ECHO_DEBUGPRINTF(("\tChecking the bus number\n"));
if (wBus < (m_wNumBussesOut + LAYLA20_INPUT_TRIMS))
{
ECHO_DEBUGPRINTF(("\twBus %d m_pDspCommPage %p\n",wBus,m_pDspCommPage));
if ( bState )
m_pDspCommPage->cmdNominalLevel.SetIndexInMask( wBus );
else
m_pDspCommPage->cmdNominalLevel.ClearIndexInMask( wBus );
ECHO_DEBUGPRINTF(("\tCalling SetBusInGain\n"));
wBus = wBus - m_wNumBussesOut;
return SetBusInGain( wBus, (INT32) m_byInputTrims[wBus]);
}
ECHO_DEBUGPRINTF( ("CLaylaDspCommObject::SetNominalOutLineLevel Invalid "
"index %d\n",
wBus ) );
return ECHOSTATUS_INVALID_CHANNEL;
}
BOOL CLaylaDspCommObject::CheckAsicStatus()
{
DWORD dwNumTests;
DWORD dwNumWins;
BOOL bLoaded;
dwNumTests = NUM_ASIC_ATTEMPTS;
dwNumWins = 0;
do
{
bLoaded = CDspCommObject::CheckAsicStatus();
if (FALSE != bLoaded)
{
dwNumWins++;
if (NUM_ASIC_WINS == dwNumWins)
{
m_bASICLoaded = TRUE;
break;
}
}
m_bASICLoaded = FALSE;
dwNumTests--;
} while (dwNumTests != 0);
return m_bASICLoaded;
}