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 // Copyright Echo Digital Audio Corporation (c) 1998 - 2002 15 // All rights reserved 16 // www.echoaudio.com 17 // 18 // Permission is hereby granted, free of charge, to any person obtaining a 19 // copy of this software and associated documentation files (the 20 // "Software"), to deal with the Software without restriction, including 21 // without limitation the rights to use, copy, modify, merge, publish, 22 // distribute, sublicense, and/or sell copies of the Software, and to 23 // permit persons to whom the Software is furnished to do so, subject to 24 // the following conditions: 25 // 26 // - Redistributions of source code must retain the above copyright 27 // notice, this list of conditions and the following disclaimers. 28 // 29 // - Redistributions in binary form must reproduce the above copyright 30 // notice, this list of conditions and the following disclaimers in the 31 // documentation and/or other materials provided with the distribution. 32 // 33 // - Neither the name of Echo Digital Audio, nor the names of its 34 // contributors may be used to endorse or promote products derived from 35 // this Software without specific prior written permission. 36 // 37 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 38 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 39 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 40 // IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR 41 // ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 42 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 43 // SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. 44 // 45 // **************************************************************************** 46 47 #include "CEchoGals.h" 48 49 50 /**************************************************************************** 51 52 CChannelMask 53 54 ****************************************************************************/ 55 56 //=========================================================================== 57 // 58 // Constructor 59 // 60 //=========================================================================== 61 62 CChannelMask::CChannelMask() 63 { 64 65 Clear(); 66 67 } // CChannelMask::CChannelMask() 68 69 70 //=========================================================================== 71 // 72 // SetMask, SetOutMask, and SetInMask all allow you to just set 73 // the masks directly. 74 // 75 //=========================================================================== 76 77 void CChannelMask::SetMask( CH_MASK OutMask, CH_MASK InMask, int nOutputs ) 78 { 79 80 m_MaskRegs[ 0 ] = SWAP( OutMask ); 81 m_MaskRegs[ 0 ] |= SWAP( (CH_MASK) ( InMask << nOutputs ) ); 82 m_MaskRegs[ 1 ] = SWAP( (CH_MASK) ( InMask >> ( CH_MASK_BITS - nOutputs ) ) ); 83 84 } // void CChannelMask::SetMask( ... ) 85 86 87 void CChannelMask::SetOutMask( CH_MASK OutMask, int nOutputs ) 88 { 89 90 m_MaskRegs[ 0 ] &= SWAP( (CH_MASK) ( (CH_MASK) -1 << nOutputs ) ); 91 m_MaskRegs[ 0 ] |= SWAP( OutMask ); 92 93 } // void CChannelMask::SetOutMask( CH_MASK OutMask, int nOutputs ) 94 95 96 void CChannelMask::SetInMask( CH_MASK InMask, int nOutputs ) 97 { 98 m_MaskRegs[ 0 ] &= SWAP( (CH_MASK) (~( (CH_MASK) -1 << nOutputs ) ) ); 99 m_MaskRegs[ 0 ] |= SWAP( (CH_MASK) ( InMask << nOutputs ) ); 100 m_MaskRegs[ 1 ] = SWAP( (CH_MASK) ( InMask >> ( CH_MASK_BITS - nOutputs ) ) ); 101 } // void CChannelMask::SetInMask( CH_MASK InMask, int nOutputs ) 102 103 104 //=========================================================================== 105 // 106 // Retrieve an output bit mask and an input bitmask. 107 // 108 //=========================================================================== 109 110 void CChannelMask::GetMask( CH_MASK & OutMask, CH_MASK & InMask, int nOutputs ) 111 { 112 OutMask = GetOutMask( nOutputs ); 113 InMask = GetInMask( nOutputs ); 114 } // void CChannelMask::GetMask( ... ) 115 116 CH_MASK CChannelMask::GetOutMask( int nOutputs ) 117 { 118 return SWAP( m_MaskRegs[ 0 ] ) & ~( (CH_MASK) -1 << nOutputs ); 119 } // CH_MASK CChannelMask::GetOutMask( int nOutputs ) 120 121 CH_MASK CChannelMask::GetInMask( int nOutputs ) 122 { 123 return ( SWAP( m_MaskRegs[ 0 ] ) >> nOutputs ) | 124 ( SWAP( m_MaskRegs[ 1 ] ) << ( CH_MASK_BITS - nOutputs ) ); 125 } // CH_MASK CChannelMask::GetIntMask( int nOutputs ) 126 127 128 //=========================================================================== 129 // 130 // IsEmpty returns TRUE if mask has no bits set 131 // 132 //=========================================================================== 133 134 BOOL CChannelMask::IsEmpty() 135 { 136 int i; 137 138 for ( i = 0; i < CH_MASK_SZ; i++ ) 139 if ( 0 != m_MaskRegs[ i ] ) 140 return FALSE; 141 142 return TRUE; 143 144 } // void CChannelMask::IsEmpty() 145 146 147 //=========================================================================== 148 // 149 // Call SetIndexInMask and ClearIndexInMask to set or clear a single bit. 150 // 151 //=========================================================================== 152 153 // Set driver channel index into DSP mask format 154 void CChannelMask::SetIndexInMask( WORD wPipeIndex ) 155 { 156 157 m_MaskRegs[ wPipeIndex / CH_MASK_BITS ] |= 158 SWAP( (CH_MASK) (( (CH_MASK) 1 ) << ( wPipeIndex % CH_MASK_BITS ) ) ); 159 160 } // void CChannelMask::SetIndexInMask( WORD wPipeIndex ) 161 162 163 // Clear driver channel index into DSP mask format 164 void CChannelMask::ClearIndexInMask( WORD wPipeIndex ) 165 { 166 167 m_MaskRegs[ wPipeIndex / CH_MASK_BITS ] &= 168 SWAP( (CH_MASK)(~( ( (CH_MASK) 1 ) << ( wPipeIndex % CH_MASK_BITS ) ) ) ); 169 170 } // void CChannelMask::ClearIndexInMask( WORD wPipeIndex ) 171 172 173 //=========================================================================== 174 // 175 // Use GetIndexFromMask to search the mask for bits that are set. 176 // 177 // The search starts at the bit specified by wStartPipeIndex and returns 178 // the pipe index for the first non-zero bit found. 179 // 180 // Returns ECHO_INVALID_CHANNEL if none are found. 181 // 182 //=========================================================================== 183 184 WORD CChannelMask::GetIndexFromMask( WORD wStartPipeIndex ) 185 { 186 WORD wIndex = wStartPipeIndex % CH_MASK_BITS; 187 WORD wCt = wStartPipeIndex / CH_MASK_BITS; 188 CH_MASK Mask; 189 190 for ( ; wCt < CH_MASK_SZ; wCt++ ) 191 { 192 Mask = SWAP( m_MaskRegs[ wCt ] ); 193 if ( 0 != Mask ) 194 { 195 while( !( Mask & (1<<wIndex) ) && 196 wIndex < CH_MASK_BITS ) 197 wIndex++; 198 if ( wIndex < CH_MASK_BITS ) 199 return( wIndex + ( wCt * CH_MASK_BITS ) ); 200 } 201 wIndex = 0; 202 } 203 return( (WORD) ECHO_INVALID_CHANNEL ); 204 205 } // WORD CChannelMask::GetIndexFromMask( WORD wStartIndex ) 206 207 208 //=========================================================================== 209 // 210 // Returns TRUE if the bit specified by the pipe index is set. 211 // 212 //=========================================================================== 213 214 BOOL CChannelMask::TestIndexInMask( WORD wPipeIndex ) 215 { 216 if ( SWAP( m_MaskRegs[ wPipeIndex / CH_MASK_BITS ] ) & 217 (CH_MASK)( ( (CH_MASK) 1 ) << ( wPipeIndex % CH_MASK_BITS ) ) 218 ) 219 return TRUE; 220 221 return FALSE; 222 } // BOOL CChannelMask::TestIndexInMask( WORD wPipeIndex ) 223 224 225 //=========================================================================== 226 // 227 // Clear bits in this mask that are in SrcMask - this is just like 228 // operator -=, below. 229 // 230 //=========================================================================== 231 232 void CChannelMask::ClearMask( CChannelMask SrcMask ) 233 { 234 int i; 235 236 for ( i = 0; i < CH_MASK_SZ; i++ ) 237 { 238 m_MaskRegs[ i ] &= ~SrcMask.m_MaskRegs[ i ]; 239 } 240 241 } // void CChannelMask::ClearMask( CChannelMask SrcMask ) 242 243 244 //=========================================================================== 245 // 246 // Clear all channels in this mask 247 // 248 //=========================================================================== 249 250 void CChannelMask::Clear() 251 { 252 int i; 253 254 for ( i = 0; i < CH_MASK_SZ; i++ ) 255 m_MaskRegs[ i ] = 0; 256 257 } // void CChannelMask::Clear() 258 259 260 //=========================================================================== 261 // 262 // operator += Add channels in source mask to this mask 263 // 264 //=========================================================================== 265 266 VOID CChannelMask::operator += (CONST CChannelMask & RVal) 267 { 268 int i; 269 270 for ( i = 0; i < CH_MASK_SZ; i++ ) 271 m_MaskRegs[ i ] |= RVal.m_MaskRegs[ i ]; 272 } // VOID operator += (CONST CChannelMask & RVal) 273 274 275 //=========================================================================== 276 // 277 // operator -= Remove channels in source mask from this mask 278 // 279 //=========================================================================== 280 281 VOID CChannelMask::operator -= (CONST CChannelMask & RVal) 282 { 283 int i; 284 285 for ( i = 0; i < CH_MASK_SZ; i++ ) 286 m_MaskRegs[ i ] &= ~RVal.m_MaskRegs[ i ]; 287 288 } // VOID operator -= (CONST CChannelMask & RVal) 289 290 291 //=========================================================================== 292 // 293 // Test returns TRUE if any bits in source mask are set in this mask 294 // 295 //=========================================================================== 296 297 BOOL CChannelMask::Test( PCChannelMask pSrcMask ) 298 { 299 int i; 300 301 for ( i = 0; i < CH_MASK_SZ; i++ ) 302 if ( m_MaskRegs[ i ] & pSrcMask->m_MaskRegs[ i ] ) 303 return TRUE; 304 return FALSE; 305 306 } // BOOL CChannelMask::Test( PChannelMask pSrcMask ) 307 308 309 //=========================================================================== 310 // 311 // IsSubsetOf returns TRUE if all of the channels in TstMask are set in 312 // m_MaskRegs. 313 // 314 // Use to be sure all channels in this instance exist in 315 // another instance. 316 // 317 //=========================================================================== 318 319 BOOL CChannelMask::IsSubsetOf 320 ( 321 CChannelMask& TstMask 322 ) 323 { 324 for ( int i = 0; i < CH_MASK_SZ; i++ ) 325 { 326 CH_MASK ThisMask; 327 328 ThisMask = SWAP( m_MaskRegs[ i ]); 329 if ( ( ThisMask & TstMask[ i ] ) != ThisMask ) 330 return FALSE; 331 } 332 333 return TRUE; 334 335 } // BOOL CChannelMask::IsSubsetOf 336 337 338 //=========================================================================== 339 // 340 // IsIntersectionOf returns TRUE if TstMask contains at least one of the 341 // channels enabled in this instance. 342 // 343 // Use this to find out if any channels in this instance exist in 344 // another instance. 345 // 346 //=========================================================================== 347 348 BOOL CChannelMask::IsIntersectionOf 349 ( 350 CChannelMask& TstMask 351 ) 352 { 353 for ( int i = 0; i < CH_MASK_SZ; i++ ) 354 if ( 0 != ( m_MaskRegs[ i ] & TstMask[ i ] ) ) 355 return TRUE; 356 357 return FALSE; 358 359 } // BOOL CChannelMask::IsIntersectionOf 360 361 362 //=========================================================================== 363 // 364 // Operator == is just what you'd expect - it tells you if one mask is 365 // the same as another 366 // 367 //=========================================================================== 368 369 BOOLEAN operator == ( CONST CChannelMask &LVal, CONST CChannelMask &RVal ) 370 { 371 for ( int i = 0; i < CH_MASK_SZ; i++ ) 372 if ( LVal.m_MaskRegs[ i ] != RVal.m_MaskRegs[ i ] ) 373 return FALSE; 374 375 return TRUE; 376 377 } // BOOLEAN operator == ( CONST CChannelMask &LVal, CONST CChannelMask &RVal ) 378 379 380 //=========================================================================== 381 // 382 // Operator = just copies from one mask to another. 383 // 384 //=========================================================================== 385 386 CChannelMask& CChannelMask::operator =(CONST CChannelMask & RVal) 387 { 388 if ( &RVal == this ) 389 return *this; 390 391 for ( int i = 0; i < CH_MASK_SZ; i++ ) 392 m_MaskRegs[ i ] = RVal.m_MaskRegs[ i ]; 393 394 return *this; 395 396 } // CChannelMask& CChannelMask::operator = (CONTS CChannelMask & RVal) 397 398 399 CChannelMask& CChannelMask::operator =(CONST CChMaskDsp & RVal) 400 { 401 CH_MASK * pMask = (CH_MASK *) &RVal.m_MaskRegs[ 0 ]; 402 403 m_MaskRegs[ 0 ] = *pMask; 404 m_MaskRegs[ 1 ] = 0; 405 406 return *this; 407 408 } // CChannelMask& CChannelMask::operator =(CONST CChMaskDsp & RVal) 409 410 411 //=========================================================================== 412 // 413 // Operator & performs a bitwise logical AND 414 // 415 //=========================================================================== 416 417 VOID CChannelMask::operator &= (CONST CChannelMask & RVal) 418 { 419 if ( &RVal == this ) 420 return; 421 422 for ( int i = 0; i < CH_MASK_SZ; i++ ) 423 m_MaskRegs[ i ] &= RVal.m_MaskRegs[ i ]; 424 425 } // VOID CChannelMask::operator &= (CONST CChannelMask & RVal) 426 427 428 //=========================================================================== 429 // 430 // Operator & performs a bitwise logical OR 431 // 432 //=========================================================================== 433 434 VOID CChannelMask::operator |= (CONST CChannelMask & RVal) 435 { 436 if ( &RVal == this ) 437 return; 438 439 for ( int i = 0; i < CH_MASK_SZ; i++ ) 440 m_MaskRegs[ i ] |= RVal.m_MaskRegs[ i ]; 441 442 } // VOID CChannelMask::operator |= (CONST CChannelMask & RVal) 443 444 445 //=========================================================================== 446 // 447 // Overload new & delete so memory for this object is allocated 448 // from non-paged memory. 449 // 450 //=========================================================================== 451 452 PVOID CChannelMask::operator new( size_t Size ) 453 { 454 PVOID pMemory; 455 ECHOSTATUS Status; 456 457 Status = OsAllocateNonPaged(Size,&pMemory); 458 459 if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory )) 460 { 461 ECHO_DEBUGPRINTF(("CChannelMask::operator new - memory allocation failed\n")); 462 463 pMemory = NULL; 464 } 465 else 466 { 467 memset( pMemory, 0, Size ); 468 } 469 470 return pMemory; 471 472 } // PVOID CChannelMask::operator new( size_t Size ) 473 474 475 VOID CChannelMask::operator delete( PVOID pVoid ) 476 { 477 if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) ) 478 { 479 ECHO_DEBUGPRINTF(("CChannelMask::operator delete memory free failed\n")); 480 } 481 } // VOID CChannelMask::operator delete( PVOID pVoid ) 482 483 484 485 486 /**************************************************************************** 487 488 CChMaskDsp 489 490 ****************************************************************************/ 491 492 //=========================================================================== 493 // 494 // Constructor 495 // 496 //=========================================================================== 497 498 CChMaskDsp::CChMaskDsp() 499 { 500 501 Clear(); 502 503 } // CChMaskDsp::CChMaskDsp() 504 505 506 //=========================================================================== 507 // 508 // IsEmpty returns TRUE if mask has no bits set 509 // 510 //=========================================================================== 511 512 BOOL CChMaskDsp::IsEmpty() 513 { 514 int i; 515 516 for ( i = 0; i < CH_MASK_SZ; i++ ) 517 if ( 0 != m_MaskRegs[ i ] ) 518 return FALSE; 519 520 return TRUE; 521 522 } // void CChMaskDsp::IsEmpty() 523 524 525 //=========================================================================== 526 // 527 // Call SetIndexInMask and ClearIndexInMask to set or clear a single bit. 528 // 529 //=========================================================================== 530 531 // Set driver channel index into DSP mask format 532 void CChMaskDsp::SetIndexInMask( WORD wPipeIndex ) 533 { 534 535 m_MaskRegs[ wPipeIndex / CH_MASK_DSP_BITS ] |= 536 SWAP( (CH_MASK_DSP)(( (CH_MASK_DSP) 1 ) << ( wPipeIndex % CH_MASK_DSP_BITS ) ) ); 537 } // void CChMaskDsp::SetIndexInMask( WORD wPipeIndex ) 538 539 540 // Clear driver channel index into DSP mask format 541 void CChMaskDsp::ClearIndexInMask( WORD wPipeIndex ) 542 { 543 m_MaskRegs[ wPipeIndex / CH_MASK_DSP_BITS ] &= 544 SWAP( (CH_MASK_DSP)(~( ( (CH_MASK_DSP) 1 ) << ( wPipeIndex % CH_MASK_DSP_BITS ) ) ) ); 545 546 } // void CChMaskDsp::SetIndexInMask( WORD wPipeIndex ) 547 548 549 //=========================================================================== 550 // 551 // Returns TRUE if the bit specified by the pipe index is set. 552 // 553 //=========================================================================== 554 555 BOOL CChMaskDsp::TestIndexInMask( WORD wPipeIndex ) 556 { 557 if ( m_MaskRegs[ wPipeIndex / CH_MASK_DSP_BITS ] & 558 SWAP( (CH_MASK_DSP)( ( (CH_MASK_DSP) 1 ) << ( wPipeIndex % CH_MASK_DSP_BITS ) ) ) ) 559 return TRUE; 560 561 return FALSE; 562 563 } // BOOL CChMaskDsp::TestIndexInMask( WORD wPipeIndex ) 564 565 566 //=========================================================================== 567 // 568 // Clear all channels in this mask 569 // 570 //=========================================================================== 571 572 void CChMaskDsp::Clear() 573 { 574 int i; 575 576 for ( i = 0; i < CH_MASK_SZ; i++ ) 577 m_MaskRegs[ i ] = 0; 578 } // void CChMaskDsp::Clear() 579 580 581 //=========================================================================== 582 // 583 // operator += Add channels in source mask to this mask 584 // 585 //=========================================================================== 586 587 VOID CChMaskDsp::operator += (CONST CChannelMask & RVal) 588 { 589 CH_MASK * pMask = (CH_MASK *) &m_MaskRegs[ 0 ]; 590 591 *pMask |= RVal.m_MaskRegs[ 0 ]; 592 } // VOID operator += (CONST CChMaskDsp & RVal) 593 594 595 //=========================================================================== 596 // 597 // operator -= Remove channels in source mask from this mask 598 // 599 //=========================================================================== 600 601 VOID CChMaskDsp::operator -= (CONST CChannelMask & RVal) 602 { 603 CH_MASK * pMask = (CH_MASK *) &m_MaskRegs[ 0 ]; 604 605 *pMask &= ~RVal.m_MaskRegs[ 0 ]; 606 } // VOID operator += (CONST CChMaskDsp & RVal) 607 608 609 //=========================================================================== 610 // 611 // Operator = just copies from one mask to another. 612 // 613 //=========================================================================== 614 615 CChMaskDsp& CChMaskDsp::operator =(CONST CChannelMask & RVal) 616 { 617 CH_MASK * pMask = (CH_MASK *) &m_MaskRegs[ 0 ]; 618 619 *pMask = RVal.m_MaskRegs[ 0 ]; 620 return *this; 621 622 } // CChMaskDsp& CChMaskDsp::operator =(CONST CChannelMask & RVal) 623 624 625 //=========================================================================== 626 // 627 // Overload new & delete so memory for this object is allocated 628 // from non-paged memory. 629 // 630 //=========================================================================== 631 632 PVOID CChMaskDsp::operator new( size_t Size ) 633 { 634 PVOID pMemory; 635 ECHOSTATUS Status; 636 637 Status = OsAllocateNonPaged(Size,&pMemory); 638 639 if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory )) 640 { 641 ECHO_DEBUGPRINTF(("CChMaskDsp::operator new memory allocation failed\n")); 642 643 pMemory = NULL; 644 } 645 else 646 { 647 memset( pMemory, 0, Size ); 648 } 649 650 return pMemory; 651 652 } // PVOID CChMaskDsp::operator new( size_t Size ) 653 654 655 VOID CChMaskDsp::operator delete( PVOID pVoid ) 656 { 657 if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) ) 658 { 659 ECHO_DEBUGPRINTF(("CChMaskDsp::operator delete memory free failed\n")); 660 } 661 } // VOID CChMaskDsp::operator delete( PVOID pVoid ) 662 663 664 // ChannelMask.cpp 665