xref: /haiku/src/add-ons/kernel/drivers/audio/echo/generic/CGdDspCommObject.cpp (revision d5cd5d63ff0ad395989db6cf4841a64d5b545d1d)
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 //		Copyright Echo Digital Audio Corporation (c) 1998 - 2002
12 //		All rights reserved
13 //		www.echoaudio.com
14 //
15 //		Permission is hereby granted, free of charge, to any person obtaining a
16 //		copy of this software and associated documentation files (the
17 //		"Software"), to deal with the Software without restriction, including
18 //		without limitation the rights to use, copy, modify, merge, publish,
19 //		distribute, sublicense, and/or sell copies of the Software, and to
20 //		permit persons to whom the Software is furnished to do so, subject to
21 //		the following conditions:
22 //
23 //		- Redistributions of source code must retain the above copyright
24 //		notice, this list of conditions and the following disclaimers.
25 //
26 //		- Redistributions in binary form must reproduce the above copyright
27 //		notice, this list of conditions and the following disclaimers in the
28 //		documentation and/or other materials provided with the distribution.
29 //
30 //		- Neither the name of Echo Digital Audio, nor the names of its
31 //		contributors may be used to endorse or promote products derived from
32 //		this Software without specific prior written permission.
33 //
34 //		THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
35 //		EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
36 //		MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
37 //		IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
38 //		ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
39 //		TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
40 //		SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
41 //
42 // ****************************************************************************
43 
44 #include "CEchoGals.h"
45 #include "CGinaDspCommObject.h"
46 
47 
48 /****************************************************************************
49 
50 	Construction and destruction
51 
52  ****************************************************************************/
53 
54 //===========================================================================
55 //
56 // Constructor
57 //
58 //===========================================================================
59 
60 CGdDspCommObject::CGdDspCommObject
61 (
62 	PDWORD		pdwRegBase,				// Virtual ptr to DSP registers
63 	PCOsSupport	pOsSupport
64 ) : CDspCommObject( pdwRegBase, pOsSupport )
65 {
66 	m_byGDCurrentSpdifStatus = GD_SPDIF_STATUS_UNDEF;
67 	m_byGDCurrentClockState = GD_CLOCK_UNDEF;
68 }	// CGdDspCommObject::CGinaDspCommObject( DWORD dwPhysRegBase )
69 
70 
71 //===========================================================================
72 //
73 // Destructor
74 //
75 //===========================================================================
76 
77 CGdDspCommObject::~CGdDspCommObject()
78 {
79 }	// CGdDspCommObject::~CGdDspCommObject()
80 
81 
82 
83 
84 /****************************************************************************
85 
86 	Hardware config
87 
88  ****************************************************************************/
89 
90 //===========================================================================
91 //
92 //	Called after LoadFirmware to restore old gains, meters on, monitors, etc.
93 //	No error checking is done here.
94 //
95 //===========================================================================
96 
97 void CGdDspCommObject::RestoreDspSettings()
98 {
99 
100 	m_pDspCommPage->byGDClockState = GD_CLOCK_UNDEF;
101 	m_pDspCommPage->byGDSpdifStatus = GD_SPDIF_STATUS_UNDEF;
102 	CDspCommObject::RestoreDspSettings();
103 
104 }	// void CLaylaDspCommObject::RestoreDspSettings()
105 
106 
107 //===========================================================================
108 //
109 // SetSampleRate
110 //
111 // Set the audio sample rate for Gina/Darla
112 //
113 // For Gina and Darla, three parameters need to be set: the resampler state,
114 // the clock state, and the S/PDIF output status state.  The idea is that
115 // these parameters are changed as infrequently as possible.
116 //
117 // Resampling is no longer supported.
118 //
119 //===========================================================================
120 
121 DWORD CGdDspCommObject::SetSampleRate( DWORD dwNewSampleRate )
122 {
123 	BYTE		byGDClockState, byGDSpdifStatus;
124 	DWORD		fUseSpdifInClock;
125 
126 	if ( !WaitForHandshake() )
127 		return ECHOSTATUS_DSP_DEAD;
128 
129 	//
130 	//	Pick the clock
131 	//
132 	fUseSpdifInClock = (GetCardType() == GINA) &&
133 							 (GetInputClock() == ECHO_CLOCK_SPDIF);
134 	if (fUseSpdifInClock)
135 	{
136 		byGDClockState = GD_CLOCK_SPDIFIN;
137 	}
138 	else
139 	{
140 		switch (dwNewSampleRate)
141 		{
142 			case 44100 :
143 				byGDClockState = GD_CLOCK_44;
144 				break;
145 
146 			case 48000 :
147 				byGDClockState = GD_CLOCK_48;
148 				break;
149 
150 			default :
151 				byGDClockState = GD_CLOCK_NOCHANGE;
152 				break;
153 		}
154 	}
155 
156 	if ( m_byGDCurrentClockState == byGDClockState )
157 	{
158 		byGDClockState = GD_CLOCK_NOCHANGE;
159 	}
160 
161 	//
162 	// Select S/PDIF output status
163 	//
164 	byGDSpdifStatus = SelectGinaDarlaSpdifStatus( dwNewSampleRate );
165 
166 	//
167 	// Write the audio state to the comm page
168 	//
169 	m_pDspCommPage->dwSampleRate = SWAP( dwNewSampleRate );
170 	m_pDspCommPage->byGDClockState = byGDClockState;
171 	m_pDspCommPage->byGDSpdifStatus = byGDSpdifStatus;
172 	m_pDspCommPage->byGDResamplerState = 3;				// magic number -
173 																		// should always be 3
174 
175 	//
176 	// Send command to DSP
177 	//
178 	ClearHandshake();
179 	SendVector( DSP_VC_SET_GD_AUDIO_STATE );
180 
181 	//
182 	// Save the new audio state
183 	//
184 	if ( byGDClockState != GD_CLOCK_NOCHANGE )
185 		m_byGDCurrentClockState = byGDClockState;
186 
187 	if ( byGDSpdifStatus != GD_SPDIF_STATUS_NOCHANGE )
188 		m_byGDCurrentSpdifStatus = byGDSpdifStatus;
189 
190 	return dwNewSampleRate;
191 
192 } // DWORD CGdDspCommObject::SetSampleRate( DWORD dwNewSampleRate )
193 
194 
195 //===========================================================================
196 //
197 // SelectGinaDarlaSpdifStatus
198 //
199 //===========================================================================
200 
201 BYTE CGdDspCommObject::SelectGinaDarlaSpdifStatus( DWORD dwNewSampleRate )
202 {
203 	BYTE byNewStatus = 0;
204 
205 	switch (dwNewSampleRate)
206 	{
207 		case 44100 :
208 			byNewStatus = GD_SPDIF_STATUS_44;
209 			break;
210 
211 		case 48000 :
212 			byNewStatus = GD_SPDIF_STATUS_48;
213 			break;
214 
215 		default :
216 			byNewStatus = GD_SPDIF_STATUS_NOCHANGE;
217 			break;
218 	}
219 
220 	if (byNewStatus == m_byGDCurrentSpdifStatus)
221 	{
222 		byNewStatus = GD_SPDIF_STATUS_NOCHANGE;
223 	}
224 
225 	return byNewStatus;
226 
227 }	// BYTE CGdDspCommObject::SelectGinaDarlaSpdifStatus( DWORD dwNewSampleRate )
228 
229 // **** GinaDspCommObject.cpp ****
230