1626bc4beSJérôme Duval// ****************************************************************************
2626bc4beSJérôme Duval//
3626bc4beSJérôme Duval//		CMona.cpp
4626bc4beSJérôme Duval//
5626bc4beSJérôme Duval//		Implementation file for the CMona driver class.
6626bc4beSJérôme Duval//		Set editor tabs to 3 for your viewing pleasure.
7626bc4beSJérôme Duval//
8626bc4beSJérôme Duval// ----------------------------------------------------------------------------
9626bc4beSJérôme Duval//
10626bc4beSJérôme Duval// This file is part of Echo Digital Audio's generic driver library.
11626bc4beSJérôme Duval// Copyright Echo Digital Audio Corporation (c) 1998 - 2005
12626bc4beSJérôme Duval// All rights reserved
13626bc4beSJérôme Duval// www.echoaudio.com
14626bc4beSJérôme Duval//
15626bc4beSJérôme Duval// This library is free software; you can redistribute it and/or
16626bc4beSJérôme Duval// modify it under the terms of the GNU Lesser General Public
17626bc4beSJérôme Duval// License as published by the Free Software Foundation; either
18626bc4beSJérôme Duval// version 2.1 of the License, or (at your option) any later version.
19626bc4beSJérôme Duval//
20626bc4beSJérôme Duval// This library is distributed in the hope that it will be useful,
21626bc4beSJérôme Duval// but WITHOUT ANY WARRANTY; without even the implied warranty of
22626bc4beSJérôme Duval// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23626bc4beSJérôme Duval// Lesser General Public License for more details.
24626bc4beSJérôme Duval//
25626bc4beSJérôme Duval// You should have received a copy of the GNU Lesser General Public
26626bc4beSJérôme Duval// License along with this library; if not, write to the Free Software
27626bc4beSJérôme Duval// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28626bc4beSJérôme Duval//
29626bc4beSJérôme Duval// ****************************************************************************
30626bc4beSJérôme Duval
31626bc4beSJérôme Duval#include "CMona.h"
32626bc4beSJérôme Duval
33626bc4beSJérôme Duval#define MONA_ANALOG_OUTPUT_LATENCY		59
34626bc4beSJérôme Duval#define MONA_ANALOG_INPUT_LATENCY		71
35626bc4beSJérôme Duval#define MONA_DIGITAL_OUTPUT_LATENCY		32
36626bc4beSJérôme Duval#define MONA_DIGITAL_INPUT_LATENCY		32
37626bc4beSJérôme Duval
38626bc4beSJérôme Duval
39626bc4beSJérôme Duval
40626bc4beSJérôme Duval/****************************************************************************
41626bc4beSJérôme Duval
42626bc4beSJérôme Duval	Construction and destruction
43626bc4beSJérôme Duval
44626bc4beSJérôme Duval ****************************************************************************/
45626bc4beSJérôme Duval
46626bc4beSJérôme Duval//===========================================================================
47626bc4beSJérôme Duval//
48626bc4beSJérôme Duval// Overload new & delete so memory for this object is allocated
49626bc4beSJérôme Duval//	from non-paged memory.
50626bc4beSJérôme Duval//
51626bc4beSJérôme Duval//===========================================================================
52626bc4beSJérôme Duval
53626bc4beSJérôme DuvalPVOID CMona::operator new( size_t Size )
54626bc4beSJérôme Duval{
55626bc4beSJérôme Duval	PVOID 		pMemory;
56626bc4beSJérôme Duval	ECHOSTATUS 	Status;
57626bc4beSJérôme Duval
58626bc4beSJérôme Duval	Status = OsAllocateNonPaged(Size,&pMemory);
59626bc4beSJérôme Duval
60626bc4beSJérôme Duval	if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory ))
61626bc4beSJérôme Duval	{
62626bc4beSJérôme Duval		ECHO_DEBUGPRINTF(("CMona::operator new - memory allocation failed\n"));
63626bc4beSJérôme Duval
64626bc4beSJérôme Duval		pMemory = NULL;
65626bc4beSJérôme Duval	}
66626bc4beSJérôme Duval	else
67626bc4beSJérôme Duval	{
68626bc4beSJérôme Duval		memset( pMemory, 0, Size );
69626bc4beSJérôme Duval	}
70626bc4beSJérôme Duval
71626bc4beSJérôme Duval	return pMemory;
72626bc4beSJérôme Duval
73626bc4beSJérôme Duval}	// PVOID CMona::operator new( size_t Size )
74626bc4beSJérôme Duval
75626bc4beSJérôme Duval
76626bc4beSJérôme DuvalVOID  CMona::operator delete( PVOID pVoid )
77626bc4beSJérôme Duval{
78626bc4beSJérôme Duval	if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) )
79626bc4beSJérôme Duval	{
80626bc4beSJérôme Duval		ECHO_DEBUGPRINTF(("CMona::operator delete memory free failed\n"));
81626bc4beSJérôme Duval	}
82626bc4beSJérôme Duval}	// VOID CMona::operator delete( PVOID pVoid )
83626bc4beSJérôme Duval
84626bc4beSJérôme Duval
85626bc4beSJérôme Duval//===========================================================================
86626bc4beSJérôme Duval//
87626bc4beSJérôme Duval// Constructor and destructor
88626bc4beSJérôme Duval//
89626bc4beSJérôme Duval//===========================================================================
90626bc4beSJérôme Duval
91626bc4beSJérôme DuvalCMona::CMona( PCOsSupport pOsSupport )
92626bc4beSJérôme Duval		: CEchoGals( pOsSupport )
93626bc4beSJérôme Duval{
94626bc4beSJérôme Duval	ECHO_DEBUGPRINTF( ( "CMona::CMona() is born!\n" ) );
95626bc4beSJérôme Duval
96626bc4beSJérôme Duval	m_wAnalogOutputLatency = MONA_ANALOG_OUTPUT_LATENCY;
97626bc4beSJérôme Duval	m_wAnalogInputLatency = MONA_ANALOG_INPUT_LATENCY;
98626bc4beSJérôme Duval	m_wDigitalOutputLatency = MONA_DIGITAL_OUTPUT_LATENCY;
99626bc4beSJérôme Duval	m_wDigitalInputLatency = MONA_DIGITAL_INPUT_LATENCY;
100626bc4beSJérôme Duval}
101626bc4beSJérôme Duval
102626bc4beSJérôme DuvalCMona::~CMona()
103626bc4beSJérôme Duval{
104626bc4beSJérôme Duval	ECHO_DEBUGPRINTF( ( "CMona::~CMona() is toast!\n" ) );
105626bc4beSJérôme Duval}
106626bc4beSJérôme Duval
107626bc4beSJérôme Duval
108626bc4beSJérôme Duval
109626bc4beSJérôme Duval
110626bc4beSJérôme Duval/****************************************************************************
111626bc4beSJérôme Duval
112626bc4beSJérôme Duval	Setup and hardware initialization
113626bc4beSJérôme Duval
114626bc4beSJérôme Duval ****************************************************************************/
115626bc4beSJérôme Duval
116626bc4beSJérôme Duval//===========================================================================
117626bc4beSJérôme Duval//
118626bc4beSJérôme Duval// Every card has an InitHw method
119626bc4beSJérôme Duval//
120626bc4beSJérôme Duval//===========================================================================
121626bc4beSJérôme Duval
122626bc4beSJérôme DuvalECHOSTATUS CMona::InitHw()
123626bc4beSJérôme Duval{
124626bc4beSJérôme Duval	ECHOSTATUS	Status;
125626bc4beSJérôme Duval
126626bc4beSJérôme Duval	//
127626bc4beSJérôme Duval	// Call the base method
128626bc4beSJérôme Duval	//
129626bc4beSJérôme Duval	if ( ECHOSTATUS_OK != ( Status = CEchoGals::InitHw() ) )
130626bc4beSJérôme Duval		return Status;
131626bc4beSJérôme Duval
132626bc4beSJérôme Duval	//
133626bc4beSJérôme Duval	// Create the DSP comm object
134626bc4beSJérôme Duval	//
1354dd9e436SJérôme Duval	ECHO_ASSERT(NULL == m_pDspCommObject );
136626bc4beSJérôme Duval	m_pDspCommObject = new CMonaDspCommObject( (PDWORD) m_pvSharedMemory,
137626bc4beSJérôme Duval															 m_pOsSupport );
138626bc4beSJérôme Duval	if (NULL == m_pDspCommObject)
139626bc4beSJérôme Duval	{
140626bc4beSJérôme Duval		ECHO_DEBUGPRINTF(("CMona::InitHw - could not create DSP comm object\n"));
141626bc4beSJérôme Duval		return ECHOSTATUS_NO_MEM;
142626bc4beSJérôme Duval	}
143626bc4beSJérôme Duval
144626bc4beSJérôme Duval	//
145626bc4beSJérôme Duval	// Load the DSP, the PCI card ASIC, and the external box ASIC
146626bc4beSJérôme Duval	//
147626bc4beSJérôme Duval	GetDspCommObject()->LoadFirmware();
148626bc4beSJérôme Duval	if ( GetDspCommObject()->IsBoardBad() )
149626bc4beSJérôme Duval		return ECHOSTATUS_DSP_DEAD;
150626bc4beSJérôme Duval
151626bc4beSJérôme Duval	//
152626bc4beSJérôme Duval	// Clear the "bad board" flag; set the flags to indicate that
153626bc4beSJérôme Duval	// Mona can handle super-interleave and supports the digital
154626bc4beSJérôme Duval	// input auto-mute.
155626bc4beSJérôme Duval	//
156626bc4beSJérôme Duval	m_wFlags &= ~ECHOGALS_FLAG_BADBOARD;
157626bc4beSJérôme Duval	m_wFlags |= ECHOGALS_ROFLAG_SUPER_INTERLEAVE_OK |
158626bc4beSJérôme Duval				ECHOGALS_ROFLAG_DIGITAL_IN_AUTOMUTE;
159626bc4beSJérôme Duval
160626bc4beSJérôme Duval	//
161626bc4beSJérôme Duval	//	Must call this here after DSP is init to
162626bc4beSJérôme Duval	//	init gains and mutes
163626bc4beSJérôme Duval	//
164626bc4beSJérôme Duval	Status = InitLineLevels();
165626bc4beSJérôme Duval	if ( ECHOSTATUS_OK != Status )
166626bc4beSJérôme Duval		return Status;
167626bc4beSJérôme Duval
168626bc4beSJérôme Duval	//
169626bc4beSJérôme Duval	// Set the digital mode to S/PDIF RCA
170626bc4beSJérôme Duval	//
171626bc4beSJérôme Duval	SetDigitalMode( DIGITAL_MODE_SPDIF_RCA );
172626bc4beSJérôme Duval
173626bc4beSJérôme Duval	//
174626bc4beSJérôme Duval	// Set the S/PDIF output format to "professional"
175626bc4beSJérôme Duval	//
176626bc4beSJérôme Duval	SetProfessionalSpdif( TRUE );
177626bc4beSJérôme Duval
178626bc4beSJérôme Duval	//
179626bc4beSJérôme Duval	//	Get default sample rate from DSP
180626bc4beSJérôme Duval	//
181626bc4beSJérôme Duval	m_dwSampleRate = GetDspCommObject()->GetSampleRate();
182626bc4beSJérôme Duval
183626bc4beSJérôme Duval	ECHO_DEBUGPRINTF( ( "CMona::InitHw()\n" ) );
184626bc4beSJérôme Duval	return Status;
185626bc4beSJérôme Duval
186626bc4beSJérôme Duval}	// ECHOSTATUS CMona::InitHw()
187626bc4beSJérôme Duval
188626bc4beSJérôme Duval
189626bc4beSJérôme Duval
190626bc4beSJérôme Duval
191626bc4beSJérôme Duval/****************************************************************************
192626bc4beSJérôme Duval
193626bc4beSJérôme Duval	Informational methods
194626bc4beSJérôme Duval
195626bc4beSJérôme Duval ****************************************************************************/
196626bc4beSJérôme Duval
197626bc4beSJérôme Duval//===========================================================================
198626bc4beSJérôme Duval//
199626bc4beSJérôme Duval// Override GetCapabilities to enumerate unique capabilties for this card
200626bc4beSJérôme Duval//
201626bc4beSJérôme Duval//===========================================================================
202626bc4beSJérôme Duval
203626bc4beSJérôme DuvalECHOSTATUS CMona::GetCapabilities
204626bc4beSJérôme Duval(
205626bc4beSJérôme Duval	PECHOGALS_CAPS	pCapabilities
206626bc4beSJérôme Duval)
207626bc4beSJérôme Duval{
208626bc4beSJérôme Duval	ECHOSTATUS	Status;
209626bc4beSJérôme Duval
210626bc4beSJérôme Duval	Status = GetBaseCapabilities(pCapabilities);
211626bc4beSJérôme Duval	if ( ECHOSTATUS_OK != Status )
212626bc4beSJérôme Duval		return Status;
213626bc4beSJérôme Duval
214626bc4beSJérôme Duval	pCapabilities->dwInClockTypes |= ECHO_CLOCK_BIT_WORD		|
215626bc4beSJérôme Duval												ECHO_CLOCK_BIT_SPDIF		|
216626bc4beSJérôme Duval												ECHO_CLOCK_BIT_ADAT;
217626bc4beSJérôme Duval
218626bc4beSJérôme Duval	return Status;
219626bc4beSJérôme Duval
220626bc4beSJérôme Duval}	// ECHOSTATUS CMona::GetCapabilities
221626bc4beSJérôme Duval
222626bc4beSJérôme Duval
223626bc4beSJérôme Duval//===========================================================================
224626bc4beSJérôme Duval//
225626bc4beSJérôme Duval// QueryAudioSampleRate is used to find out if this card can handle a
226626bc4beSJérôme Duval// given sample rate.
227626bc4beSJérôme Duval//
228626bc4beSJérôme Duval//===========================================================================
229626bc4beSJérôme Duval
230626bc4beSJérôme DuvalECHOSTATUS CMona::QueryAudioSampleRate
231626bc4beSJérôme Duval(
232626bc4beSJérôme Duval	DWORD		dwSampleRate
233626bc4beSJérôme Duval)
234626bc4beSJérôme Duval{
235626bc4beSJérôme Duval	if ( dwSampleRate !=  8000 &&
236626bc4beSJérôme Duval		  dwSampleRate != 11025 &&
237626bc4beSJérôme Duval		  dwSampleRate != 16000 &&
238626bc4beSJérôme Duval		  dwSampleRate != 22050 &&
239626bc4beSJérôme Duval		  dwSampleRate != 32000 &&
240626bc4beSJérôme Duval		  dwSampleRate != 44100 &&
241626bc4beSJérôme Duval		  dwSampleRate != 48000 &&
242626bc4beSJérôme Duval		  dwSampleRate != 88200 &&
243626bc4beSJérôme Duval		  dwSampleRate != 96000 )
244626bc4beSJérôme Duval	{
245626bc4beSJérôme Duval		ECHO_DEBUGPRINTF(
246626bc4beSJérôme Duval			("CMona::QueryAudioSampleRate() - rate %ld invalid\n",dwSampleRate) );
247626bc4beSJérôme Duval		return ECHOSTATUS_BAD_FORMAT;
248626bc4beSJérôme Duval	}
249626bc4beSJérôme Duval	if ( dwSampleRate >= 88200 && DIGITAL_MODE_ADAT == GetDigitalMode() )
250626bc4beSJérôme Duval	{
251626bc4beSJérôme Duval		ECHO_DEBUGPRINTF(
252626bc4beSJérôme Duval			("CMona::QueryAudioSampleRate() Sample rate cannot be "
253626bc4beSJérôme Duval			 "set to 88,200 Hz or 96,000 Hz in ADAT mode\n") );
254626bc4beSJérôme Duval		return ECHOSTATUS_BAD_FORMAT;
255626bc4beSJérôme Duval	}
256626bc4beSJérôme Duval
257626bc4beSJérôme Duval	ECHO_DEBUGPRINTF( ( "CMona::QueryAudioSampleRate()\n" ) );
258626bc4beSJérôme Duval	return ECHOSTATUS_OK;
259626bc4beSJérôme Duval}	// ECHOSTATUS CMona::QueryAudioSampleRate
260626bc4beSJérôme Duval
261626bc4beSJérôme Duval
2624dd9e436SJérôme Duvalvoid CMona::QuerySampleRateRange(DWORD &dwMinRate,DWORD &dwMaxRate)
2634dd9e436SJérôme Duval{
2644dd9e436SJérôme Duval	dwMinRate = 8000;
2654dd9e436SJérôme Duval	dwMaxRate = 96000;
2664dd9e436SJérôme Duval}
2674dd9e436SJérôme Duval
2684dd9e436SJérôme Duval
269626bc4beSJérôme Duval//===========================================================================
270626bc4beSJérôme Duval//
271626bc4beSJérôme Duval// GetInputClockDetect returns a bitmask consisting of all the input
272626bc4beSJérôme Duval// clocks currently connected to the hardware; this changes as the user
273626bc4beSJérôme Duval// connects and disconnects clock inputs.
274626bc4beSJérôme Duval//
275626bc4beSJérôme Duval// You should use this information to determine which clocks the user is
276626bc4beSJérôme Duval// allowed to select.
277626bc4beSJérôme Duval//
278626bc4beSJérôme Duval// Mona supports S/PDIF, word, and ADAT input clocks.
279626bc4beSJérôme Duval//
280626bc4beSJérôme Duval//===========================================================================
281626bc4beSJérôme Duval
282626bc4beSJérôme DuvalECHOSTATUS CMona::GetInputClockDetect(DWORD &dwClockDetectBits)
283626bc4beSJérôme Duval{
284626bc4beSJérôme Duval	//ECHO_DEBUGPRINTF(("CMona::GetInputClockDetect\n"));
285626bc4beSJérôme Duval
286626bc4beSJérôme Duval	if ( NULL == GetDspCommObject() || GetDspCommObject()->IsBoardBad() )
287626bc4beSJérôme Duval	{
288626bc4beSJérôme Duval		ECHO_DEBUGPRINTF( ("CMona::GetInputClockDetect: DSP Dead!\n") );
289626bc4beSJérôme Duval		return ECHOSTATUS_DSP_DEAD;
290626bc4beSJérôme Duval	}
291626bc4beSJérôme Duval
292626bc4beSJérôme Duval	//
293626bc4beSJérôme Duval	// Map the DSP clock detect bits to the generic driver clock detect bits
294626bc4beSJérôme Duval	//
295626bc4beSJérôme Duval	DWORD dwClocksFromDsp = GetDspCommObject()->GetInputClockDetect();
296626bc4beSJérôme Duval
297626bc4beSJérôme Duval	dwClockDetectBits = ECHO_CLOCK_BIT_INTERNAL;
298626bc4beSJérôme Duval
299626bc4beSJérôme Duval	if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_SPDIF))
300626bc4beSJérôme Duval		dwClockDetectBits |= ECHO_CLOCK_BIT_SPDIF;
301626bc4beSJérôme Duval
302626bc4beSJérôme Duval	if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_ADAT))
303626bc4beSJérôme Duval		dwClockDetectBits |= ECHO_CLOCK_BIT_ADAT;
304626bc4beSJérôme Duval
305626bc4beSJérôme Duval	if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_WORD))
306626bc4beSJérôme Duval		dwClockDetectBits |= ECHO_CLOCK_BIT_WORD;
307626bc4beSJérôme Duval
308626bc4beSJérôme Duval	return ECHOSTATUS_OK;
309626bc4beSJérôme Duval
310626bc4beSJérôme Duval}	// GetInputClockDetect
311626bc4beSJérôme Duval
312626bc4beSJérôme Duval
313626bc4beSJérôme Duval// *** CMona.cpp ***
314