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