xref: /haiku/src/add-ons/kernel/drivers/audio/echo/generic/CChannelMask.cpp (revision 93aeb8c3bc3f13cb1f282e3e749258a23790d947)
1 // ****************************************************************************
2 //
3 //		CChannelMask.cpp
4 //
5 //		Implementation file for the CChannelMask class.
6 //
7 // 	CChannelMask is a handy way to specify a group of pipes simultaneously.
8 //		It should really be called "CPipeMask", but the class name predates
9 //		the term "pipe".
10 //
11 // 	Since these masks are sometimes passed to the DSP, they must be kept in
12 //	 	little-endian format; the class does this for you.
13 //
14 // ----------------------------------------------------------------------------
15 //
16 // This file is part of Echo Digital Audio's generic driver library.
17 // Copyright Echo Digital Audio Corporation (c) 1998 - 2005
18 // All rights reserved
19 // www.echoaudio.com
20 //
21 // This library is free software; you can redistribute it and/or
22 // modify it under the terms of the GNU Lesser General Public
23 // License as published by the Free Software Foundation; either
24 // version 2.1 of the License, or (at your option) any later version.
25 //
26 // This library is distributed in the hope that it will be useful,
27 // but WITHOUT ANY WARRANTY; without even the implied warranty of
28 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
29 // Lesser General Public License for more details.
30 //
31 // You should have received a copy of the GNU Lesser General Public
32 // License along with this library; if not, write to the Free Software
33 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
34 //
35 // ****************************************************************************
36 
37 #include "CEchoGals.h"
38 
39 
40 /****************************************************************************
41 
42 	CChannelMask
43 
44  ****************************************************************************/
45 
46 //===========================================================================
47 //
48 // Constructor
49 //
50 //===========================================================================
51 
52 CChannelMask::CChannelMask()
53 {
54 
55 	Clear();
56 
57 }	// CChannelMask::CChannelMask()
58 
59 
60 //===========================================================================
61 //
62 //	SetMask, SetOutMask, and SetInMask all allow you to just set
63 // the masks directly.
64 //
65 //===========================================================================
66 
67 void CChannelMask::SetMask( CH_MASK OutMask, CH_MASK InMask, int nOutputs )
68 {
69 
70 	m_Mask = OutMask;
71 	m_Mask |= InMask << nOutputs;
72 
73 }	// void CChannelMask::SetMask( ... )
74 
75 
76 void CChannelMask::SetOutMask( CH_MASK OutMask, int nOutputs )
77 {
78 
79 	m_Mask &= ((CH_MASK) -1) << nOutputs;
80 	m_Mask |= OutMask;
81 
82 }	// void CChannelMask::SetOutMask( CH_MASK OutMask, int nOutputs )
83 
84 
85 void CChannelMask::SetInMask( CH_MASK InMask, int nOutputs )
86 {
87 	m_Mask &= ~( (CH_MASK) -1 << nOutputs );
88 	m_Mask |= InMask << nOutputs;
89 }	// void CChannelMask::SetInMask( CH_MASK InMask, int nOutputs )
90 
91 
92 //===========================================================================
93 //
94 //	Retrieve an output bit mask and an input bitmask.
95 //
96 //===========================================================================
97 
98 void CChannelMask::GetMask( CH_MASK & OutMask, CH_MASK & InMask, int nOutputs )
99 {
100 	OutMask = GetOutMask( nOutputs );
101 	InMask = GetInMask( nOutputs );
102 }	// void CChannelMask::GetMask( ... )
103 
104 CH_MASK CChannelMask::GetOutMask( int nOutputs )
105 {
106 	return  m_Mask & ~( (CH_MASK) -1 << nOutputs );
107 }	// CH_MASK CChannelMask::GetOutMask( int nOutputs )
108 
109 CH_MASK CChannelMask::GetInMask( int nOutputs )
110 {
111 	return  m_Mask >> nOutputs;
112 }	// CH_MASK CChannelMask::GetIntMask( int nOutputs )
113 
114 
115 //===========================================================================
116 //
117 // IsEmpty returns TRUE if mask has no bits set
118 //
119 //===========================================================================
120 
121 BOOL CChannelMask::IsEmpty()
122 {
123 	if (0 != m_Mask)
124 		return FALSE;
125 
126 	return TRUE;
127 
128 }	// void CChannelMask::IsEmpty()
129 
130 
131 //===========================================================================
132 //
133 // Call SetIndexInMask and ClearIndexInMask to set or clear a single bit.
134 //
135 //===========================================================================
136 
137 // Set driver channel index into DSP mask format
138 void CChannelMask::SetIndexInMask( WORD wPipeIndex )
139 {
140 	m_Mask |= 1 << wPipeIndex;
141 
142 }	// void CChannelMask::SetIndexInMask( WORD wPipeIndex )
143 
144 
145 // Clear driver channel index into DSP mask format
146 void CChannelMask::ClearIndexInMask( WORD wPipeIndex )
147 {
148 
149 	m_Mask &= ~((CH_MASK) 1 << wPipeIndex);
150 
151 }	// void CChannelMask::ClearIndexInMask( WORD wPipeIndex )
152 
153 
154 //===========================================================================
155 //
156 // Use GetIndexFromMask	to search the mask for bits that are set.
157 //
158 // The search starts at the bit specified by wStartPipeIndex and returns
159 // the pipe index for the first non-zero bit found.
160 //
161 //	Returns ECHO_INVALID_CHANNEL if none are found.
162 //
163 //===========================================================================
164 
165 WORD CChannelMask::GetIndexFromMask( WORD wStartPipeIndex )
166 {
167 	CH_MASK bit;
168 	WORD index;
169 
170 	bit = 1 << wStartPipeIndex;
171 	index = wStartPipeIndex;
172 	while (bit != 0)
173 	{
174 		if (0 != (m_Mask & bit))
175 			return index;
176 
177 		bit <<= 1;
178 		index++;
179 	}
180 
181 	return( (WORD) ECHO_INVALID_CHANNEL );
182 
183 }		// WORD CChannelMask::GetIndexFromMask( WORD wStartIndex )
184 
185 
186 //===========================================================================
187 //
188 // Returns TRUE if the bit specified by the pipe index is set.
189 //
190 //===========================================================================
191 
192 BOOL CChannelMask::TestIndexInMask( WORD wPipeIndex )
193 {
194 	if (0 != (m_Mask & ((CH_MASK) 1 << wPipeIndex)))
195 		return TRUE;
196 
197 	return FALSE;
198 }	// BOOL CChannelMask::TestIndexInMask( WORD wPipeIndex )
199 
200 
201 //===========================================================================
202 //
203 // Clear bits in this mask that are in SrcMask - this is just like
204 // operator -=, below.
205 //
206 //===========================================================================
207 
208 void CChannelMask::ClearMask( CChannelMask SrcMask )
209 {
210 	m_Mask &= ~SrcMask.m_Mask;
211 
212 }	// void CChannelMask::ClearMask( CChannelMask SrcMask )
213 
214 
215 //===========================================================================
216 //
217 //	Clear all channels in this mask
218 //
219 //===========================================================================
220 
221 void CChannelMask::Clear()
222 {
223 	m_Mask = 0;
224 }	// void CChannelMask::Clear()
225 
226 
227 //===========================================================================
228 //
229 //	operator +=    Add channels in source mask to this mask
230 //
231 //===========================================================================
232 
233 VOID CChannelMask::operator += (CONST CChannelMask & RVal)
234 {
235 	m_Mask |= RVal.m_Mask;
236 
237 }	// VOID operator += (CONST CChannelMask & RVal)
238 
239 
240 //===========================================================================
241 //
242 //	operator -=    Remove channels in source mask from this mask
243 //
244 //===========================================================================
245 
246 VOID CChannelMask::operator -= (CONST CChannelMask & RVal)
247 {
248 	ClearMask(RVal);
249 }	// VOID operator -= (CONST CChannelMask & RVal)
250 
251 
252 //===========================================================================
253 //
254 // Test returns TRUE if any bits in source mask are set in this mask
255 //
256 //===========================================================================
257 
258 BOOL CChannelMask::Test( PCChannelMask pSrcMask )
259 {
260 	if (0 != (m_Mask & pSrcMask->m_Mask))
261 		return TRUE;
262 
263 	return FALSE;
264 
265 }	// BOOL CChannelMask::Test( PChannelMask pSrcMask )
266 
267 
268 //===========================================================================
269 //
270 //	IsSubsetOf returns TRUE if all of the channels in TstMask are set in
271 // m_Mask.
272 //
273 //	Use to be sure all channels in this instance exist in
274 //	another instance.
275 //
276 //===========================================================================
277 
278 BOOL CChannelMask::IsSubsetOf
279 (
280 	CChannelMask& TstMask
281 )
282 {
283 	if ((m_Mask & TstMask.m_Mask) != TstMask.m_Mask)
284 		return FALSE;
285 
286 	return TRUE;
287 
288 }	// BOOL CChannelMask::IsSubsetOf
289 
290 
291 //===========================================================================
292 //
293 //	IsIntersectionOf returns TRUE if TstMask contains at least one of the
294 // channels enabled in this instance.
295 //
296 //	Use this to find out if any channels in this instance exist in
297 //	another instance.
298 //
299 //===========================================================================
300 
301 BOOL CChannelMask::IsIntersectionOf
302 (
303 	CChannelMask& TstMask
304 )
305 {
306 	if (0 != (m_Mask & TstMask.m_Mask))
307 		return TRUE;
308 
309 	return FALSE;
310 
311 }	// BOOL CChannelMask::IsIntersectionOf
312 
313 
314 //===========================================================================
315 //
316 // Operator == is just what you'd expect - it tells you if one mask is
317 // the same as another
318 //
319 //===========================================================================
320 
321 BOOLEAN operator == ( CONST CChannelMask &LVal, CONST CChannelMask &RVal )
322 {
323 	if (LVal.m_Mask != RVal.m_Mask)
324 		return FALSE;
325 
326 	return TRUE;
327 
328 }	// BOOLEAN operator == ( CONST CChannelMask &LVal, CONST CChannelMask &RVal )
329 
330 
331 //===========================================================================
332 //
333 // Operator = just copies from one mask to another.
334 //
335 //===========================================================================
336 
337 CChannelMask& CChannelMask::operator =(CONST CChannelMask & RVal)
338 {
339 	if ( &RVal == this )
340 		return *this;
341 
342 	m_Mask = RVal.m_Mask;
343 
344 	return *this;
345 
346 }	// CChannelMask& CChannelMask::operator = (CONTS CChannelMask & RVal)
347 
348 
349 //===========================================================================
350 //
351 // Operator & performs a bitwise logical AND
352 //
353 //===========================================================================
354 
355 VOID CChannelMask::operator &= (CONST CChannelMask & RVal)
356 {
357 	if ( &RVal == this )
358 		return;
359 
360 	m_Mask &= RVal.m_Mask;
361 
362 }	// VOID CChannelMask::operator &= (CONST CChannelMask & RVal)
363 
364 
365 //===========================================================================
366 //
367 // Operator & performs a bitwise logical OR
368 //
369 //===========================================================================
370 
371 VOID CChannelMask::operator |= (CONST CChannelMask & RVal)
372 {
373 	if ( &RVal == this )
374 		return;
375 
376 	m_Mask |= RVal.m_Mask;
377 
378 }	// VOID CChannelMask::operator |= (CONST CChannelMask & RVal)
379 
380 
381 //===========================================================================
382 //
383 // Overload new & delete so memory for this object is allocated
384 //	from non-paged memory.
385 //
386 //===========================================================================
387 
388 PVOID CChannelMask::operator new( size_t Size )
389 {
390 	PVOID 		pMemory;
391 	ECHOSTATUS 	Status;
392 
393 	Status = OsAllocateNonPaged(Size,&pMemory);
394 
395 	if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory ))
396 	{
397 		ECHO_DEBUGPRINTF(("CChannelMask::operator new - memory allocation failed\n"));
398 
399 		pMemory = NULL;
400 	}
401 	else
402 	{
403 		memset( pMemory, 0, Size );
404 	}
405 
406 	return pMemory;
407 
408 }	// PVOID CChannelMask::operator new( size_t Size )
409 
410 
411 VOID  CChannelMask::operator delete( PVOID pVoid )
412 {
413 	if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) )
414 	{
415 		ECHO_DEBUGPRINTF(("CChannelMask::operator delete memory free failed\n"));
416 	}
417 }	// VOID  CChannelMask::operator delete( PVOID pVoid )
418 
419 
420 
421 
422 /****************************************************************************
423 
424 	CChMaskDsp
425 
426  ****************************************************************************/
427 
428 //===========================================================================
429 //
430 // Constructor
431 //
432 //===========================================================================
433 
434 CChMaskDsp::CChMaskDsp()
435 {
436 
437 	Clear();
438 
439 }	// CChMaskDsp::CChMaskDsp()
440 
441 
442 //===========================================================================
443 //
444 // IsEmpty returns TRUE if mask has no bits set
445 //
446 //===========================================================================
447 
448 BOOL CChMaskDsp::IsEmpty()
449 {
450 	int	i;
451 
452 	for ( i = 0; i < CH_MASK_SZ; i++ )
453 		if ( 0 != m_MaskRegs[ i ] )
454 			return FALSE;
455 
456 	return TRUE;
457 
458 }	// void CChMaskDsp::IsEmpty()
459 
460 
461 //===========================================================================
462 //
463 // Call SetIndexInMask and ClearIndexInMask to set or clear a single bit.
464 //
465 //===========================================================================
466 
467 // Set driver channel index into DSP mask format
468 void CChMaskDsp::SetIndexInMask( WORD wPipeIndex )
469 {
470 
471 	m_MaskRegs[ wPipeIndex / CH_MASK_DSP_BITS ] |=
472 		SWAP( (CH_MASK_DSP)(( (CH_MASK_DSP) 1 ) << ( wPipeIndex % CH_MASK_DSP_BITS ) ) );
473 }	// void CChMaskDsp::SetIndexInMask( WORD wPipeIndex )
474 
475 
476 // Clear driver channel index into DSP mask format
477 void CChMaskDsp::ClearIndexInMask( WORD wPipeIndex )
478 {
479 	m_MaskRegs[ wPipeIndex / CH_MASK_DSP_BITS ] &=
480 		SWAP( (CH_MASK_DSP)(~( ( (CH_MASK_DSP) 1 ) << ( wPipeIndex % CH_MASK_DSP_BITS ) ) ) );
481 
482 }	// void CChMaskDsp::SetIndexInMask( WORD wPipeIndex )
483 
484 
485 //===========================================================================
486 //
487 // Returns TRUE if the bit specified by the pipe index is set.
488 //
489 //===========================================================================
490 
491 BOOL CChMaskDsp::TestIndexInMask( WORD wPipeIndex )
492 {
493 	if ( m_MaskRegs[ wPipeIndex / CH_MASK_DSP_BITS ] &
494 		  SWAP( (CH_MASK_DSP)( ( (CH_MASK_DSP) 1 ) << ( wPipeIndex % CH_MASK_DSP_BITS ) ) ) )
495 		return TRUE;
496 
497 	return FALSE;
498 
499 }	// BOOL CChMaskDsp::TestIndexInMask( WORD wPipeIndex )
500 
501 
502 //===========================================================================
503 //
504 //	Clear all channels in this mask
505 //
506 //===========================================================================
507 
508 void CChMaskDsp::Clear()
509 {
510 	int	i;
511 
512 	for ( i = 0; i < CH_MASK_SZ; i++ )
513 		m_MaskRegs[ i ] = 0;
514 }	// void CChMaskDsp::Clear()
515 
516 
517 //===========================================================================
518 //
519 //	operator +=    Add channels in source mask to this mask
520 //
521 //===========================================================================
522 
523 VOID CChMaskDsp::operator += (CONST CChannelMask & RVal)
524 {
525 	CH_MASK *	pMask = (CH_MASK *) &m_MaskRegs[ 0 ];
526 
527 	*pMask |= RVal.m_Mask;
528 }	// VOID operator += (CONST CChMaskDsp & RVal)
529 
530 
531 //===========================================================================
532 //
533 //	operator -=    Remove channels in source mask from this mask
534 //
535 //===========================================================================
536 
537 VOID CChMaskDsp::operator -= (CONST CChannelMask & RVal)
538 {
539 	CH_MASK *	pMask = (CH_MASK *) &m_MaskRegs[ 0 ];
540 
541 	*pMask &= ~RVal.m_Mask;
542 }	// VOID operator += (CONST CChMaskDsp & RVal)
543 
544 
545 //===========================================================================
546 //
547 // Operator = just copies from one mask to another.
548 //
549 //===========================================================================
550 
551 CChMaskDsp& CChMaskDsp::operator =(CONST CChannelMask & RVal)
552 {
553 	CH_MASK *	pMask = (CH_MASK *) &m_MaskRegs[ 0 ];
554 
555 	*pMask = RVal.m_Mask;
556 	return *this;
557 
558 }	// CChMaskDsp& CChMaskDsp::operator =(CONST CChannelMask & RVal)
559 
560 
561 //===========================================================================
562 //
563 // Overload new & delete so memory for this object is allocated
564 //	from non-paged memory.
565 //
566 //===========================================================================
567 
568 PVOID CChMaskDsp::operator new( size_t Size )
569 {
570 	PVOID 		pMemory;
571 	ECHOSTATUS 	Status;
572 
573 	Status = OsAllocateNonPaged(Size,&pMemory);
574 
575 	if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory ))
576 	{
577 		ECHO_DEBUGPRINTF(("CChMaskDsp::operator new memory allocation failed\n"));
578 
579 		pMemory = NULL;
580 	}
581 	else
582 	{
583 		memset( pMemory, 0, Size );
584 	}
585 
586 	return pMemory;
587 
588 }	// PVOID CChMaskDsp::operator new( size_t Size )
589 
590 
591 VOID  CChMaskDsp::operator delete( PVOID pVoid )
592 {
593 	if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) )
594 	{
595 		ECHO_DEBUGPRINTF(("CChMaskDsp::operator delete memory free failed\n"));
596 	}
597 }	// VOID  CChMaskDsp::operator delete( PVOID pVoid )
598 
599 
600 // ChannelMask.cpp
601