1// ****************************************************************************
2//
3//  	CGMLDspCommObject.cpp
4//
5//		Implementation file for GML cards (Gina24, Mona, and Layla24).
6//
7// ----------------------------------------------------------------------------
8//
9// This file is part of Echo Digital Audio's generic driver library.
10// Copyright Echo Digital Audio Corporation (c) 1998 - 2005
11// All rights reserved
12// www.echoaudio.com
13//
14// This library is free software; you can redistribute it and/or
15// modify it under the terms of the GNU Lesser General Public
16// License as published by the Free Software Foundation; either
17// version 2.1 of the License, or (at your option) any later version.
18//
19// This library is distributed in the hope that it will be useful,
20// but WITHOUT ANY WARRANTY; without even the implied warranty of
21// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22// Lesser General Public License for more details.
23//
24// You should have received a copy of the GNU Lesser General Public
25// License along with this library; if not, write to the Free Software
26// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27//
28// ****************************************************************************
29
30#include "CEchoGals.h"
31#include "CGMLDspCommObject.h"
32
33//===========================================================================
34//
35// Set the S/PDIF output format
36//
37//===========================================================================
38
39void CGMLDspCommObject::SetProfessionalSpdif
40(
41	BOOL bNewStatus
42)
43{
44	DWORD		dwControlReg;
45
46	dwControlReg = GetControlRegister();
47
48	//
49	// Clear the current S/PDIF flags
50	//
51	dwControlReg &= GML_SPDIF_FORMAT_CLEAR_MASK;
52
53	//
54	// Set the new S/PDIF flags depending on the mode
55	//
56	dwControlReg |= 	GML_SPDIF_TWO_CHANNEL |
57							GML_SPDIF_24_BIT |
58							GML_SPDIF_COPY_PERMIT;
59	if ( bNewStatus )
60	{
61		//
62		// Professional mode
63		//
64		dwControlReg |= GML_SPDIF_PRO_MODE;
65
66		switch ( GetSampleRate() )
67		{
68			case 32000 :
69				dwControlReg |= GML_SPDIF_SAMPLE_RATE0 |
70									 GML_SPDIF_SAMPLE_RATE1;
71				break;
72
73			case 44100 :
74				dwControlReg |= GML_SPDIF_SAMPLE_RATE0;
75				break;
76
77			case 48000 :
78				dwControlReg |= GML_SPDIF_SAMPLE_RATE1;
79				break;
80		}
81	}
82	else
83	{
84		//
85		// Consumer mode
86		//
87		switch ( GetSampleRate() )
88		{
89			case 32000 :
90				dwControlReg |= GML_SPDIF_SAMPLE_RATE0 |
91									 GML_SPDIF_SAMPLE_RATE1;
92				break;
93
94			case 48000 :
95				dwControlReg |= GML_SPDIF_SAMPLE_RATE1;
96				break;
97		}
98	}
99
100	//
101	// Handle the non-audio bit
102	//
103	if (m_bNonAudio)
104		dwControlReg |= GML_SPDIF_NOT_AUDIO;
105
106	//
107	// Write the control reg
108	//
109	WriteControlReg( dwControlReg );
110
111	m_bProfessionalSpdif = bNewStatus;
112
113	ECHO_DEBUGPRINTF( ("CGMLDspCommObject::SetProfessionalSpdif to %s\n",
114							( bNewStatus ) ? "Professional" : "Consumer") );
115
116}	// void CGMLDspCommObject::SetProfessionalSpdif( ... )
117
118
119
120
121//===========================================================================
122//
123// SetSpdifOutNonAudio
124//
125// Set the state of the non-audio status bit in the S/PDIF out status bits
126//
127//===========================================================================
128
129void CGMLDspCommObject::SetSpdifOutNonAudio(BOOL bNonAudio)
130{
131	DWORD		dwControlReg;
132
133	dwControlReg = GetControlRegister();
134	if (bNonAudio)
135	{
136		dwControlReg |= GML_SPDIF_NOT_AUDIO;
137	}
138	else
139	{
140		dwControlReg &= ~GML_SPDIF_NOT_AUDIO;
141	}
142
143	m_bNonAudio = bNonAudio;
144
145	WriteControlReg( dwControlReg );
146}
147
148
149
150//===========================================================================
151//
152// WriteControlReg
153//
154// Most configuration of Gina24, Layla24, or Mona is
155// accomplished by writing the control register.  WriteControlReg
156// sends the new control register value to the DSP.
157//
158//===========================================================================
159
160ECHOSTATUS CGMLDspCommObject::WriteControlReg
161(
162	DWORD dwControlReg,
163	BOOL 	fForceWrite
164)
165{
166	ECHO_DEBUGPRINTF(("CGMLDspCommObject::WriteControlReg 0x%lx\n",dwControlReg));
167
168	if ( !m_bASICLoaded )
169	{
170		ECHO_DEBUGPRINTF(("CGMLDspCommObject::WriteControlReg - ASIC not loaded\n"));
171		return( ECHOSTATUS_ASIC_NOT_LOADED );
172	}
173
174
175	if ( !WaitForHandshake() )
176	{
177		ECHO_DEBUGPRINTF(("CGMLDspCommObject::WriteControlReg - no handshake\n"));
178		return ECHOSTATUS_DSP_DEAD;
179	}
180
181#ifdef DIGITAL_INPUT_AUTO_MUTE_SUPPORT
182	//
183	// Handle the digital input auto-mute
184	//
185	if (TRUE == m_fDigitalInAutoMute)
186		dwControlReg |= GML_DIGITAL_IN_AUTO_MUTE;
187	else
188		dwControlReg &= ~GML_DIGITAL_IN_AUTO_MUTE;
189#endif
190
191	//
192	// Write the control register
193	//
194	if (fForceWrite || (dwControlReg != GetControlRegister()) )
195	{
196		SetControlRegister( dwControlReg );
197
198		ECHO_DEBUGPRINTF( ("CGMLDspCommObject::WriteControlReg: Setting 0x%lx\n",
199								 dwControlReg) );
200
201		ClearHandshake();
202		return SendVector( DSP_VC_WRITE_CONTROL_REG );
203	}
204	else
205	{
206		ECHO_DEBUGPRINTF( ("CGMLDspCommObject::WriteControlReg: control reg is already 0x%lx\n",
207								 dwControlReg) );
208	}
209
210	return ECHOSTATUS_OK;
211
212} // ECHOSTATUS CGMLDspCommObject::WriteControlReg( DWORD dwControlReg )
213
214//===========================================================================
215//
216// SetDigitalMode
217//
218//===========================================================================
219
220ECHOSTATUS CGMLDspCommObject::SetDigitalMode
221(
222	BYTE	byNewMode
223)
224{
225	WORD		wInvalidClock;
226
227	//
228	// See if the current input clock doesn't match the new digital mode
229	//
230	switch (byNewMode)
231	{
232		case DIGITAL_MODE_SPDIF_RCA :
233		case DIGITAL_MODE_SPDIF_OPTICAL :
234			wInvalidClock = ECHO_CLOCK_ADAT;
235			break;
236
237		case DIGITAL_MODE_ADAT :
238			wInvalidClock = ECHO_CLOCK_SPDIF;
239			break;
240
241		default :
242			wInvalidClock = 0xffff;
243			break;
244	}
245
246	if (wInvalidClock == GetInputClock())
247	{
248		SetInputClock( ECHO_CLOCK_INTERNAL );
249		SetSampleRate( 48000 );
250	}
251
252	//
253	// Clear the current digital mode
254	//
255	DWORD dwControlReg;
256
257	dwControlReg = GetControlRegister();
258	dwControlReg &= GML_DIGITAL_MODE_CLEAR_MASK;
259
260	//
261	// Tweak the control reg
262	//
263	switch ( byNewMode )
264	{
265		case DIGITAL_MODE_SPDIF_RCA :
266			break;
267
268		case DIGITAL_MODE_SPDIF_OPTICAL :
269			dwControlReg |= GML_SPDIF_OPTICAL_MODE;
270			break;
271
272		case DIGITAL_MODE_ADAT :
273			dwControlReg |= GML_ADAT_MODE;
274			dwControlReg &= ~GML_DOUBLE_SPEED_MODE;
275			break;
276
277		default :
278			return ECHOSTATUS_DIGITAL_MODE_NOT_SUPPORTED;
279	}
280
281	//
282	// Write the control reg
283	//
284	WriteControlReg( dwControlReg );
285
286	m_byDigitalMode = byNewMode;
287
288	ECHO_DEBUGPRINTF( ("CGMLDspCommObject::SetDigitalMode to %ld\n",
289							(DWORD) m_byDigitalMode) );
290
291	return ECHOSTATUS_OK;
292
293}	// ECHOSTATUS CGMLDspCommObject::SetDigitalMode
294
295
296// **** CGMLDspCommObject.cpp ****
297