1189251Ssam// ****************************************************************************
2189251Ssam//
3189251Ssam//		CMia.cpp
4189251Ssam//
5252726Srpaulo//		Implementation file for the CMia driver class.
6252726Srpaulo//		Set editor tabs to 3 for your viewing pleasure.
7189251Ssam//
8189251Ssam// ----------------------------------------------------------------------------
9189251Ssam//
10189251Ssam// This file is part of Echo Digital Audio's generic driver library.
11189251Ssam// Copyright Echo Digital Audio Corporation (c) 1998 - 2005
12214734Srpaulo// All rights reserved
13252726Srpaulo// www.echoaudio.com
14189251Ssam//
15189251Ssam// This library is free software; you can redistribute it and/or
16189251Ssam// modify it under the terms of the GNU Lesser General Public
17189251Ssam// License as published by the Free Software Foundation; either
18189251Ssam// version 2.1 of the License, or (at your option) any later version.
19189251Ssam//
20189251Ssam// This library is distributed in the hope that it will be useful,
21189251Ssam// but WITHOUT ANY WARRANTY; without even the implied warranty of
22189251Ssam// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23189251Ssam// Lesser General Public License for more details.
24189251Ssam//
25189251Ssam// You should have received a copy of the GNU Lesser General Public
26189251Ssam// License along with this library; if not, write to the Free Software
27189251Ssam// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28189251Ssam//
29189251Ssam// ****************************************************************************
30189251Ssam
31189251Ssam#include "CMia.h"
32189251Ssam
33189251Ssam#define MIA_ANALOG_OUTPUT_LATENCY	63
34189251Ssam#define MIA_ANALOG_INPUT_LATENCY		62
35189251Ssam
36189251Ssam
37189251Ssam
38189251Ssam/****************************************************************************
39189251Ssam
40189251Ssam	Construction and destruction
41189251Ssam
42189251Ssam ****************************************************************************/
43189251Ssam
44189251Ssam//===========================================================================
45189251Ssam//
46189251Ssam// Overload new & delete so memory for this object is allocated
47189251Ssam//	from non-paged memory.
48189251Ssam//
49189251Ssam//===========================================================================
50189251Ssam
51189251SsamPVOID CMia::operator new( size_t Size )
52189251Ssam{
53189251Ssam	PVOID 		pMemory;
54189251Ssam	ECHOSTATUS 	Status;
55189251Ssam
56189251Ssam	Status = OsAllocateNonPaged(Size,&pMemory);
57189251Ssam
58189251Ssam	if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory ))
59189251Ssam	{
60189251Ssam		ECHO_DEBUGPRINTF(("CMia::operator new - memory allocation failed\n"));
61189251Ssam
62189251Ssam		pMemory = NULL;
63189251Ssam	}
64189251Ssam	else
65189251Ssam	{
66189251Ssam		memset( pMemory, 0, Size );
67189251Ssam	}
68189251Ssam
69189251Ssam	return pMemory;
70189251Ssam
71189251Ssam}	// PVOID CMia::operator new( size_t Size )
72189251Ssam
73189251Ssam
74189251SsamVOID  CMia::operator delete( PVOID pVoid )
75189251Ssam{
76189251Ssam	if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) )
77189251Ssam	{
78189251Ssam		ECHO_DEBUGPRINTF(("CMia::operator delete memory free failed\n"));
79189251Ssam	}
80189251Ssam}	// VOID CMia::operator delete( PVOID pVoid )
81189251Ssam
82189251Ssam
83189251Ssam//===========================================================================
84189251Ssam//
85189251Ssam// Constructor and destructor
86189251Ssam//
87189251Ssam//===========================================================================
88189251Ssam
89189251SsamCMia::CMia( PCOsSupport pOsSupport )
90189251Ssam	  : CEchoGalsVmixer( pOsSupport )
91189251Ssam{
92189251Ssam	ECHO_DEBUGPRINTF( ( "CMia::CMia() is born!\n" ) );
93189251Ssam
94189251Ssam	//
95189251Ssam	// Mia's virtual outputs make things tricky, since a pipe can
96189251Ssam	// go to either bus.
97189251Ssam	//
98189251Ssam	m_wAnalogOutputLatency = MIA_ANALOG_OUTPUT_LATENCY;
99189251Ssam	m_wAnalogInputLatency = MIA_ANALOG_INPUT_LATENCY;
100189251Ssam
101189251Ssam}
102189251Ssam
103189251SsamCMia::~CMia()
104189251Ssam{
105189251Ssam	ECHO_DEBUGPRINTF( ( "CMia::~CMia() is toast!\n" ) );
106189251Ssam}
107189251Ssam
108189251Ssam
109189251Ssam
110189251Ssam
111189251Ssam/****************************************************************************
112189251Ssam
113189251Ssam	Setup and hardware initialization
114189251Ssam
115189251Ssam ****************************************************************************/
116189251Ssam
117189251Ssam//===========================================================================
118189251Ssam//
119189251Ssam// Every card has an InitHw method
120189251Ssam//
121189251Ssam//===========================================================================
122189251Ssam
123189251SsamECHOSTATUS CMia::InitHw()
124189251Ssam{
125189251Ssam	ECHOSTATUS	Status;
126189251Ssam	WORD			i;
127189251Ssam
128189251Ssam	//
129189251Ssam	// Call the base method
130189251Ssam	//
131189251Ssam	if ( ECHOSTATUS_OK != ( Status = CEchoGals::InitHw() ) )
132189251Ssam		return Status;
133189251Ssam
134189251Ssam	//
135189251Ssam	// Create the DSP comm object
136337817Scy	//
137189251Ssam	ECHO_ASSERT(NULL == m_pDspCommObject );
138189251Ssam	m_pDspCommObject = new CMiaDspCommObject( (PDWORD) m_pvSharedMemory,
139189251Ssam															 m_pOsSupport );
140189251Ssam	if (NULL == m_pDspCommObject)
141189251Ssam	{
142189251Ssam		ECHO_DEBUGPRINTF(("CMia::InitHw - could not create DSP comm object\n"));
143189251Ssam		return ECHOSTATUS_NO_MEM;
144189251Ssam	}
145189251Ssam
146189251Ssam	//
147189251Ssam	// Load the DSP
148189251Ssam	//
149189251Ssam	GetDspCommObject()->LoadFirmware();
150189251Ssam	if ( GetDspCommObject()->IsBoardBad() )
151189251Ssam		return ECHOSTATUS_DSP_DEAD;
152189251Ssam
153189251Ssam	//
154189251Ssam	// Clear the "bad board" flag; set the flags to indicate that
155189251Ssam	// Mia can handle super-interleave.
156189251Ssam	//
157189251Ssam	m_wFlags &= ~ECHOGALS_FLAG_BADBOARD;
158189251Ssam	m_wFlags |= ECHOGALS_ROFLAG_SUPER_INTERLEAVE_OK;
159189251Ssam
160189251Ssam	//
161189251Ssam	//	Must call this here after DSP is init to
162189251Ssam	//	init gains and mutes
163189251Ssam	//
164189251Ssam	Status = InitLineLevels();
165189251Ssam	if ( ECHOSTATUS_OK != Status )
166189251Ssam		return Status;
167189251Ssam
168189251Ssam	//
169189251Ssam	// Set defaults for +4/-10
170189251Ssam	//
171189251Ssam	for (i = 0; i < GetFirstDigitalBusOut(); i++ )
172189251Ssam	{
173189251Ssam		GetDspCommObject()->
174189251Ssam			SetNominalLevel( i, FALSE );	// FALSE is +4 here
175189251Ssam	}
176189251Ssam	for ( i = 0; i < GetFirstDigitalBusIn(); i++ )
177189251Ssam	{
178189251Ssam		GetDspCommObject()->
179189251Ssam			SetNominalLevel( GetNumBussesOut() + i, FALSE );
180189251Ssam	}
181189251Ssam
182189251Ssam	//
183189251Ssam	// Set the digital mode to S/PDIF RCA
184189251Ssam	//
185189251Ssam	SetDigitalMode( DIGITAL_MODE_SPDIF_RCA );
186189251Ssam
187189251Ssam	//
188189251Ssam	//	Get default sample rate from DSP
189189251Ssam	//
190189251Ssam	m_dwSampleRate = GetDspCommObject()->GetSampleRate();
191189251Ssam
192189251Ssam	//
193189251Ssam	// Is this a Mia MIDI card?
194189251Ssam	//
195189251Ssam	if (MIA_MIDI_REV == m_pOsSupport->GetCardRev())
196189251Ssam	{
197189251Ssam		Status = m_MidiIn.Init( this );
198189251Ssam	}
199189251Ssam
200189251Ssam
201189251Ssam	ECHO_DEBUGPRINTF( ( "CMia::InitHw()\n" ) );
202189251Ssam	return Status;
203189251Ssam
204189251Ssam}	// ECHOSTATUS CMia::InitHw()
205189251Ssam
206189251Ssam
207189251Ssam
208189251Ssam
209189251Ssam/****************************************************************************
210189251Ssam
211189251Ssam	Informational methods
212189251Ssam
213189251Ssam ****************************************************************************/
214189251Ssam
215189251Ssam//===========================================================================
216189251Ssam//
217189251Ssam// Override GetCapabilities to enumerate unique capabilties for this card
218189251Ssam//
219189251Ssam//===========================================================================
220189251Ssam
221189251SsamECHOSTATUS CMia::GetCapabilities
222189251Ssam(
223189251Ssam	PECHOGALS_CAPS	pCapabilities
224337817Scy)
225189251Ssam{
226189251Ssam	ECHOSTATUS	Status;
227189251Ssam	WORD			i;
228189251Ssam
229189251Ssam	Status = GetBaseCapabilities(pCapabilities);
230189251Ssam	if ( ECHOSTATUS_OK != Status )
231189251Ssam		return Status;
232189251Ssam
233189251Ssam	//
234189251Ssam	// Add nominal level control to analog ins & outs
235189251Ssam	//
236189251Ssam	for (i = 0 ; i < GetFirstDigitalBusOut(); i++)
237189251Ssam	{
238189251Ssam		pCapabilities->dwBusOutCaps[i] |= ECHOCAPS_NOMINAL_LEVEL;
239189251Ssam	}
240189251Ssam
241189251Ssam	for (i = 0 ; i < GetFirstDigitalBusIn(); i++)
242189251Ssam	{
243189251Ssam		pCapabilities->dwBusInCaps[i] |= ECHOCAPS_NOMINAL_LEVEL;
244189251Ssam	}
245189251Ssam
246189251Ssam	pCapabilities->dwInClockTypes |= ECHO_CLOCK_BIT_SPDIF;
247189251Ssam	pCapabilities->dwOutClockTypes = 0;
248189251Ssam
249189251Ssam	return Status;
250189251Ssam
251189251Ssam}	// ECHOSTATUS CMia::GetCapabilities
252189251Ssam
253189251Ssam
254189251Ssam//===========================================================================
255189251Ssam//
256189251Ssam// QueryAudioSampleRate is used to find out if this card can handle a
257189251Ssam// given sample rate.
258189251Ssam//
259337817Scy//===========================================================================
260189251Ssam
261189251SsamECHOSTATUS CMia::QueryAudioSampleRate
262189251Ssam(
263189251Ssam	DWORD		dwSampleRate
264189251Ssam)
265189251Ssam{
266189251Ssam	if ( dwSampleRate != 32000 &&
267189251Ssam		  dwSampleRate != 44100 &&
268189251Ssam		  dwSampleRate != 48000 &&
269189251Ssam		  dwSampleRate != 88200 &&
270189251Ssam		  dwSampleRate != 96000 )
271189251Ssam	{
272189251Ssam		ECHO_DEBUGPRINTF(
273189251Ssam			("CMia::QueryAudioSampleRate() - rate %ld invalid\n",dwSampleRate) );
274189251Ssam		return ECHOSTATUS_BAD_FORMAT;
275189251Ssam	}
276189251Ssam
277189251Ssam	ECHO_DEBUGPRINTF( ( "CMia::QueryAudioSampleRate()\n" ) );
278189251Ssam	return ECHOSTATUS_OK;
279189251Ssam
280189251Ssam}	// ECHOSTATUS CMia::QueryAudioSampleRate
281189251Ssam
282189251Ssam
283189251Ssamvoid CMia::QuerySampleRateRange(DWORD &dwMinRate,DWORD &dwMaxRate)
284189251Ssam{
285189251Ssam	dwMinRate = 32000;
286189251Ssam	dwMaxRate = 96000;
287189251Ssam}
288189251Ssam
289189251Ssam
290189251Ssam
291189251Ssam//===========================================================================
292189251Ssam//
293189251Ssam// GetInputClockDetect returns a bitmask consisting of all the input
294189251Ssam// clocks currently connected to the hardware; this changes as the user
295189251Ssam// connects and disconnects clock inputs.
296189251Ssam//
297189251Ssam// You should use this information to determine which clocks the user is
298189251Ssam// allowed to select.
299189251Ssam//
300189251Ssam// Mia supports S/PDIF input clock.
301189251Ssam//
302189251Ssam//===========================================================================
303189251Ssam
304189251SsamECHOSTATUS CMia::GetInputClockDetect(DWORD &dwClockDetectBits)
305189251Ssam{
306189251Ssam	//ECHO_DEBUGPRINTF(("CMia::GetInputClockDetect\n"));
307189251Ssam
308189251Ssam	if ( NULL == GetDspCommObject() || GetDspCommObject()->IsBoardBad() )
309189251Ssam	{
310189251Ssam		//ECHO_DEBUGPRINTF( ("CMia::GetInputClockDetect: DSP Dead!\n") );
311189251Ssam		return ECHOSTATUS_DSP_DEAD;
312189251Ssam	}
313189251Ssam
314189251Ssam	//
315189251Ssam	// Map the DSP clock detect bits to the generic driver clock detect bits
316189251Ssam	//
317189251Ssam	DWORD dwClocksFromDsp = GetDspCommObject()->GetInputClockDetect();
318189251Ssam
319189251Ssam	dwClockDetectBits = ECHO_CLOCK_BIT_INTERNAL;
320189251Ssam
321189251Ssam	if (0 != (dwClocksFromDsp & GLDM_CLOCK_DETECT_BIT_SPDIF))
322189251Ssam		dwClockDetectBits |= ECHO_CLOCK_BIT_SPDIF;
323189251Ssam
324189251Ssam	return ECHOSTATUS_OK;
325189251Ssam
326189251Ssam}	// GetInputClockDetect
327189251Ssam
328189251Ssam
329189251Ssam
330189251Ssam// *** Mia.cpp ***
331189251Ssam