// **************************************************************************** // // CLayla.cpp // // Implementation file for the CLayla driver class; this is for 20-bit // Layla. // // Set editor tabs to 3 for your viewing pleasure. // // ---------------------------------------------------------------------------- // // This file is part of Echo Digital Audio's generic driver library. // Copyright Echo Digital Audio Corporation (c) 1998 - 2005 // All rights reserved // www.echoaudio.com // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // **************************************************************************** #include "CLayla.h" #define LAYLA20_ANALOG_OUTPUT_LATENCY 57 #define LAYLA20_ANALOG_INPUT_LATENCY 64 #define LAYLA20_DIGITAL_OUTPUT_LATENCY 32 #define LAYLA20_DIGITAL_INPUT_LATENCY 32 /**************************************************************************** Construction and destruction ****************************************************************************/ //=========================================================================== // // Overload new & delete so memory for this object is allocated // from non-paged memory. // //=========================================================================== PVOID CLayla::operator new( size_t Size ) { PVOID pMemory; ECHOSTATUS Status; Status = OsAllocateNonPaged(Size,&pMemory); if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory )) { ECHO_DEBUGPRINTF(("CLayla::operator new - memory allocation failed\n")); pMemory = NULL; } else { memset( pMemory, 0, Size ); } return pMemory; } // PVOID CLayla::operator new( size_t Size ) VOID CLayla::operator delete( PVOID pVoid ) { if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) ) { ECHO_DEBUGPRINTF( ("CLayla::operator delete memory free failed\n") ); } } // VOID CLayla::operator delete( PVOID pVoid ) //=========================================================================== // // Constructor and destructor // //=========================================================================== CLayla::CLayla( PCOsSupport pOsSupport ) : CEchoGalsMTC( pOsSupport ) { ECHO_DEBUGPRINTF( ( "CLayla::CLayla() is born!\n" ) ); m_wAnalogOutputLatency = LAYLA20_ANALOG_OUTPUT_LATENCY; m_wAnalogInputLatency = LAYLA20_ANALOG_INPUT_LATENCY; m_wDigitalOutputLatency = LAYLA20_DIGITAL_OUTPUT_LATENCY; m_wDigitalInputLatency = LAYLA20_DIGITAL_INPUT_LATENCY; } // CLayla::CLayla() CLayla::~CLayla() { ECHO_DEBUGPRINTF( ( "CLayla::~CLayla() is toast!\n" ) ); } // CLayla::~CLayla() /**************************************************************************** Setup and hardware initialization ****************************************************************************/ //=========================================================================== // // Every card has an InitHw method // //=========================================================================== ECHOSTATUS CLayla::InitHw() { ECHOSTATUS Status; WORD i; // // Call the base method // if ( ECHOSTATUS_OK != ( Status = CEchoGals::InitHw() ) ) return Status; // // Create the DSP comm object // ECHO_ASSERT(NULL == m_pDspCommObject ); m_pDspCommObject = new CLaylaDspCommObject( (PDWORD) m_pvSharedMemory, m_pOsSupport ); if (NULL == m_pDspCommObject) { ECHO_DEBUGPRINTF(("CLayla::InitHw - could not create DSP comm object\n")); return ECHOSTATUS_NO_MEM; } // // Load the DSP and the external box ASIC // GetDspCommObject()->LoadFirmware(); if ( GetDspCommObject()->IsBoardBad() ) return ECHOSTATUS_DSP_DEAD; // // Clear the "bad board" flag; set the flag to indicate that // Darla24 can handle super-interleave. // m_wFlags &= ~ECHOGALS_FLAG_BADBOARD; m_wFlags |= ECHOGALS_ROFLAG_SUPER_INTERLEAVE_OK; // // Must call this here after DSP is init to // init gains and mutes // Status = InitLineLevels(); if ( ECHOSTATUS_OK != Status ) return Status; // // Initialize the MIDI input // Status = m_MidiIn.Init( this ); if ( ECHOSTATUS_OK != Status ) return Status; ECHO_DEBUGPRINTF(("\tMIDI input init done\n")); // // Set defaults for +4/-10 // for (i = 0; i < GetFirstDigitalBusOut(); i++ ) { ECHO_DEBUGPRINTF(("\tSetting nominal output level %d\n",i)); GetDspCommObject()->SetNominalLevel( i, TRUE ); // TRUE is -10 here } for ( i = 0; i < GetFirstDigitalBusIn(); i++ ) { ECHO_DEBUGPRINTF(("\tSetting nominal input level %d\n",i)); GetDspCommObject()->SetNominalLevel( GetNumBussesOut() + i, TRUE ); } ECHO_DEBUGPRINTF(("\tNominal levels done\n")); // // Set the S/PDIF output format to "professional" // SetProfessionalSpdif( TRUE ); ECHO_DEBUGPRINTF(("\tSet S/PDIF format OK\n")); // // Get default sample rate from DSP // m_dwSampleRate = GetDspCommObject()->GetSampleRate(); ECHO_DEBUGPRINTF( ( "\tCLayla::InitHw() finished\n" ) ); return Status; } // ECHOSTATUS CLayla::InitHw() /**************************************************************************** Informational methods ****************************************************************************/ //=========================================================================== // // Override GetCapabilities to enumerate unique capabilties for Layla20 // //=========================================================================== ECHOSTATUS CLayla::GetCapabilities ( PECHOGALS_CAPS pCapabilities ) { ECHOSTATUS Status; WORD i; Status = GetBaseCapabilities(pCapabilities); // // Add input gain and nominal level to input busses // for (i = 0; i < GetFirstDigitalBusIn(); i++) { pCapabilities->dwBusInCaps[i] |= ECHOCAPS_GAIN | ECHOCAPS_MUTE | ECHOCAPS_NOMINAL_LEVEL; } // // Add nominal levels to output busses // for (i = 0; i < GetFirstDigitalBusOut(); i++) { pCapabilities->dwBusOutCaps[i] |= ECHOCAPS_NOMINAL_LEVEL; } if ( ECHOSTATUS_OK != Status ) return Status; pCapabilities->dwInClockTypes |= ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER | ECHO_CLOCK_BIT_SPDIF | ECHO_CLOCK_BIT_MTC; pCapabilities->dwOutClockTypes |= ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER; return Status; } // ECHOSTATUS CLayla::GetCapabilities //=========================================================================== // // QueryAudioSampleRate is used to find out if this card can handle a // given sample rate. // //=========================================================================== ECHOSTATUS CLayla::QueryAudioSampleRate ( DWORD dwSampleRate ) { if ( dwSampleRate < 8000 || dwSampleRate > 50000 ) { ECHO_DEBUGPRINTF( ("CLayla::QueryAudioSampleRate() - rate %ld invalid\n",dwSampleRate) ); return ECHOSTATUS_BAD_FORMAT; } ECHO_DEBUGPRINTF( ( "CLayla::QueryAudioSampleRate() %ld Hz OK\n", dwSampleRate ) ); return ECHOSTATUS_OK; } // ECHOSTATUS CLayla::QueryAudioSampleRate void CLayla::QuerySampleRateRange(DWORD &dwMinRate,DWORD &dwMaxRate) { dwMinRate = 8000; dwMaxRate = 50000; } //=========================================================================== // // GetInputClockDetect returns a bitmask consisting of all the input // clocks currently connected to the hardware; this changes as the user // connects and disconnects clock inputs. // // You should use this information to determine which clocks the user is // allowed to select. // // Layla20 supports S/PDIF clock, word clock, and super clock. // //=========================================================================== ECHOSTATUS CLayla::GetInputClockDetect(DWORD &dwClockDetectBits) { if ( NULL == GetDspCommObject() || GetDspCommObject()->IsBoardBad() ) { ECHO_DEBUGPRINTF( ("CLayla::GetInputClockDetect: DSP Dead!\n") ); return ECHOSTATUS_DSP_DEAD; } DWORD dwClocksFromDsp = GetDspCommObject()->GetInputClockDetect(); dwClockDetectBits = ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_MTC; if (0 != (dwClocksFromDsp & GLDM_CLOCK_DETECT_BIT_SPDIF)) dwClockDetectBits |= ECHO_CLOCK_BIT_SPDIF; if (0 != (dwClocksFromDsp & GLDM_CLOCK_DETECT_BIT_WORD)) { if (0 != (dwClocksFromDsp & GLDM_CLOCK_DETECT_BIT_SUPER)) dwClockDetectBits |= ECHO_CLOCK_BIT_SUPER; else dwClockDetectBits |= ECHO_CLOCK_BIT_WORD; } return ECHOSTATUS_OK; } // GetInputClockDetect // *** CLayla.cpp ***