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 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 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 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 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 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 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 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 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