xref: /haiku/src/add-ons/kernel/drivers/audio/echo/generic/CChannelMask.cpp (revision 4dd9e43637031d2c5a6755a0184040f0de8f2884)
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 
CChannelMask()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 
SetMask(CH_MASK OutMask,CH_MASK InMask,int nOutputs)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 
SetOutMask(CH_MASK OutMask,int nOutputs)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 
SetInMask(CH_MASK InMask,int nOutputs)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 
GetMask(CH_MASK & OutMask,CH_MASK & InMask,int nOutputs)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 
GetOutMask(int nOutputs)104 CH_MASK CChannelMask::GetOutMask( int nOutputs )
105 {
106 	return  m_Mask & ~( (CH_MASK) -1 << nOutputs );
107 }	// CH_MASK CChannelMask::GetOutMask( int nOutputs )
108 
GetInMask(int nOutputs)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 
IsEmpty()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
SetIndexInMask(WORD wPipeIndex)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
ClearIndexInMask(WORD wPipeIndex)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 
GetIndexFromMask(WORD wStartPipeIndex)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 
TestIndexInMask(WORD wPipeIndex)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 
ClearMask(CChannelMask SrcMask)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 
Clear()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 
operator +=(CONST CChannelMask & RVal)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 
operator -=(CONST CChannelMask & RVal)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 
Test(PCChannelMask pSrcMask)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 
IsSubsetOf(CChannelMask & TstMask)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 
IsIntersectionOf(CChannelMask & TstMask)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 
operator ==(CONST CChannelMask & LVal,CONST CChannelMask & RVal)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 
operator =(CONST CChannelMask & RVal)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 
operator &=(CONST CChannelMask & RVal)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 
operator |=(CONST CChannelMask & RVal)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 
operator new(size_t Size)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 
operator delete(PVOID pVoid)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 
CChMaskDsp()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 
IsEmpty()448 BOOL CChMaskDsp::IsEmpty()
449 {
450 	if (0 != m_Mask)
451 			return FALSE;
452 
453 	return TRUE;
454 
455 }	// void CChMaskDsp::IsEmpty()
456 
457 
458 //===========================================================================
459 //
460 // Call SetIndexInMask and ClearIndexInMask to set or clear a single bit.
461 //
462 //===========================================================================
463 
464 // Set driver channel index into DSP mask format
SetIndexInMask(WORD wPipeIndex)465 void CChMaskDsp::SetIndexInMask( WORD wPipeIndex )
466 {
467 	CH_MASK_DSP bit,temp;
468 
469 	temp = SWAP( m_Mask );
470 	bit = 1 << wPipeIndex;
471 	temp |= bit;
472 	m_Mask = SWAP( temp );
473 
474 }	// void CChMaskDsp::SetIndexInMask( WORD wPipeIndex )
475 
476 
477 // Clear driver channel index into DSP mask format
ClearIndexInMask(WORD wPipeIndex)478 void CChMaskDsp::ClearIndexInMask( WORD wPipeIndex )
479 {
480 	CH_MASK_DSP bit,temp;
481 
482 	temp = SWAP( m_Mask );
483 	bit = 1 << wPipeIndex;
484 	temp &= ~bit;
485 	m_Mask = SWAP( temp );
486 
487 }	// void CChMaskDsp::SetIndexInMask( WORD wPipeIndex )
488 
489 
490 //===========================================================================
491 //
492 // Returns TRUE if the bit specified by the pipe index is set.
493 //
494 //===========================================================================
495 
TestIndexInMask(WORD wPipeIndex)496 BOOL CChMaskDsp::TestIndexInMask( WORD wPipeIndex )
497 {
498 	CH_MASK_DSP temp,bit;
499 
500 	temp = SWAP(m_Mask);
501 	bit = 1 << wPipeIndex;
502 	if (0 != (temp & bit))
503 		return TRUE;
504 
505 	return FALSE;
506 
507 }	// BOOL CChMaskDsp::TestIndexInMask( WORD wPipeIndex )
508 
509 
510 //===========================================================================
511 //
512 //	Clear all channels in this mask
513 //
514 //===========================================================================
515 
Clear()516 void CChMaskDsp::Clear()
517 {
518 	m_Mask = 0;
519 }	// void CChMaskDsp::Clear()
520 
521 
522 //===========================================================================
523 //
524 // Operator = just copies from one mask to another.
525 //
526 //===========================================================================
527 
operator =(CONST CChannelMask & RVal)528 CChMaskDsp& CChMaskDsp::operator =(CONST CChannelMask & RVal)
529 {
530 	m_Mask = SWAP(RVal.m_Mask);
531 
532 	return *this;
533 
534 }	// CChMaskDsp& CChMaskDsp::operator =(CONST CChannelMask & RVal)
535 
536 
537 //===========================================================================
538 //
539 // Overload new & delete so memory for this object is allocated
540 //	from non-paged memory.
541 //
542 //===========================================================================
543 
operator new(size_t Size)544 PVOID CChMaskDsp::operator new( size_t Size )
545 {
546 	PVOID 		pMemory;
547 	ECHOSTATUS 	Status;
548 
549 	Status = OsAllocateNonPaged(Size,&pMemory);
550 
551 	if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory ))
552 	{
553 		ECHO_DEBUGPRINTF(("CChMaskDsp::operator new memory allocation failed\n"));
554 
555 		pMemory = NULL;
556 	}
557 	else
558 	{
559 		memset( pMemory, 0, Size );
560 	}
561 
562 	return pMemory;
563 
564 }	// PVOID CChMaskDsp::operator new( size_t Size )
565 
566 
operator delete(PVOID pVoid)567 VOID  CChMaskDsp::operator delete( PVOID pVoid )
568 {
569 	if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) )
570 	{
571 		ECHO_DEBUGPRINTF(("CChMaskDsp::operator delete memory free failed\n"));
572 	}
573 }	// VOID  CChMaskDsp::operator delete( PVOID pVoid )
574 
575 
576 // ChannelMask.cpp
577