1// ****************************************************************************
2//
3//		CGina.cpp
4//
5//		Implementation file for the CGina driver class.  CGina is for
6// 	20-bit Gina, not Gina24.
7//
8//		Set editor tabs to 3 for your viewing pleasure.
9//
10// ----------------------------------------------------------------------------
11//
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
15// www.echoaudio.com
16//
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.
21//
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.
26//
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
30//
31// ****************************************************************************
32
33#include "CGina.h"
34
35#define GINA20_ANALOG_OUTPUT_LATENCY		137
36#define GINA20_ANALOG_INPUT_LATENCY			240
37#define GINA20_DIGITAL_OUTPUT_LATENCY		112
38#define GINA20_DIGITAL_INPUT_LATENCY		208
39
40
41/****************************************************************************
42
43	Construction and destruction
44
45 ****************************************************************************/
46
47//===========================================================================
48//
49// Overload new & delete so memory for this object is allocated
50//	from non-paged memory.
51//
52//===========================================================================
53
54PVOID CGina::operator new( size_t Size )
55{
56	PVOID 		pMemory;
57	ECHOSTATUS 	Status;
58
59	Status = OsAllocateNonPaged(Size,&pMemory);
60
61	if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory ))
62	{
63		ECHO_DEBUGPRINTF(("CGina::operator new - memory allocation failed\n"));
64
65		pMemory = NULL;
66	}
67	else
68	{
69		memset( pMemory, 0, Size );
70	}
71
72	return pMemory;
73
74}	// PVOID CGina::operator new( size_t Size )
75
76VOID  CGina::operator delete( PVOID pVoid )
77{
78	if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) )
79	{
80		ECHO_DEBUGPRINTF(("CGina::operator delete memory free failed\n"));
81	}
82}	// VOID  CGina::operator delete( PVOID pVoid )
83
84
85//===========================================================================
86//
87// Constructor and destructor
88//
89//===========================================================================
90
91CGina::CGina( PCOsSupport pOsSupport )
92		: CEchoGals( pOsSupport )
93{
94	ECHO_DEBUGPRINTF( ( "CGina::CGina() is born!\n" ) );
95
96	m_wAnalogOutputLatency = GINA20_ANALOG_OUTPUT_LATENCY;
97	m_wAnalogInputLatency = GINA20_ANALOG_INPUT_LATENCY;
98	m_wDigitalOutputLatency = GINA20_DIGITAL_OUTPUT_LATENCY;
99	m_wDigitalInputLatency = GINA20_DIGITAL_INPUT_LATENCY;
100}
101
102CGina::~CGina()
103{
104	ECHO_DEBUGPRINTF( ( "CGina::~CGina() is toast!\n" ) );
105}
106
107
108
109
110/****************************************************************************
111
112	Setup and hardware initialization
113
114 ****************************************************************************/
115
116//===========================================================================
117//
118// Every card has an InitHw method
119//
120//===========================================================================
121
122ECHOSTATUS CGina::InitHw()
123{
124	ECHOSTATUS	Status;
125
126	//
127	// Call the base method
128	//
129	if ( ECHOSTATUS_OK != ( Status = CEchoGals::InitHw() ) )
130		return Status;
131
132	//
133	// Create the DSP comm object
134	//
135	ECHO_ASSERT(NULL == m_pDspCommObject );
136	m_pDspCommObject = new CGinaDspCommObject( (PDWORD) m_pvSharedMemory,
137															 m_pOsSupport );
138	if (NULL == m_pDspCommObject)
139	{
140		ECHO_DEBUGPRINTF(("CGina::InitHw - could not create DSP comm object\n"));
141		return ECHOSTATUS_NO_MEM;
142	}
143
144	//
145	// Load the firmware
146	//
147	GetDspCommObject()->LoadFirmware();
148	if ( GetDspCommObject()->IsBoardBad() )
149		return ECHOSTATUS_DSP_DEAD;
150
151	//
152	// Clear the "bad board" flag
153	//
154	m_wFlags &= ~ECHOGALS_FLAG_BADBOARD;
155
156	//
157	//	Must call this here after DSP is init to
158	//	init gains and mutes
159	//
160	Status = InitLineLevels();
161
162	//
163	// Set the S/PDIF output format to "professional"
164	//
165	SetProfessionalSpdif( TRUE );
166
167	//
168	//	Get default sample rate from DSP
169	//
170	m_dwSampleRate = GetDspCommObject()->GetSampleRate();
171
172	ECHO_DEBUGPRINTF( ( "CGina::InitHw()\n" ) );
173	return Status;
174
175}	// ECHOSTATUS CGina::InitHw()
176
177
178
179
180/****************************************************************************
181
182	Informational methods
183
184 ****************************************************************************/
185
186//===========================================================================
187//
188// Override GetCapabilities to enumerate unique capabilties for this card
189//
190//===========================================================================
191
192ECHOSTATUS CGina::GetCapabilities
193(
194	PECHOGALS_CAPS	pCapabilities
195)
196{
197	WORD i;
198
199	GetBaseCapabilities(pCapabilities);
200
201	//
202	// Add input gain to input busses
203	//
204	for (i = 0; i < GetFirstDigitalBusIn(); i++)
205	{
206		pCapabilities->dwBusInCaps[i] |= ECHOCAPS_GAIN |
207													ECHOCAPS_MUTE;
208	}
209
210	pCapabilities->dwInClockTypes |= ECHO_CLOCK_BIT_SPDIF;
211
212	return ECHOSTATUS_OK;
213}
214
215
216//===========================================================================
217//
218// GetInputClockDetect returns a bitmask consisting of all the input
219// clocks currently connected to the hardware; this changes as the user
220// connects and disconnects clock inputs.
221//
222// You should use this information to determine which clocks the user is
223// allowed to select.
224//
225// Gina20 only supports S/PDIF input clock.
226//
227//===========================================================================
228
229ECHOSTATUS CGina::GetInputClockDetect(DWORD &dwClockDetectBits)
230{
231	if ( NULL == GetDspCommObject() || GetDspCommObject()->IsBoardBad() )
232	{
233		ECHO_DEBUGPRINTF( ("CGina::GetInputClockDetect: DSP Dead!\n") );
234		return ECHOSTATUS_DSP_DEAD;
235	}
236
237	DWORD dwClocksFromDsp = GetDspCommObject()->GetInputClockDetect();
238
239	dwClockDetectBits = ECHO_CLOCK_BIT_INTERNAL;
240
241	if (0 != (dwClocksFromDsp & GLDM_CLOCK_DETECT_BIT_SPDIF))
242		dwClockDetectBits |= ECHO_CLOCK_BIT_SPDIF;
243
244	return ECHOSTATUS_OK;
245
246}	// GetInputClockDetect
247
248
249//===========================================================================
250//
251// QueryAudioSampleRate is used to find out if this card can handle a
252// given sample rate.
253//
254//===========================================================================
255
256ECHOSTATUS CGina::QueryAudioSampleRate
257(
258	DWORD		dwSampleRate
259)
260{
261	if ( dwSampleRate != 44100 &&
262		  dwSampleRate != 48000 )
263	{
264		ECHO_DEBUGPRINTF(
265			("CGina::QueryAudioSampleRate() - rate %ld invalid\n",
266			dwSampleRate) );
267		return ECHOSTATUS_BAD_FORMAT;
268	}
269
270	ECHO_DEBUGPRINTF( ( "CGina::QueryAudioSampleRate()\n" ) );
271	return ECHOSTATUS_OK;
272
273}	// ECHOSTATUS CGina::QueryAudioSampleRate
274
275
276void CGina::QuerySampleRateRange(DWORD &dwMinRate,DWORD &dwMaxRate)
277{
278	dwMinRate = 44100;
279	dwMaxRate = 48000;
280}
281
282// *** CGina.cpp ***
283