#include "CEchoGals.h"
#include "CLayla24DspCommObject.h"
#include LAYLA24_DSP_FILENAME
#include "Layla24_1ASIC.c"
#include "Layla24_2A_ASIC.c"
#include LAYLA24_2ASIC_FILENAME
#define LAYLA24_ASIC_SIZE 31146
Construction and destruction
****************************************************************************/
CLayla24DspCommObject::CLayla24DspCommObject
(
PDWORD pdwRegBase,
PCOsSupport pOsSupport
) : CGMLDspCommObject( pdwRegBase, pOsSupport )
{
strcpy( m_szCardName, LAYLA24_CARD_NAME);
m_pdwDspRegBase = pdwRegBase;
m_wNumPipesOut = 16;
m_wNumPipesIn = 16;
m_wNumBussesOut = 16;
m_wNumBussesIn = 16;
m_wFirstDigitalBusOut = 8;
m_wFirstDigitalBusIn = 8;
m_fHasVmixer = LAYLA24_HAS_VMIXER;
m_wNumMidiOut = 1;
m_wNumMidiIn = 1;
m_bHasASIC = TRUE;
m_pwDspCodeToLoad = LAYLA24_DSP_CODE;
m_byDigitalMode = DIGITAL_MODE_SPDIF_RCA;
m_bProfessionalSpdif = FALSE;
m_wMtcState = MIDI_IN_STATE_NORMAL;
m_dwSampleRate = 48000;
}
CLayla24DspCommObject::~CLayla24DspCommObject()
{
ECHO_DEBUGPRINTF( ( "CLayla24DspCommObject::~CLayla24DspCommObject() "
"is toast!\n" ) );
}
Hardware setup and config
****************************************************************************/
BOOL CLayla24DspCommObject::LoadASIC()
{
DWORD dwControlReg;
if ( m_bASICLoaded == TRUE )
return TRUE;
ECHO_DEBUGPRINTF(("CLayla24DspCommObject::LoadASIC\n"));
m_pOsSupport->OsSnooze( 10000 );
if ( !CDspCommObject::LoadASIC( DSP_FNC_LOAD_LAYLA24_PCI_CARD_ASIC,
pbLayla24_1ASIC,
sizeof( pbLayla24_1ASIC ) ) )
return FALSE;
m_pbyAsic = pbLayla24_2S_ASIC;
m_pOsSupport->OsSnooze( 10000 );
if ( !CDspCommObject::LoadASIC( DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC,
pbLayla24_2S_ASIC,
sizeof( pbLayla24_2S_ASIC ) ) )
return FALSE;
m_pOsSupport->OsSnooze( 10000 );
CheckAsicStatus();
if ( m_bASICLoaded )
{
dwControlReg = GML_CONVERTER_ENABLE | GML_48KHZ;
WriteControlReg( dwControlReg, TRUE );
m_dwSampleRate = 48000;
}
ECHO_DEBUGPRINTF(("\tFinished\n"));
return m_bASICLoaded;
}
DWORD CLayla24DspCommObject::SetSampleRate( DWORD dwNewSampleRate )
{
DWORD dwControlReg, dwNewClock, dwBaseRate;
BOOL bSetFreqReg = FALSE;
if ( GetInputClock() != ECHO_CLOCK_INTERNAL )
{
ECHO_DEBUGPRINTF( ( "CLayla24DspCommObject::SetSampleRate: Cannot set sample rate - "
"clock not set to CLK_CLOCKININTERNAL\n" ) );
m_dwSampleRate = SWAP( dwNewSampleRate );
SetInputClock( m_wInputClock );
return dwNewSampleRate;
}
dwControlReg = GetControlRegister();
dwControlReg &= GML_CLOCK_CLEAR_MASK;
dwControlReg &= GML_SPDIF_RATE_CLEAR_MASK;
bSetFreqReg = FALSE;
switch ( dwNewSampleRate )
{
case 96000 :
dwNewClock = GML_96KHZ;
break;
case 88200 :
dwNewClock = GML_88KHZ;
break;
case 48000 :
dwNewClock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1;
break;
case 44100 :
dwNewClock = GML_44KHZ;
if ( dwControlReg & GML_SPDIF_PRO_MODE )
{
dwNewClock |= GML_SPDIF_SAMPLE_RATE0;
}
break;
case 32000 :
dwNewClock = GML_32KHZ |
GML_SPDIF_SAMPLE_RATE0 |
GML_SPDIF_SAMPLE_RATE1;
break;
case 22050 :
dwNewClock = GML_22KHZ;
break;
case 16000 :
dwNewClock = GML_16KHZ;
break;
case 11025 :
dwNewClock = GML_11KHZ;
break;
case 8000 :
dwNewClock = GML_8KHZ;
break;
default :
bSetFreqReg = TRUE;
dwNewClock = LAYLA24_CONTINUOUS_CLOCK;
}
dwControlReg |= dwNewClock;
if ( bSetFreqReg )
{
if ( dwNewSampleRate > 50000 )
{
dwBaseRate = dwNewSampleRate >> 1;
dwControlReg |= GML_DOUBLE_SPEED_MODE;
}
else
{
dwBaseRate = dwNewSampleRate;
}
if ( dwBaseRate < 25000 )
dwBaseRate = 25000;
if ( !WaitForHandshake() )
return 0xffffffff;
m_pDspCommPage->dwSampleRate =
SWAP( LAYLA24_MAGIC_NUMBER / dwBaseRate - 2 );
ClearHandshake();
SendVector( DSP_VC_SET_LAYLA24_FREQUENCY_REG );
}
if ( ECHOSTATUS_OK == WriteControlReg( dwControlReg ) )
{
m_pDspCommPage->dwSampleRate = SWAP( dwNewSampleRate );
ECHO_DEBUGPRINTF( ("CLayla24DspCommObject::SetSampleRate: %ld "
"clock %lx\n", dwNewSampleRate, dwControlReg) );
}
m_dwSampleRate = dwNewSampleRate;
return dwNewSampleRate;
}
ECHOSTATUS CLayla24DspCommObject::SetDigitalMode
(
BYTE byNewMode
)
{
BOOL AsicOk;
switch ( byNewMode )
{
case DIGITAL_MODE_SPDIF_RCA :
case DIGITAL_MODE_SPDIF_OPTICAL :
AsicOk = SwitchAsic( pbLayla24_2S_ASIC, sizeof( pbLayla24_2S_ASIC ) );
break;
case DIGITAL_MODE_ADAT :
AsicOk = SwitchAsic( pbLayla24_2A_ASIC, sizeof( pbLayla24_2A_ASIC ) );
break;
default :
return ECHOSTATUS_DIGITAL_MODE_NOT_SUPPORTED;
}
if (FALSE == AsicOk)
return ECHOSTATUS_ASIC_NOT_LOADED;
return CGMLDspCommObject::SetDigitalMode(byNewMode);
}
BOOL CLayla24DspCommObject::SwitchAsic
(
BYTE * pbyAsicNeeded,
DWORD dwAsicSize
)
{
BOOL rval;
rval = TRUE;
if ( pbyAsicNeeded != m_pbyAsic )
{
BYTE byMonitors[ MONITOR_ARRAY_SIZE ];
memmove( byMonitors, m_pDspCommPage->byMonitors, MONITOR_ARRAY_SIZE );
memset( m_pDspCommPage->byMonitors,
GENERIC_TO_DSP(ECHOGAIN_MUTED),
MONITOR_ARRAY_SIZE );
rval = CDspCommObject::LoadASIC(DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC,
pbyAsicNeeded,
dwAsicSize );
if (FALSE != rval)
{
m_pbyAsic = pbyAsicNeeded;
}
memmove( m_pDspCommPage->byMonitors, byMonitors, MONITOR_ARRAY_SIZE );
}
return rval;
}
ECHOSTATUS CLayla24DspCommObject::SetInputClock(WORD wClock)
{
BOOL bSetRate;
BOOL bWriteControlReg;
DWORD dwControlReg, dwSampleRate;
ECHO_DEBUGPRINTF( ( "CLayla24DspCommObject::SetInputClock:\n" ) );
dwControlReg = GetControlRegister();
dwControlReg &= GML_CLOCK_CLEAR_MASK;
dwSampleRate = GetSampleRate();
bSetRate = FALSE;
bWriteControlReg = TRUE;
switch ( wClock )
{
case ECHO_CLOCK_INTERNAL :
ECHO_DEBUGPRINTF( ( "\tSet Layla24 clock to INTERNAL\n" ) );
if ( ( GetSampleRate() < 8000 ) ||
( GetSampleRate() > 100000 ) )
{
m_pDspCommPage->dwSampleRate = SWAP( (DWORD) 48000 );
m_dwSampleRate = 48000;
}
bSetRate = TRUE;
bWriteControlReg = FALSE;
break;
case ECHO_CLOCK_SPDIF:
if ( DIGITAL_MODE_ADAT == GetDigitalMode() )
{
return ECHOSTATUS_CLOCK_NOT_AVAILABLE;
}
ECHO_DEBUGPRINTF( ( "\tSet Layla24 clock to SPDIF\n" ) );
dwControlReg |= GML_SPDIF_CLOCK;
Since Layla24 doesn't support 96 kHz S/PDIF, this can be ignored
if ( GML_CLOCK_DETECT_BIT_SPDIF96 & GetInputClockDetect() )
{
dwControlReg |= GML_DOUBLE_SPEED_MODE;
}
else
{
dwControlReg &= ~GML_DOUBLE_SPEED_MODE;
}
*/
dwControlReg &= ~GML_DOUBLE_SPEED_MODE;
ECHO_DEBUGPRINTF( ( "\tSet Layla24 clock to SPDIF\n" ) );
break;
case ECHO_CLOCK_WORD:
dwControlReg |= GML_WORD_CLOCK;
if ( GML_CLOCK_DETECT_BIT_WORD96 & GetInputClockDetect() )
{
dwControlReg |= GML_DOUBLE_SPEED_MODE;
}
else
{
dwControlReg &= ~GML_DOUBLE_SPEED_MODE;
}
ECHO_DEBUGPRINTF( ( "\tSet Layla24 clock to WORD\n" ) );
break;
case ECHO_CLOCK_ADAT :
if ( DIGITAL_MODE_ADAT != GetDigitalMode() )
{
return ECHOSTATUS_CLOCK_NOT_AVAILABLE;
}
dwControlReg |= GML_ADAT_CLOCK;
dwControlReg &= ~GML_DOUBLE_SPEED_MODE;
ECHO_DEBUGPRINTF( ( "\tSet Layla24 clock to ADAT\n" ) );
break;
default :
ECHO_DEBUGPRINTF(("Input clock 0x%x not supported for Layla24\n",wClock));
ECHO_DEBUGBREAK();
return ECHOSTATUS_CLOCK_NOT_SUPPORTED;
}
m_wInputClock = wClock;
if ( bWriteControlReg )
{
WriteControlReg( dwControlReg, TRUE );
}
if ( bSetRate )
SetSampleRate( m_dwSampleRate );
return ECHOSTATUS_OK;
}