xref: /haiku/src/add-ons/kernel/drivers/audio/echo/generic/CGdDspCommObject.cpp (revision 1deede7388b04dbeec5af85cae7164735ea9e70d)
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 
50 CGdDspCommObject::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 
69 CGdDspCommObject::~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 
89 void 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 
114 DWORD 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 
194 BYTE 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 
236 ECHOSTATUS 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