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
CGdDspCommObject(PDWORD pdwRegBase,PCOsSupport pOsSupport)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
~CGdDspCommObject()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
RestoreDspSettings()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
SetSampleRate(DWORD dwNewSampleRate)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
SelectGinaDarlaSpdifStatus(DWORD dwNewSampleRate)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
GoComatose()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