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 52CChannelMask::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 67void 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 76void 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 85void 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 98void CChannelMask::GetMask( CH_MASK & OutMask, CH_MASK & InMask, int nOutputs ) 99{ 100 OutMask = GetOutMask( nOutputs ); 101 InMask = GetInMask( nOutputs ); 102} // void CChannelMask::GetMask( ... ) 103 104CH_MASK CChannelMask::GetOutMask( int nOutputs ) 105{ 106 return m_Mask & ~( (CH_MASK) -1 << nOutputs ); 107} // CH_MASK CChannelMask::GetOutMask( int nOutputs ) 108 109CH_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 121BOOL 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 138void 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 146void 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 165WORD 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 192BOOL 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 208void 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 221void 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 233VOID 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 246VOID 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 258BOOL 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 278BOOL 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 301BOOL 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 321BOOLEAN 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 337CChannelMask& 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 355VOID 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 371VOID 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 388PVOID 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 411VOID 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 434CChMaskDsp::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 448BOOL 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 465void 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 478void 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 496BOOL 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 516void 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 528CChMaskDsp& 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 544PVOID 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 567VOID 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