1 // ****************************************************************************
5 // Implementation file for the CLayla driver class; this is for 20-bit
8 // Set editor tabs to 3 for your viewing pleasure.
10 // ----------------------------------------------------------------------------
12 // This file is part of Echo Digital Audio's generic driver library.
13 // Copyright Echo Digital Audio Corporation (c) 1998 - 2005
14 // All rights reserved
17 // This library is free software; you can redistribute it and/or
18 // modify it under the terms of the GNU Lesser General Public
19 // License as published by the Free Software Foundation; either
20 // version 2.1 of the License, or (at your option) any later version.
22 // This library is distributed in the hope that it will be useful,
23 // but WITHOUT ANY WARRANTY; without even the implied warranty of
24 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 // Lesser General Public License for more details.
27 // You should have received a copy of the GNU Lesser General Public
28 // License along with this library; if not, write to the Free Software
29 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 // ****************************************************************************
35 #define LAYLA20_ANALOG_OUTPUT_LATENCY 57
36 #define LAYLA20_ANALOG_INPUT_LATENCY 64
37 #define LAYLA20_DIGITAL_OUTPUT_LATENCY 32
38 #define LAYLA20_DIGITAL_INPUT_LATENCY 32
41 /****************************************************************************
43 Construction and destruction
45 ****************************************************************************/
47 //===========================================================================
49 // Overload new & delete so memory for this object is allocated
50 // from non-paged memory.
52 //===========================================================================
54 PVOID
CLayla::operator new( size_t Size
)
59 Status
= OsAllocateNonPaged(Size
,&pMemory
);
61 if ( (ECHOSTATUS_OK
!= Status
) || (NULL
== pMemory
))
63 ECHO_DEBUGPRINTF(("CLayla::operator new - memory allocation failed\n"));
69 memset( pMemory
, 0, Size
);
74 } // PVOID CLayla::operator new( size_t Size )
77 VOID
CLayla::operator delete( PVOID pVoid
)
79 if ( ECHOSTATUS_OK
!= OsFreeNonPaged( pVoid
) )
81 ECHO_DEBUGPRINTF( ("CLayla::operator delete memory free failed\n") );
83 } // VOID CLayla::operator delete( PVOID pVoid )
86 //===========================================================================
88 // Constructor and destructor
90 //===========================================================================
92 CLayla::CLayla( PCOsSupport pOsSupport
)
93 : CEchoGalsMTC( pOsSupport
)
95 ECHO_DEBUGPRINTF( ( "CLayla::CLayla() is born!\n" ) );
97 m_wAnalogOutputLatency
= LAYLA20_ANALOG_OUTPUT_LATENCY
;
98 m_wAnalogInputLatency
= LAYLA20_ANALOG_INPUT_LATENCY
;
99 m_wDigitalOutputLatency
= LAYLA20_DIGITAL_OUTPUT_LATENCY
;
100 m_wDigitalInputLatency
= LAYLA20_DIGITAL_INPUT_LATENCY
;
102 } // CLayla::CLayla()
107 ECHO_DEBUGPRINTF( ( "CLayla::~CLayla() is toast!\n" ) );
108 } // CLayla::~CLayla()
113 /****************************************************************************
115 Setup and hardware initialization
117 ****************************************************************************/
119 //===========================================================================
121 // Every card has an InitHw method
123 //===========================================================================
125 ECHOSTATUS
CLayla::InitHw()
131 // Call the base method
133 if ( ECHOSTATUS_OK
!= ( Status
= CEchoGals::InitHw() ) )
137 // Create the DSP comm object
139 ECHO_ASSERT(NULL
== m_pDspCommObject
);
140 m_pDspCommObject
= new CLaylaDspCommObject( (PDWORD
) m_pvSharedMemory
,
142 if (NULL
== m_pDspCommObject
)
144 ECHO_DEBUGPRINTF(("CLayla::InitHw - could not create DSP comm object\n"));
145 return ECHOSTATUS_NO_MEM
;
149 // Load the DSP and the external box ASIC
151 GetDspCommObject()->LoadFirmware();
152 if ( GetDspCommObject()->IsBoardBad() )
153 return ECHOSTATUS_DSP_DEAD
;
156 // Clear the "bad board" flag; set the flag to indicate that
157 // Darla24 can handle super-interleave.
159 m_wFlags
&= ~ECHOGALS_FLAG_BADBOARD
;
160 m_wFlags
|= ECHOGALS_ROFLAG_SUPER_INTERLEAVE_OK
;
163 // Must call this here after DSP is init to
164 // init gains and mutes
166 Status
= InitLineLevels();
167 if ( ECHOSTATUS_OK
!= Status
)
171 // Initialize the MIDI input
173 Status
= m_MidiIn
.Init( this );
174 if ( ECHOSTATUS_OK
!= Status
)
177 ECHO_DEBUGPRINTF(("\tMIDI input init done\n"));
180 // Set defaults for +4/-10
182 for (i
= 0; i
< GetFirstDigitalBusOut(); i
++ )
184 ECHO_DEBUGPRINTF(("\tSetting nominal output level %d\n",i
));
185 GetDspCommObject()->SetNominalLevel( i
, TRUE
); // TRUE is -10 here
187 for ( i
= 0; i
< GetFirstDigitalBusIn(); i
++ )
189 ECHO_DEBUGPRINTF(("\tSetting nominal input level %d\n",i
));
190 GetDspCommObject()->SetNominalLevel( GetNumBussesOut() + i
, TRUE
);
193 ECHO_DEBUGPRINTF(("\tNominal levels done\n"));
196 // Set the S/PDIF output format to "professional"
198 SetProfessionalSpdif( TRUE
);
199 ECHO_DEBUGPRINTF(("\tSet S/PDIF format OK\n"));
202 // Get default sample rate from DSP
204 m_dwSampleRate
= GetDspCommObject()->GetSampleRate();
205 ECHO_DEBUGPRINTF( ( "\tCLayla::InitHw() finished\n" ) );
209 } // ECHOSTATUS CLayla::InitHw()
214 /****************************************************************************
216 Informational methods
218 ****************************************************************************/
220 //===========================================================================
222 // Override GetCapabilities to enumerate unique capabilties for Layla20
224 //===========================================================================
226 ECHOSTATUS
CLayla::GetCapabilities
228 PECHOGALS_CAPS pCapabilities
234 Status
= GetBaseCapabilities(pCapabilities
);
237 // Add input gain and nominal level to input busses
239 for (i
= 0; i
< GetFirstDigitalBusIn(); i
++)
241 pCapabilities
->dwBusInCaps
[i
] |= ECHOCAPS_GAIN
|
243 ECHOCAPS_NOMINAL_LEVEL
;
247 // Add nominal levels to output busses
249 for (i
= 0; i
< GetFirstDigitalBusOut(); i
++)
251 pCapabilities
->dwBusOutCaps
[i
] |= ECHOCAPS_NOMINAL_LEVEL
;
254 if ( ECHOSTATUS_OK
!= Status
)
257 pCapabilities
->dwInClockTypes
|= ECHO_CLOCK_BIT_WORD
|
258 ECHO_CLOCK_BIT_SUPER
|
259 ECHO_CLOCK_BIT_SPDIF
|
262 pCapabilities
->dwOutClockTypes
|= ECHO_CLOCK_BIT_WORD
|
263 ECHO_CLOCK_BIT_SUPER
;
267 } // ECHOSTATUS CLayla::GetCapabilities
270 //===========================================================================
272 // QueryAudioSampleRate is used to find out if this card can handle a
273 // given sample rate.
275 //===========================================================================
277 ECHOSTATUS
CLayla::QueryAudioSampleRate
282 if ( dwSampleRate
< 8000 ||
283 dwSampleRate
> 50000 )
286 ("CLayla::QueryAudioSampleRate() - rate %ld invalid\n",dwSampleRate
) );
287 return ECHOSTATUS_BAD_FORMAT
;
289 ECHO_DEBUGPRINTF( ( "CLayla::QueryAudioSampleRate() %ld Hz OK\n",
291 return ECHOSTATUS_OK
;
293 } // ECHOSTATUS CLayla::QueryAudioSampleRate
296 void CLayla::QuerySampleRateRange(DWORD
&dwMinRate
,DWORD
&dwMaxRate
)
303 //===========================================================================
305 // GetInputClockDetect returns a bitmask consisting of all the input
306 // clocks currently connected to the hardware; this changes as the user
307 // connects and disconnects clock inputs.
309 // You should use this information to determine which clocks the user is
310 // allowed to select.
312 // Layla20 supports S/PDIF clock, word clock, and super clock.
314 //===========================================================================
316 ECHOSTATUS
CLayla::GetInputClockDetect(DWORD
&dwClockDetectBits
)
318 if ( NULL
== GetDspCommObject() || GetDspCommObject()->IsBoardBad() )
320 ECHO_DEBUGPRINTF( ("CLayla::GetInputClockDetect: DSP Dead!\n") );
321 return ECHOSTATUS_DSP_DEAD
;
324 DWORD dwClocksFromDsp
= GetDspCommObject()->GetInputClockDetect();
326 dwClockDetectBits
= ECHO_CLOCK_BIT_INTERNAL
| ECHO_CLOCK_BIT_MTC
;
328 if (0 != (dwClocksFromDsp
& GLDM_CLOCK_DETECT_BIT_SPDIF
))
329 dwClockDetectBits
|= ECHO_CLOCK_BIT_SPDIF
;
331 if (0 != (dwClocksFromDsp
& GLDM_CLOCK_DETECT_BIT_WORD
))
333 if (0 != (dwClocksFromDsp
& GLDM_CLOCK_DETECT_BIT_SUPER
))
334 dwClockDetectBits
|= ECHO_CLOCK_BIT_SUPER
;
336 dwClockDetectBits
|= ECHO_CLOCK_BIT_WORD
;
339 return ECHOSTATUS_OK
;
341 } // GetInputClockDetect
344 // *** CLayla.cpp ***