1 // ****************************************************************************
2 //
3 // CGina24.cpp
4 //
5 // Implementation file for the CGina24 driver class.
6 // Set editor tabs to 3 for your viewing pleasure.
7 //
8 // ----------------------------------------------------------------------------
9 //
10 // This file is part of Echo Digital Audio's generic driver library.
11 // Copyright Echo Digital Audio Corporation (c) 1998 - 2005
12 // All rights reserved
13 // www.echoaudio.com
14 //
15 // This library is free software; you can redistribute it and/or
16 // modify it under the terms of the GNU Lesser General Public
17 // License as published by the Free Software Foundation; either
18 // version 2.1 of the License, or (at your option) any later version.
19 //
20 // This library is distributed in the hope that it will be useful,
21 // but WITHOUT ANY WARRANTY; without even the implied warranty of
22 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 // Lesser General Public License for more details.
24 //
25 // You should have received a copy of the GNU Lesser General Public
26 // License along with this library; if not, write to the Free Software
27 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 //
29 // ****************************************************************************
30
31 #include "CGina24.h"
32
33 #define GINA24_ANALOG_OUTPUT_LATENCY 59
34 #define GINA24_ANALOG_INPUT_LATENCY 71
35 #define GINA24_DIGITAL_OUTPUT_LATENCY 32
36 #define GINA24_DIGITAL_INPUT_LATENCY 32
37
38
39
40 /****************************************************************************
41
42 Construction and destruction
43
44 ****************************************************************************/
45
46 //===========================================================================
47 //
48 // Overload new & delete so memory for this object is allocated
49 // from non-paged memory.
50 //
51 //===========================================================================
52
operator new(size_t Size)53 PVOID CGina24::operator new( size_t Size )
54 {
55 PVOID pMemory;
56 ECHOSTATUS Status;
57
58 Status = OsAllocateNonPaged(Size,&pMemory);
59
60 if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory ))
61 {
62 ECHO_DEBUGPRINTF(("CGina::operator new - memory allocation failed\n"));
63
64 pMemory = NULL;
65 }
66 else
67 {
68 memset( pMemory, 0, Size );
69 }
70
71 return pMemory;
72
73 } // PVOID CGina24::operator new( size_t Size )
74
75
operator delete(PVOID pVoid)76 VOID CGina24::operator delete( PVOID pVoid )
77 {
78 if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) )
79 {
80 ECHO_DEBUGPRINTF(("CGina24::operator delete memory free failed\n"));
81 }
82 } // VOID CGina24::operator delete( PVOID pVoid )
83
84
85 //===========================================================================
86 //
87 // Constructor and destructor
88 //
89 //===========================================================================
90
CGina24(PCOsSupport pOsSupport)91 CGina24::CGina24( PCOsSupport pOsSupport )
92 : CEchoGals( pOsSupport )
93 {
94 ECHO_DEBUGPRINTF( ( "CGina24::CGina24() is born!\n" ) );
95
96 m_wAnalogOutputLatency = GINA24_ANALOG_OUTPUT_LATENCY;
97 m_wAnalogInputLatency = GINA24_ANALOG_INPUT_LATENCY;
98 m_wDigitalOutputLatency = GINA24_DIGITAL_OUTPUT_LATENCY;
99 m_wDigitalInputLatency = GINA24_DIGITAL_INPUT_LATENCY;
100
101 }
102
~CGina24()103 CGina24::~CGina24()
104 {
105 ECHO_DEBUGPRINTF( ( "CGina24::~CGina24() is toast!\n" ) );
106 }
107
108
109
110
111 /****************************************************************************
112
113 Setup and hardware initialization
114
115 ****************************************************************************/
116
117 //===========================================================================
118 //
119 // Every card has an InitHw method
120 //
121 //===========================================================================
122
InitHw()123 ECHOSTATUS CGina24::InitHw()
124 {
125 ECHOSTATUS Status;
126
127 //
128 // Call the base method
129 //
130 if ( ECHOSTATUS_OK != ( Status = CEchoGals::InitHw() ) )
131 return Status;
132
133 //
134 // Create the DSP comm object
135 //
136 ECHO_ASSERT(NULL == m_pDspCommObject );
137 m_pDspCommObject = new CGina24DspCommObject( (PDWORD) m_pvSharedMemory,
138 m_pOsSupport );
139 if (NULL == m_pDspCommObject)
140 {
141 ECHO_DEBUGPRINTF(("CGina24::InitHw - could not create DSP comm object\n"));
142 return ECHOSTATUS_NO_MEM;
143 }
144
145 ECHO_ASSERT(GetDspCommObject() );
146
147 //
148 // Load the DSP and the ASIC on the PCI card
149 //
150 GetDspCommObject()->LoadFirmware();
151 if ( GetDspCommObject()->IsBoardBad() )
152 return ECHOSTATUS_DSP_DEAD;
153
154 //
155 // Clear the "bad board" flag; set the flags to indicate that
156 // Gina24 can handle super-interleave and supports the digital
157 // input auto-mute.
158 //
159 m_wFlags &= ~ECHOGALS_FLAG_BADBOARD;
160 m_wFlags |= ECHOGALS_ROFLAG_SUPER_INTERLEAVE_OK |
161 ECHOGALS_ROFLAG_DIGITAL_IN_AUTOMUTE;
162
163 //
164 // Must call this here after DSP is init to
165 // init gains and mutes
166 //
167 Status = InitLineLevels();
168 if ( ECHOSTATUS_OK != Status )
169 return Status;
170
171 //
172 // Set defaults for +4/-10
173 //
174 WORD i;
175 for (i = 0; i < GetFirstDigitalBusOut(); i++ )
176 {
177 Status = GetDspCommObject()->
178 SetNominalLevel( i, FALSE ); // FALSE is +4 here
179 }
180 for ( i = 0; i < GetFirstDigitalBusIn(); i++ )
181 {
182 Status = GetDspCommObject()->
183 SetNominalLevel( GetNumBussesOut() + i, FALSE );
184 }
185
186 //
187 // Set the digital mode to S/PDIF RCA
188 //
189 SetDigitalMode( DIGITAL_MODE_SPDIF_RCA );
190
191 //
192 // Set the S/PDIF output format to "professional"
193 //
194 SetProfessionalSpdif( TRUE );
195
196 //
197 // Get default sample rate from DSP
198 //
199 m_dwSampleRate = GetDspCommObject()->GetSampleRate();
200
201 ECHO_DEBUGPRINTF( ( "CGina24::InitHw()\n" ) );
202 return Status;
203
204 } // ECHOSTATUS CGina24::InitHw()
205
206
207
208
209 /****************************************************************************
210
211 Informational methods
212
213 ****************************************************************************/
214
215 //===========================================================================
216 //
217 // Override GetCapabilities to enumerate unique capabilties for Gina24
218 //
219 //===========================================================================
220
GetCapabilities(PECHOGALS_CAPS pCapabilities)221 ECHOSTATUS CGina24::GetCapabilities
222 (
223 PECHOGALS_CAPS pCapabilities
224 )
225 {
226 ECHOSTATUS Status;
227
228 Status = GetBaseCapabilities(pCapabilities);
229
230 //
231 // Add nominal level control to analog ins & outs
232 //
233 WORD i;
234 for (i = 0 ; i < GetFirstDigitalBusOut(); i++)
235 {
236 pCapabilities->dwBusOutCaps[i] |= ECHOCAPS_NOMINAL_LEVEL;
237 }
238
239 for (i = 0 ; i < GetFirstDigitalBusIn(); i++)
240 {
241 pCapabilities->dwBusInCaps[i] |= ECHOCAPS_NOMINAL_LEVEL;
242 }
243
244 if ( ECHOSTATUS_OK != Status )
245 return Status;
246
247 pCapabilities->dwInClockTypes |=
248 ECHO_CLOCK_BIT_SPDIF |
249 ECHO_CLOCK_BIT_ESYNC |
250 ECHO_CLOCK_BIT_ESYNC96 |
251 ECHO_CLOCK_BIT_ADAT;
252
253 return Status;
254 } // ECHOSTATUS CGina24::GetCapabilities
255
256
257 //===========================================================================
258 //
259 // QueryAudioSampleRate is used to find out if this card can handle a
260 // given sample rate.
261 //
262 //===========================================================================
263
QueryAudioSampleRate(DWORD dwSampleRate)264 ECHOSTATUS CGina24::QueryAudioSampleRate
265 (
266 DWORD dwSampleRate
267 )
268 {
269 if ( dwSampleRate != 8000 &&
270 dwSampleRate != 11025 &&
271 dwSampleRate != 16000 &&
272 dwSampleRate != 22050 &&
273 dwSampleRate != 32000 &&
274 dwSampleRate != 44100 &&
275 dwSampleRate != 48000 &&
276 dwSampleRate != 88200 &&
277 dwSampleRate != 96000 )
278 {
279 ECHO_DEBUGPRINTF(
280 ("CGina24::QueryAudioSampleRate() - rate %ld invalid\n",dwSampleRate) );
281 return ECHOSTATUS_BAD_FORMAT;
282 }
283 if ( dwSampleRate >= 88200 && DIGITAL_MODE_ADAT == GetDigitalMode() )
284 {
285 ECHO_DEBUGPRINTF(
286 ("CGina24::QueryAudioSampleRate() Sample rate cannot be "
287 "set to 88,200 Hz or 96,000 Hz in ADAT mode\n") );
288 return ECHOSTATUS_BAD_FORMAT;
289 }
290
291 ECHO_DEBUGPRINTF( ( "CGina24::QueryAudioSampleRate()\n" ) );
292 return ECHOSTATUS_OK;
293 } // ECHOSTATUS CGina24::QueryAudioSampleRate
294
295
QuerySampleRateRange(DWORD & dwMinRate,DWORD & dwMaxRate)296 void CGina24::QuerySampleRateRange(DWORD &dwMinRate,DWORD &dwMaxRate)
297 {
298 dwMinRate = 8000;
299 dwMaxRate = 96000;
300 }
301
302
303 //===========================================================================
304 //
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.
308 //
309 // You should use this information to determine which clocks the user is
310 // allowed to select.
311 //
312 // Gina24 supports S/PDIF, Esync, and ADAT input clocks.
313 //
314 //===========================================================================
315
GetInputClockDetect(DWORD & dwClockDetectBits)316 ECHOSTATUS CGina24::GetInputClockDetect(DWORD &dwClockDetectBits)
317 {
318 //ECHO_DEBUGPRINTF(("CGina24::GetInputClockDetect\n"));
319
320 if ( NULL == GetDspCommObject() || GetDspCommObject()->IsBoardBad() )
321 {
322 ECHO_DEBUGPRINTF( ("CGina24::GetInputClockDetect: DSP Dead!\n") );
323 return ECHOSTATUS_DSP_DEAD;
324 }
325
326 //
327 // Map the DSP clock detect bits to the generic driver clock detect bits
328 //
329 DWORD dwClocksFromDsp = GetDspCommObject()->GetInputClockDetect();
330
331 dwClockDetectBits = ECHO_CLOCK_BIT_INTERNAL;
332
333 if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_SPDIF))
334 dwClockDetectBits |= ECHO_CLOCK_BIT_SPDIF;
335
336 if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_ADAT))
337 dwClockDetectBits |= ECHO_CLOCK_BIT_ADAT;
338
339 if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_ESYNC))
340 dwClockDetectBits |= ECHO_CLOCK_BIT_ESYNC | ECHO_CLOCK_BIT_ESYNC96;
341
342 return ECHOSTATUS_OK;
343
344 } // GetInputClockDetect
345
346
347 // *** CGina24.cpp ***
348