1 // ****************************************************************************
3 // CGina24DspCommObject.cpp
5 // Implementation file for Gina24 DSP interface class.
7 // ----------------------------------------------------------------------------
9 // This file is part of Echo Digital Audio's generic driver library.
10 // Copyright Echo Digital Audio Corporation (c) 1998 - 2005
11 // All rights reserved
14 // This library is free software; you can redistribute it and/or
15 // modify it under the terms of the GNU Lesser General Public
16 // License as published by the Free Software Foundation; either
17 // version 2.1 of the License, or (at your option) any later version.
19 // This library is distributed in the hope that it will be useful,
20 // but WITHOUT ANY WARRANTY; without even the implied warranty of
21 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 // Lesser General Public License for more details.
24 // You should have received a copy of the GNU Lesser General Public
25 // License along with this library; if not, write to the Free Software
26 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 // ****************************************************************************
30 #include "CEchoGals.h"
31 #include "CGina24DspCommObject.h"
33 #include "Gina24DSP.c"
34 #include "Gina24_361DSP.c"
36 #include "Gina24ASIC.c"
37 #include "Gina24ASIC_361.c"
40 /****************************************************************************
42 Construction and destruction
44 ****************************************************************************/
46 //===========================================================================
50 //===========================================================================
52 CGina24DspCommObject::CGina24DspCommObject
54 PDWORD pdwRegBase
, // Virtual ptr to DSP registers
55 PCOsSupport pOsSupport
56 ) : CGMLDspCommObject( pdwRegBase
, pOsSupport
)
58 strcpy( m_szCardName
, "Gina24" );
59 m_pdwDspRegBase
= pdwRegBase
; // Virtual addr DSP's register base
65 m_wFirstDigitalBusOut
= 8;
66 m_wFirstDigitalBusIn
= 2;
70 m_wNumMidiOut
= 0; // # MIDI out channels
71 m_wNumMidiIn
= 0; // # MIDI in channels
72 m_pDspCommPage
->dwSampleRate
= SWAP( (DWORD
) 44100 );
73 // Need this in cse we start with ESYNC
77 // Gina24 comes in both '301 and '361 flavors; pick the correct one.
79 if ( DEVICE_ID_56361
== m_pOsSupport
->GetDeviceId() )
80 m_pwDspCodeToLoad
= pwGina24_361DSP
;
82 m_pwDspCodeToLoad
= pwGina24DSP
;
84 m_byDigitalMode
= DIGITAL_MODE_SPDIF_RCA
;
85 m_bProfessionalSpdif
= FALSE
;
86 } // CGina24DspCommObject::CGina24DspCommObject( DWORD dwPhysRegBase )
89 //===========================================================================
93 //===========================================================================
95 CGina24DspCommObject::~CGina24DspCommObject()
97 ECHO_DEBUGPRINTF(("CGina24DspCommObject::~CGina24DspCommObject - "
98 "hasta la vista!\n"));
99 } // CGina24DspCommObject::~CGina24DspCommObject()
104 /****************************************************************************
106 Hardware setup and config
108 ****************************************************************************/
110 //===========================================================================
112 // Gina24 has an ASIC on the PCI card which must be loaded for anything
113 // interesting to happen.
115 //===========================================================================
117 BOOL
CGina24DspCommObject::LoadASIC()
119 DWORD dwControlReg
, dwSize
;
126 // Give the DSP a few milliseconds to settle down
128 m_pOsSupport
->OsSnooze( 10000 );
131 // Pick the correct ASIC for '301 or '361 Gina24
133 if ( DEVICE_ID_56361
== m_pOsSupport
->GetDeviceId() )
135 pbAsic
= pbGina24ASIC_361
;
136 dwSize
= sizeof( pbGina24ASIC_361
);
140 pbAsic
= pbGina24ASIC
;
141 dwSize
= sizeof( pbGina24ASIC
);
143 if ( !CDspCommObject::LoadASIC( DSP_FNC_LOAD_GINA24_ASIC
,
151 // Now give the new ASIC a little time to set up
153 m_pOsSupport
->OsSnooze( 10000 );
161 // Set up the control register if the load succeeded -
163 // 48 kHz, internal clock, S/PDIF RCA mode
167 dwControlReg
= GML_CONVERTER_ENABLE
| GML_48KHZ
;
168 WriteControlReg( dwControlReg
, TRUE
);
171 return m_bASICLoaded
;
173 } // BOOL CGina24DspCommObject::LoadASIC()
176 //===========================================================================
178 // Set the input clock to internal, S/PDIF, ADAT
180 //===========================================================================
182 ECHOSTATUS
CGina24DspCommObject::SetInputClock(WORD wClock
)
185 BOOL bWriteControlReg
;
188 ECHO_DEBUGPRINTF( ("CGina24DspCommObject::SetInputClock:\n") );
190 dwControlReg
= GetControlRegister();
193 // Mask off the clock select bits
195 dwControlReg
&= GML_CLOCK_CLEAR_MASK
;
198 bWriteControlReg
= TRUE
;
201 case ECHO_CLOCK_INTERNAL
:
203 ECHO_DEBUGPRINTF( ( "\tSet Gina24 clock to INTERNAL\n" ) );
206 bWriteControlReg
= FALSE
;
208 } // ECHO_CLOCK_INTERNAL
210 case ECHO_CLOCK_SPDIF
:
212 if ( DIGITAL_MODE_ADAT
== GetDigitalMode() )
214 return ECHOSTATUS_CLOCK_NOT_AVAILABLE
;
217 ECHO_DEBUGPRINTF( ( "\tSet Gina24 clock to SPDIF\n" ) );
219 dwControlReg
|= GML_SPDIF_CLOCK
;
221 if ( GML_CLOCK_DETECT_BIT_SPDIF96
& GetInputClockDetect() )
223 dwControlReg
|= GML_DOUBLE_SPEED_MODE
;
227 dwControlReg
&= ~GML_DOUBLE_SPEED_MODE
;
230 } // ECHO_CLOCK_SPDIF
232 case ECHO_CLOCK_ADAT
:
234 ECHO_DEBUGPRINTF( ( "\tSet Gina24 clock to ADAT\n" ) );
236 if ( DIGITAL_MODE_ADAT
!= GetDigitalMode() )
238 return ECHOSTATUS_CLOCK_NOT_AVAILABLE
;
241 dwControlReg
|= GML_ADAT_CLOCK
;
242 dwControlReg
&= ~GML_DOUBLE_SPEED_MODE
;
246 case ECHO_CLOCK_ESYNC
:
248 ECHO_DEBUGPRINTF( ( "\tSet Gina24 clock to ESYNC\n" ) );
250 dwControlReg
|= GML_ESYNC_CLOCK
;
251 dwControlReg
&= ~GML_DOUBLE_SPEED_MODE
;
253 } // ECHO_CLOCK_ESYNC
255 case ECHO_CLOCK_ESYNC96
:
257 ECHO_DEBUGPRINTF( ( "\tSet Gina24 clock to ESYNC96\n" ) );
259 dwControlReg
|= GML_ESYNC_CLOCK
| GML_DOUBLE_SPEED_MODE
;
261 } // ECHO_CLOCK_ESYNC96
264 ECHO_DEBUGPRINTF(("Input clock 0x%x not supported for Gina24\n",wClock
));
266 return ECHOSTATUS_CLOCK_NOT_SUPPORTED
;
267 } // switch (wInputClock)
271 // Winner! Save the new input clock.
273 m_wInputClock
= wClock
;
276 // Write the control reg if that's called for
278 if ( bWriteControlReg
)
280 WriteControlReg( dwControlReg
, TRUE
);
283 // Set Gina24 sample rate to something sane if word or superword is
287 SetSampleRate( GetSampleRate() );
289 return ECHOSTATUS_OK
;
291 } // ECHOSTATUS CGina24DspCommObject::SetInputClock
294 //===========================================================================
298 // Set the audio sample rate for Gina24
300 //===========================================================================
302 DWORD
CGina24DspCommObject::SetSampleRate( DWORD dwNewSampleRate
)
304 DWORD dwControlReg
, dwNewClock
;
307 // Only set the clock for internal mode. If the clock is not set to
308 // internal, try and re-set the input clock; this more transparently
309 // handles switching between single and double-speed mode
311 if ( GetInputClock() != ECHO_CLOCK_INTERNAL
)
313 ECHO_DEBUGPRINTF( ( "CGina24DspCommObject::SetSampleRate: Cannot set sample rate - "
314 "clock not set to CLK_CLOCKININTERNAL\n" ) );
317 // Save the rate anyhow
319 m_pDspCommPage
->dwSampleRate
= SWAP( dwNewSampleRate
);
322 // Set the input clock to the current value
324 SetInputClock( m_wInputClock
);
326 return GetSampleRate();
330 // Set the sample rate
334 dwControlReg
= GetControlRegister();
335 dwControlReg
&= GML_CLOCK_CLEAR_MASK
;
336 dwControlReg
&= GML_SPDIF_RATE_CLEAR_MASK
;
338 switch ( dwNewSampleRate
)
341 dwNewClock
= GML_96KHZ
;
345 dwNewClock
= GML_88KHZ
;
349 dwNewClock
= GML_48KHZ
| GML_SPDIF_SAMPLE_RATE1
;
353 dwNewClock
= GML_44KHZ
;
357 if ( dwControlReg
& GML_SPDIF_PRO_MODE
)
359 dwNewClock
|= GML_SPDIF_SAMPLE_RATE0
;
364 dwNewClock
= GML_32KHZ
|
365 GML_SPDIF_SAMPLE_RATE0
|
366 GML_SPDIF_SAMPLE_RATE1
;
370 dwNewClock
= GML_22KHZ
;
374 dwNewClock
= GML_16KHZ
;
378 dwNewClock
= GML_11KHZ
;
382 dwNewClock
= GML_8KHZ
;
386 ECHO_DEBUGPRINTF( ("CGina24DspCommObject::SetSampleRate: %ld "
387 "invalid!\n", dwNewSampleRate
) );
389 return( GetSampleRate() );
392 dwControlReg
|= dwNewClock
;
395 // Send the new value to the DSP
397 if ( ECHOSTATUS_OK
== WriteControlReg( dwControlReg
) )
399 m_pDspCommPage
->dwSampleRate
= SWAP( dwNewSampleRate
);
401 ECHO_DEBUGPRINTF( ("CGina24DspCommObject::SetSampleRate: %ld "
402 "clock %ld\n", dwNewSampleRate
, dwNewClock
) );
405 return GetSampleRate();
407 } // DWORD CGina24DspCommObject::SetSampleRate( DWORD dwNewSampleRate )
411 // **** CGina24DspCommObject.cpp ****