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