xref: /haiku/src/add-ons/kernel/drivers/audio/echo/generic/CMia.cpp (revision 51978af14a173e7fae0563b562be5603bc652aeb)
1 // ****************************************************************************
2 //
3 //		CMia.cpp
4 //
5 //		Implementation file for the CMia driver class.
6 //		Set editor tabs to 3 for your viewing pleasure.
7 //
8 //		Copyright Echo Digital Audio Corporation (c) 1998 - 2002
9 //		All rights reserved
10 //		www.echoaudio.com
11 //
12 //		Permission is hereby granted, free of charge, to any person obtaining a
13 //		copy of this software and associated documentation files (the
14 //		"Software"), to deal with the Software without restriction, including
15 //		without limitation the rights to use, copy, modify, merge, publish,
16 //		distribute, sublicense, and/or sell copies of the Software, and to
17 //		permit persons to whom the Software is furnished to do so, subject to
18 //		the following conditions:
19 //
20 //		- Redistributions of source code must retain the above copyright
21 //		notice, this list of conditions and the following disclaimers.
22 //
23 //		- Redistributions in binary form must reproduce the above copyright
24 //		notice, this list of conditions and the following disclaimers in the
25 //		documentation and/or other materials provided with the distribution.
26 //
27 //		- Neither the name of Echo Digital Audio, nor the names of its
28 //		contributors may be used to endorse or promote products derived from
29 //		this Software without specific prior written permission.
30 //
31 //		THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32 //		EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33 //		MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
34 //		IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
35 //		ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
36 //		TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
37 //		SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
38 //
39 // ****************************************************************************
40 
41 #include "CMia.h"
42 
43 
44 /****************************************************************************
45 
46 	Construction and destruction
47 
48  ****************************************************************************/
49 
50 //===========================================================================
51 //
52 // Overload new & delete so memory for this object is allocated
53 //	from non-paged memory.
54 //
55 //===========================================================================
56 
57 PVOID CMia::operator new( size_t Size )
58 {
59 	PVOID 		pMemory;
60 	ECHOSTATUS 	Status;
61 
62 	Status = OsAllocateNonPaged(Size,&pMemory);
63 
64 	if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory ))
65 	{
66 		ECHO_DEBUGPRINTF(("CMia::operator new - memory allocation failed\n"));
67 
68 		pMemory = NULL;
69 	}
70 	else
71 	{
72 		memset( pMemory, 0, Size );
73 	}
74 
75 	return pMemory;
76 
77 }	// PVOID CMia::operator new( size_t Size )
78 
79 
80 VOID  CMia::operator delete( PVOID pVoid )
81 {
82 	if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) )
83 	{
84 		ECHO_DEBUGPRINTF(("CMia::operator delete memory free failed\n"));
85 	}
86 }	// VOID CMia::operator delete( PVOID pVoid )
87 
88 
89 //===========================================================================
90 //
91 // Constructor and destructor
92 //
93 //===========================================================================
94 
95 CMia::CMia( PCOsSupport pOsSupport )
96 	  : CEchoGals( pOsSupport )
97 {
98 	ECHO_DEBUGPRINTF( ( "CMia::CMia() is born!\n" ) );
99 }
100 
101 CMia::~CMia()
102 {
103 	ECHO_DEBUGPRINTF( ( "CMia::~CMia() is toast!\n" ) );
104 }
105 
106 
107 
108 
109 /****************************************************************************
110 
111 	Setup and hardware initialization
112 
113  ****************************************************************************/
114 
115 //===========================================================================
116 //
117 // Every card has an InitHw method
118 //
119 //===========================================================================
120 
121 ECHOSTATUS CMia::InitHw()
122 {
123 	ECHOSTATUS	Status;
124 	WORD			i;
125 
126 	//
127 	// Call the base method
128 	//
129 	if ( ECHOSTATUS_OK != ( Status = CEchoGals::InitHw() ) )
130 		return Status;
131 
132 	//
133 	// Create the DSP comm object
134 	//
135 	ASSERT( NULL == m_pDspCommObject );
136 	m_pDspCommObject = new CMiaDspCommObject( (PDWORD) m_pvSharedMemory,
137 															 m_pOsSupport );
138 	if (NULL == m_pDspCommObject)
139 	{
140 		ECHO_DEBUGPRINTF(("CMia::InitHw - could not create DSP comm object\n"));
141 		return ECHOSTATUS_NO_MEM;
142 	}
143 
144 	//
145 	// Load the DSP
146 	//
147 	GetDspCommObject()->LoadFirmware();
148 	if ( GetDspCommObject()->IsBoardBad() )
149 		return ECHOSTATUS_DSP_DEAD;
150 
151 	//
152 	// Clear the "bad board" flag; set the flags to indicate that
153 	// Mia can handle super-interleave.
154 	//
155 	m_wFlags &= ~ECHOGALS_FLAG_BADBOARD;
156 	m_wFlags |= ECHOGALS_ROFLAG_SUPER_INTERLEAVE_OK;
157 
158 	//
159 	//	Must call this here after DSP is init to
160 	//	init gains and mutes
161 	//
162 	Status = InitLineLevels();
163 	if ( ECHOSTATUS_OK != Status )
164 		return Status;
165 
166 	//
167 	// Set defaults for +4/-10
168 	//
169 	for (i = 0; i < GetFirstDigitalBusOut(); i++ )
170 	{
171 		GetDspCommObject()->
172 			SetNominalLevel( i, FALSE );	// FALSE is +4 here
173 	}
174 	for ( i = 0; i < GetFirstDigitalBusIn(); i++ )
175 	{
176 		GetDspCommObject()->
177 			SetNominalLevel( GetNumBussesOut() + i, FALSE );
178 	}
179 
180 	//
181 	// Set the digital mode to S/PDIF RCA
182 	//
183 	SetDigitalMode( DIGITAL_MODE_SPDIF_RCA );
184 
185 	//
186 	//	Get default sample rate from DSP
187 	//
188 	m_dwSampleRate = GetDspCommObject()->GetSampleRate();
189 
190 	ECHO_DEBUGPRINTF( ( "CMia::InitHw()\n" ) );
191 	return Status;
192 
193 }	// ECHOSTATUS CMia::InitHw()
194 
195 
196 
197 
198 /****************************************************************************
199 
200 	Informational methods
201 
202  ****************************************************************************/
203 
204 //===========================================================================
205 //
206 // Override GetCapabilities to enumerate unique capabilties for this card
207 //
208 //===========================================================================
209 
210 ECHOSTATUS CMia::GetCapabilities
211 (
212 	PECHOGALS_CAPS	pCapabilities
213 )
214 {
215 	ECHOSTATUS	Status;
216 	WORD			i;
217 
218 	Status = GetBaseCapabilities(pCapabilities);
219 	if ( ECHOSTATUS_OK != Status )
220 		return Status;
221 
222 	//
223 	// Add meters & pans to output pipes
224 	//
225 	for (i = 0 ; i < GetNumPipesOut(); i++)
226 	{
227 		pCapabilities->dwPipeOutCaps[i] |= ECHOCAPS_PEAK_METER |
228 														ECHOCAPS_PAN;
229 	}
230 
231 	//
232 	// Add nominal level control to analog ins & outs
233 	//
234 	for (i = 0 ; i < GetFirstDigitalBusOut(); i++)
235 	{
236 		pCapabilities->dwBusOutCaps[i] |= ECHOCAPS_NOMINAL_LEVEL;
237 	}
238 
239 	for (i = 0 ; i < GetFirstDigitalBusIn(); i++)
240 	{
241 		pCapabilities->dwBusInCaps[i] |= ECHOCAPS_NOMINAL_LEVEL;
242 	}
243 
244 	pCapabilities->dwInClockTypes |= ECHO_CLOCK_BIT_SPDIF;
245 	pCapabilities->dwOutClockTypes = 0;
246 
247 	return Status;
248 
249 }	// ECHOSTATUS CMia::GetCapabilities
250 
251 
252 //===========================================================================
253 //
254 // QueryAudioSampleRate is used to find out if this card can handle a
255 // given sample rate.
256 //
257 //===========================================================================
258 
259 ECHOSTATUS CMia::QueryAudioSampleRate
260 (
261 	DWORD		dwSampleRate
262 )
263 {
264 	if ( dwSampleRate !=  8000 &&
265 		  dwSampleRate != 11025 &&
266 		  dwSampleRate != 12000 &&
267 		  dwSampleRate != 16000 &&
268 		  dwSampleRate != 22050 &&
269 		  dwSampleRate != 24000 &&
270 		  dwSampleRate != 32000 &&
271 		  dwSampleRate != 44100 &&
272 		  dwSampleRate != 48000 &&
273 		  dwSampleRate != 88200 &&
274 		  dwSampleRate != 96000 )
275 	{
276 		ECHO_DEBUGPRINTF(
277 			("CMia::QueryAudioSampleRate() Sample rate must be "
278 			 " 8,000 Hz, 11,025 Hz, 12,000 Hz, 16,000 Hz, 22,050 Hz, "
279 			 "24,000 Hz, 32,000 Hz, 44,100 Hz, 48,000 Hz, 88,200 Hz "
280 			 "or 96,000 Hz\n") );
281 		return ECHOSTATUS_BAD_FORMAT;
282 	}
283 
284 	ECHO_DEBUGPRINTF( ( "CMia::QueryAudioSampleRate()\n" ) );
285 	return ECHOSTATUS_OK;
286 
287 }	// ECHOSTATUS CMia::QueryAudioSampleRate
288 
289 
290 //===========================================================================
291 //
292 // GetInputClockDetect returns a bitmask consisting of all the input
293 // clocks currently connected to the hardware; this changes as the user
294 // connects and disconnects clock inputs.
295 //
296 // You should use this information to determine which clocks the user is
297 // allowed to select.
298 //
299 // Mia supports S/PDIF input clock.
300 //
301 //===========================================================================
302 
303 ECHOSTATUS CMia::GetInputClockDetect(DWORD &dwClockDetectBits)
304 {
305 	ECHO_DEBUGPRINTF(("CMia::GetInputClockDetect\n"));
306 
307 	if ( NULL == GetDspCommObject() || GetDspCommObject()->IsBoardBad() )
308 	{
309 		ECHO_DEBUGPRINTF( ("CMia::GetInputClockDetect: DSP Dead!\n") );
310 		return ECHOSTATUS_DSP_DEAD;
311 	}
312 
313 	//
314 	// Map the DSP clock detect bits to the generic driver clock detect bits
315 	//
316 	DWORD dwClocksFromDsp = GetDspCommObject()->GetInputClockDetect();
317 
318 	dwClockDetectBits = ECHO_CLOCK_BIT_INTERNAL;
319 
320 	if (0 != (dwClocksFromDsp & GLDM_CLOCK_DETECT_BIT_SPDIF))
321 		dwClockDetectBits |= ECHO_CLOCK_BIT_SPDIF;
322 
323 	return ECHOSTATUS_OK;
324 
325 }	// GetInputClockDetect
326 
327 
328 //===========================================================================
329 //
330 // Most of the cards don't have an actual output bus gain; they only
331 // have gain controls for output pipes; the output bus gain is implemented
332 // as a logical control.  Mia (and any other card with a vmixer) works
333 // differently; it does have a physical output bus gain control, so
334 // just pass the gain down to the DSP comm object.
335 //
336 //===========================================================================
337 
338 ECHOSTATUS CMia::AdjustPipesOutForBusOut(WORD wBusOut,int iBusOutGain)
339 {
340 
341 	GetDspCommObject()->SetBusOutGain(wBusOut,iBusOutGain);
342 
343 	return ECHOSTATUS_OK;
344 
345 }	// AdjustPipesOutForBusOut
346 
347 
348 // *** Mia.cpp ***
349