1// ****************************************************************************
2//
3//  	CGdDspCommObject.cpp
4//
5//		Implementation file for Gina20/Darla20 DSP interface class.
6//
7//		Darla20 and Gina20 are very similar; this class is used for both.
8//		CGinaDspCommObject and CDarlaDspCommObject dervie from this class, in
9//		turn.
10//
11// ----------------------------------------------------------------------------
12//
13// This file is part of Echo Digital Audio's generic driver library.
14// Copyright Echo Digital Audio Corporation (c) 1998 - 2005
15// All rights reserved
16// www.echoaudio.com
17//
18// This library is free software; you can redistribute it and/or
19// modify it under the terms of the GNU Lesser General Public
20// License as published by the Free Software Foundation; either
21// version 2.1 of the License, or (at your option) any later version.
22//
23// This library is distributed in the hope that it will be useful,
24// but WITHOUT ANY WARRANTY; without even the implied warranty of
25// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
26// Lesser General Public License for more details.
27//
28// You should have received a copy of the GNU Lesser General Public
29// License along with this library; if not, write to the Free Software
30// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
31//
32// ****************************************************************************
33
34#include "CEchoGals.h"
35#include "CGinaDspCommObject.h"
36
37
38/****************************************************************************
39
40	Construction and destruction
41
42 ****************************************************************************/
43
44//===========================================================================
45//
46// Constructor
47//
48//===========================================================================
49
50CGdDspCommObject::CGdDspCommObject
51(
52	PDWORD		pdwRegBase,				// Virtual ptr to DSP registers
53	PCOsSupport	pOsSupport
54) : CDspCommObject( pdwRegBase, pOsSupport )
55{
56
57	m_byGDCurrentSpdifStatus = GD_SPDIF_STATUS_UNDEF;
58	m_byGDCurrentClockState = GD_CLOCK_UNDEF;
59
60}	// CGdDspCommObject::CGinaDspCommObject( DWORD dwPhysRegBase )
61
62
63//===========================================================================
64//
65// Destructor
66//
67//===========================================================================
68
69CGdDspCommObject::~CGdDspCommObject()
70{
71}	// CGdDspCommObject::~CGdDspCommObject()
72
73
74
75
76/****************************************************************************
77
78	Hardware config
79
80 ****************************************************************************/
81
82//===========================================================================
83//
84//	Called after LoadFirmware to restore old gains, meters on, monitors, etc.
85//	No error checking is done here.
86//
87//===========================================================================
88
89void CGdDspCommObject::RestoreDspSettings()
90{
91
92	m_pDspCommPage->byGDClockState = GD_CLOCK_UNDEF;
93	m_pDspCommPage->byGDSpdifStatus = GD_SPDIF_STATUS_UNDEF;
94
95	CDspCommObject::RestoreDspSettings();
96
97}	// void CGdDspCommObject::RestoreDspSettings()
98
99
100//===========================================================================
101//
102// SetSampleRate
103//
104// Set the audio sample rate for Gina/Darla
105//
106// For Gina and Darla, three parameters need to be set: the resampler state,
107// the clock state, and the S/PDIF output status state.  The idea is that
108// these parameters are changed as infrequently as possible.
109//
110// Resampling is no longer supported.
111//
112//===========================================================================
113
114DWORD CGdDspCommObject::SetSampleRate( DWORD dwNewSampleRate )
115{
116	BYTE		byGDClockState, byGDSpdifStatus;
117	DWORD		fUseSpdifInClock;
118
119	if ( !WaitForHandshake() )
120		return ECHOSTATUS_DSP_DEAD;
121
122	//
123	//	Pick the clock
124	//
125	fUseSpdifInClock = (GetCardType() == GINA) &&
126							 (GetInputClock() == ECHO_CLOCK_SPDIF);
127	if (fUseSpdifInClock)
128	{
129		byGDClockState = GD_CLOCK_SPDIFIN;
130	}
131	else
132	{
133		switch (dwNewSampleRate)
134		{
135			case 44100 :
136				byGDClockState = GD_CLOCK_44;
137				break;
138
139			case 48000 :
140				byGDClockState = GD_CLOCK_48;
141				break;
142
143			default :
144				byGDClockState = GD_CLOCK_NOCHANGE;
145				break;
146		}
147	}
148
149	if ( m_byGDCurrentClockState == byGDClockState )
150	{
151		byGDClockState = GD_CLOCK_NOCHANGE;
152	}
153
154	//
155	// Select S/PDIF output status
156	//
157	byGDSpdifStatus = SelectGinaDarlaSpdifStatus( dwNewSampleRate );
158
159	//
160	// Write the audio state to the comm page
161	//
162	m_pDspCommPage->dwSampleRate = SWAP( dwNewSampleRate );
163	m_pDspCommPage->byGDClockState = byGDClockState;
164	m_pDspCommPage->byGDSpdifStatus = byGDSpdifStatus;
165	m_pDspCommPage->byGDResamplerState = 3;				// magic number -
166																		// should always be 3
167
168	//
169	// Send command to DSP
170	//
171	ClearHandshake();
172	SendVector( DSP_VC_SET_GD_AUDIO_STATE );
173
174	//
175	// Save the new audio state
176	//
177	if ( byGDClockState != GD_CLOCK_NOCHANGE )
178		m_byGDCurrentClockState = byGDClockState;
179
180	if ( byGDSpdifStatus != GD_SPDIF_STATUS_NOCHANGE )
181		m_byGDCurrentSpdifStatus = byGDSpdifStatus;
182
183	return dwNewSampleRate;
184
185} // DWORD CGdDspCommObject::SetSampleRate( DWORD dwNewSampleRate )
186
187
188//===========================================================================
189//
190// SelectGinaDarlaSpdifStatus
191//
192//===========================================================================
193
194BYTE CGdDspCommObject::SelectGinaDarlaSpdifStatus( DWORD dwNewSampleRate )
195{
196	BYTE byNewStatus = 0;
197
198	switch (dwNewSampleRate)
199	{
200		case 44100 :
201			byNewStatus = GD_SPDIF_STATUS_44;
202			break;
203
204		case 48000 :
205			byNewStatus = GD_SPDIF_STATUS_48;
206			break;
207
208		default :
209			byNewStatus = GD_SPDIF_STATUS_NOCHANGE;
210			break;
211	}
212
213	if (byNewStatus == m_byGDCurrentSpdifStatus)
214	{
215		byNewStatus = GD_SPDIF_STATUS_NOCHANGE;
216	}
217
218	return byNewStatus;
219
220}	// BYTE CGdDspCommObject::SelectGinaDarlaSpdifStatus( DWORD dwNewSampleRate )
221
222
223
224/****************************************************************************
225
226	Power management
227
228 ****************************************************************************/
229
230//===========================================================================
231//
232// Tell the DSP to go into low-power mode
233//
234//===========================================================================
235
236ECHOSTATUS CGdDspCommObject::GoComatose()
237{
238	ECHO_DEBUGPRINTF(("CGdDspCommObject::GoComatose\n"));
239
240  	m_byGDCurrentClockState = GD_CLOCK_UNDEF;
241  	m_byGDCurrentSpdifStatus = GD_SPDIF_STATUS_UNDEF;
242
243	return CDspCommObject::GoComatose();
244
245}	// end of GoComatose
246
247
248// **** GinaDspCommObject.cpp ****
249