1// **************************************************************************** 2// 3// C3gDco.cpp 4// 5// Implementation file for EchoGals generic driver 3G DSP 6// interface class. 7// 8// ---------------------------------------------------------------------------- 9// 10// This file is part of Echo Digital Audio's generic driver library. 11// Copyright Echo Digital Audio Corporation (c) 1998 - 2005 12// All rights reserved 13// www.echoaudio.com 14// 15// This library is free software; you can redistribute it and/or 16// modify it under the terms of the GNU Lesser General Public 17// License as published by the Free Software Foundation; either 18// version 2.1 of the License, or (at your option) any later version. 19// 20// This library is distributed in the hope that it will be useful, 21// but WITHOUT ANY WARRANTY; without even the implied warranty of 22// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23// Lesser General Public License for more details. 24// 25// You should have received a copy of the GNU Lesser General Public 26// License along with this library; if not, write to the Free Software 27// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 28// 29// **************************************************************************** 30 31#include "CEchoGals.h" 32#include "C3gDco.h" 33 34#include "Echo3gDSP.c" 35#include "3G_ASIC.c" 36 37/**************************************************************************** 38 39 Construction and destruction 40 41 ****************************************************************************/ 42 43//=========================================================================== 44// 45// Constructor 46// 47//=========================================================================== 48 49C3gDco::C3gDco 50( 51 PDWORD pdwRegBase, // Virtual ptr to DSP registers 52 PCOsSupport pOsSupport 53) : CDspCommObject( pdwRegBase, pOsSupport ) 54{ 55 m_pdwDspRegBase = pdwRegBase; // Virtual addr DSP's register base fixme put this in base class 56 57 m_dwOriginalBoxType = NO3GBOX; 58 m_dwCurrentBoxType = m_dwOriginalBoxType; 59 SetChannelCounts(); 60 m_bBoxTypeSet = FALSE; 61 62 m_fHasVmixer = FALSE; 63 64 m_wNumMidiOut = 1; // # MIDI out channels 65 m_wNumMidiIn = 1; // # MIDI in channels 66 67 m_pDspCommPage->dwSampleRate = SWAP( (DWORD) 48000 ); 68 m_pDspCommPage->dw3gFreqReg = SWAP( (DWORD) (E3G_MAGIC_NUMBER / 48000) - 2); 69 70 m_bHasASIC = TRUE; 71 72 m_pwDspCodeToLoad = pwEcho3gDSP; 73 74 m_byDigitalMode = DIGITAL_MODE_SPDIF_RCA; 75 76 m_bProfessionalSpdif = FALSE; 77 m_bNonAudio = FALSE; 78 79} // C3gDco::C3gDco( DWORD dwPhysRegBase ) 80 81 82 83//=========================================================================== 84// 85// Destructor 86// 87//=========================================================================== 88 89C3gDco::~C3gDco() 90{ 91} // C3gDco::~C3gDco() 92 93 94 95//=========================================================================== 96// 97// Supported digital modes depend on what kind of box you have 98// 99//=========================================================================== 100 101DWORD C3gDco::GetDigitalModes() 102{ 103 DWORD dwModes; 104 105 dwModes = ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | 106 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | 107 ECHOCAPS_HAS_DIGITAL_MODE_ADAT; 108 109 return dwModes; 110} 111 112 113/**************************************************************************** 114 115 Hardware setup and config 116 117 ****************************************************************************/ 118 119//=========================================================================== 120// 121// 3G has an ASIC in the external box 122// 123//=========================================================================== 124 125BOOL C3gDco::LoadASIC() 126{ 127 DWORD dwControlReg; 128 129 if ( m_bASICLoaded == TRUE ) 130 return TRUE; 131 132 ECHO_DEBUGPRINTF(("C3gDco::LoadASIC\n")); 133 134 // 135 // Give the DSP a few milliseconds to settle down 136 // 137 m_pOsSupport->OsSnooze( 2000 ); 138 139 // 140 // Load the ASIC 141 // 142 if ( !CDspCommObject::LoadASIC( DSP_FNC_LOAD_3G_ASIC, 143 pb3g_asic, 144 sizeof(pb3g_asic) ) ) 145 return FALSE; 146 147 // 148 // Give the ASIC a whole second to set up 149 // 150 m_pOsSupport->OsSnooze( 1000000 ); 151 152 // 153 // See if it worked 154 // 155 CheckAsicStatus(); 156 157 // 158 // Set up the control register if the load succeeded - 159 // 160 // 48 kHz, internal clock, S/PDIF RCA mode 161 // 162 if ( m_bASICLoaded ) 163 { 164 dwControlReg = E3G_48KHZ; 165 WriteControlReg( dwControlReg, E3G_FREQ_REG_DEFAULT, TRUE); // TRUE == force write 166 } 167 168 ECHO_DEBUGPRINTF(("\t3G ASIC loader finished\n")); 169 170 return m_bASICLoaded; 171 172} // BOOL C3gDco::LoadASIC() 173 174 175 176//=========================================================================== 177// 178// Set the input clock 179// 180//=========================================================================== 181 182ECHOSTATUS C3gDco::SetInputClock(WORD wClock) 183{ 184 DWORD dwControlReg,dwSampleRate; 185 ECHOSTATUS Status; 186 187 ECHO_DEBUGPRINTF( ("C3gDco::SetInputClock:\n") ); 188 189 // 190 // Mask off the clock select bits 191 // 192 dwControlReg = GetControlRegister(); 193 dwControlReg &= E3G_CLOCK_CLEAR_MASK; 194 195 // 196 // New clock 197 // 198 switch (wClock) 199 { 200 case ECHO_CLOCK_INTERNAL : 201 ECHO_DEBUGPRINTF(("\tsetting internal clock\n")); 202 203 m_wInputClock = ECHO_CLOCK_INTERNAL; // prevent recursion 204 205 dwSampleRate = GetSampleRate(); 206 if ((dwSampleRate < 32000) || (dwSampleRate > 100000)) 207 dwSampleRate = 48000; 208 209 SetSampleRate(dwSampleRate); 210 return ECHOSTATUS_OK; 211 212 213 case ECHO_CLOCK_WORD: 214 dwControlReg |= E3G_WORD_CLOCK; 215 216 if ( E3G_CLOCK_DETECT_BIT_WORD96 & GetInputClockDetect() ) 217 { 218 dwControlReg |= E3G_DOUBLE_SPEED_MODE; 219 } 220 else 221 { 222 dwControlReg &= ~E3G_DOUBLE_SPEED_MODE; 223 } 224 ECHO_DEBUGPRINTF( ( "\tSet 3G clock to WORD\n" ) ); 225 break; 226 227 228 case ECHO_CLOCK_SPDIF : 229 if ( DIGITAL_MODE_ADAT == GetDigitalMode() ) 230 { 231 return ECHOSTATUS_CLOCK_NOT_AVAILABLE; 232 } 233 234 dwControlReg |= E3G_SPDIF_CLOCK; 235 if ( E3G_CLOCK_DETECT_BIT_SPDIF96 & GetInputClockDetect() ) 236 { 237 dwControlReg |= E3G_DOUBLE_SPEED_MODE; 238 } 239 else 240 { 241 dwControlReg &= ~E3G_DOUBLE_SPEED_MODE; 242 } 243 244 ECHO_DEBUGPRINTF( ( "\tSet 3G clock to SPDIF\n" ) ); 245 break; 246 247 248 case ECHO_CLOCK_ADAT : 249 if ( DIGITAL_MODE_ADAT != GetDigitalMode() ) 250 { 251 return ECHOSTATUS_CLOCK_NOT_AVAILABLE; 252 } 253 254 dwControlReg |= E3G_ADAT_CLOCK; 255 dwControlReg &= ~E3G_DOUBLE_SPEED_MODE; 256 ECHO_DEBUGPRINTF( ( "\tSet 3G clock to ADAT\n" ) ); 257 break; 258 259 260 default : 261 ECHO_DEBUGPRINTF(("Input clock 0x%x not supported for 3G\n",wClock)); 262 ECHO_DEBUGBREAK(); 263 return ECHOSTATUS_CLOCK_NOT_SUPPORTED; 264 } 265 266 // 267 // Winner! Try to write the hardware 268 // 269 Status = WriteControlReg( dwControlReg, Get3gFreqReg(), TRUE ); 270 if (ECHOSTATUS_OK == Status) 271 m_wInputClock = wClock; 272 273 return Status; 274 275} // ECHOSTATUS C3gDco::SetInputClock 276 277 278 279//=========================================================================== 280// 281// SetSampleRate 282// 283// Set the audio sample rate for 3G 284// 285//=========================================================================== 286 287DWORD C3gDco::SetSampleRate( DWORD dwNewSampleRate ) 288{ 289 DWORD dwControlReg,dwNewClock,dwBaseRate,dwFreqReg; 290 291 ECHO_DEBUGPRINTF(("3G set sample rate to %ld\n",dwNewSampleRate)); 292 293 // 294 // Only set the clock for internal mode. If the clock is not set to 295 // internal, try and re-set the input clock; this more transparently 296 // handles switching between single and double-speed mode 297 // 298 if ( GetInputClock() != ECHO_CLOCK_INTERNAL ) 299 { 300 ECHO_DEBUGPRINTF( ( "C3gDco::SetSampleRate: Cannot set sample rate - " 301 "clock not set to ECHO_CLOCK_INTERNAL\n" ) ); 302 303 // 304 // Save the rate anyhow 305 // 306 m_pDspCommPage->dwSampleRate = SWAP( dwNewSampleRate ); 307 308 // 309 // Set the input clock to the current value 310 // 311 SetInputClock( m_wInputClock ); 312 313 return dwNewSampleRate; 314 } 315 316 // 317 // Get the control register & clear the appropriate bits 318 // 319 dwControlReg = GetControlRegister(); 320 dwControlReg &= E3G_CLOCK_CLEAR_MASK; 321 322 // 323 // Set the sample rate 324 // 325 switch ( dwNewSampleRate ) 326 { 327 case 96000 : 328 dwNewClock = E3G_96KHZ; 329 break; 330 331 case 88200 : 332 dwNewClock = E3G_88KHZ; 333 break; 334 335 case 48000 : 336 dwNewClock = E3G_48KHZ; 337 break; 338 339 case 44100 : 340 dwNewClock = E3G_44KHZ; 341 break; 342 343 case 32000 : 344 dwNewClock = E3G_32KHZ; 345 break; 346 347 default : 348 dwNewClock = E3G_CONTINUOUS_CLOCK; 349 if (dwNewSampleRate > 50000) 350 dwNewClock |= E3G_DOUBLE_SPEED_MODE; 351 break; 352 } 353 354 dwControlReg |= dwNewClock; 355 SetSpdifBits(&dwControlReg,dwNewSampleRate); 356 357 ECHO_DEBUGPRINTF(("\tdwNewClock 0x%lx dwControlReg 0x%lx\n",dwNewClock,dwControlReg)); 358 359 // 360 // Set up the frequency reg 361 // 362 dwBaseRate = dwNewSampleRate; 363 if (dwBaseRate > 50000) 364 dwBaseRate /= 2; 365 366 if (dwBaseRate < 32000) 367 dwBaseRate = 32000; 368 369 dwFreqReg = E3G_MAGIC_NUMBER / dwBaseRate - 2; 370 if (dwFreqReg > E3G_FREQ_REG_MAX) 371 dwFreqReg = E3G_FREQ_REG_MAX; 372 373 // 374 // Tell the DSP about it - DSP reads both control reg & freq reg 375 // 376 if ( ECHOSTATUS_OK == WriteControlReg( dwControlReg, dwFreqReg) ) 377 { 378 m_pDspCommPage->dwSampleRate = SWAP( dwNewSampleRate ); 379 380 ECHO_DEBUGPRINTF( ("C3gDco::SetSampleRate: %ld clock %lx\n", dwNewSampleRate, dwControlReg) ); 381 } 382 else 383 { 384 ECHO_DEBUGPRINTF( ("C3gDco::SetSampleRate: could not set sample rate %ld\n", dwNewSampleRate) ); 385 386 dwNewSampleRate = SWAP( m_pDspCommPage->dwSampleRate ); 387 } 388 389 return dwNewSampleRate; 390 391} // DWORD C3gDco::SetSampleRate( DWORD dwNewSampleRate ) 392 393 394 395//=========================================================================== 396// 397// SetDigitalMode 398// 399//=========================================================================== 400 401ECHOSTATUS C3gDco::SetDigitalMode 402( 403 BYTE byNewMode 404) 405{ 406 DWORD dwControlReg; 407 WORD wInvalidClock; 408 409 // 410 // See if the current input clock doesn't match the new digital mode 411 // 412 switch (byNewMode) 413 { 414 case DIGITAL_MODE_SPDIF_RCA : 415 case DIGITAL_MODE_SPDIF_OPTICAL : 416 wInvalidClock = ECHO_CLOCK_ADAT; 417 break; 418 419 case DIGITAL_MODE_ADAT : 420 wInvalidClock = ECHO_CLOCK_SPDIF; 421 break; 422 423 default : 424 wInvalidClock = 0xffff; 425 break; 426 } 427 428 if (wInvalidClock == GetInputClock()) 429 { 430 SetInputClock( ECHO_CLOCK_INTERNAL ); 431 SetSampleRate( 48000 ); 432 } 433 434 435 // 436 // Clear the current digital mode 437 // 438 dwControlReg = GetControlRegister(); 439 dwControlReg &= E3G_DIGITAL_MODE_CLEAR_MASK; 440 441 // 442 // Tweak the control reg 443 // 444 switch ( byNewMode ) 445 { 446 default : 447 return ECHOSTATUS_DIGITAL_MODE_NOT_SUPPORTED; 448 449 case DIGITAL_MODE_SPDIF_OPTICAL : 450 dwControlReg |= E3G_SPDIF_OPTICAL_MODE; 451 // fall through 452 453 case DIGITAL_MODE_SPDIF_RCA : 454 break; 455 456 case DIGITAL_MODE_ADAT : 457 dwControlReg |= E3G_ADAT_MODE; 458 dwControlReg &= ~E3G_DOUBLE_SPEED_MODE; 459 break; 460 } 461 462 // 463 // Write the control reg 464 // 465 WriteControlReg( dwControlReg, Get3gFreqReg(), TRUE ); 466 467 m_byDigitalMode = byNewMode; 468 469 ECHO_DEBUGPRINTF( ("C3gDco::SetDigitalMode to %ld\n", 470 (DWORD) m_byDigitalMode) ); 471 472 return ECHOSTATUS_OK; 473 474} // ECHOSTATUS C3gDco::SetDigitalMode 475 476 477 478//=========================================================================== 479// 480// WriteControlReg 481// 482//=========================================================================== 483 484ECHOSTATUS C3gDco::WriteControlReg 485( 486 DWORD dwControlReg, 487 DWORD dwFreqReg, 488 BOOL fForceWrite 489) 490{ 491 ECHOSTATUS Status; 492 493 ECHO_DEBUGPRINTF(("C3gDco::WriteControlReg 0x%lx 0x%lx\n",dwControlReg,dwFreqReg)); 494 495 // 496 // New value OK? 497 // 498 Status = ValidateCtrlReg(dwControlReg); 499 if (ECHOSTATUS_OK != Status) 500 return Status; 501 502 // 503 // Ready to go? 504 // 505 if ( !m_bASICLoaded ) 506 { 507 ECHO_DEBUGPRINTF(("C3gDco::WriteControlReg - ASIC not loaded\n")); 508 return( ECHOSTATUS_ASIC_NOT_LOADED ); 509 } 510 511 if ( !WaitForHandshake() ) 512 { 513 ECHO_DEBUGPRINTF(("C3gDco::WriteControlReg - no handshake\n")); 514 return ECHOSTATUS_DSP_DEAD; 515 } 516 517 // 518 // Write the control register 519 // 520 if ( fForceWrite || 521 (dwControlReg != GetControlRegister()) || 522 (dwFreqReg != Get3gFreqReg()) 523 ) 524 { 525 m_pDspCommPage->dw3gFreqReg = SWAP( dwFreqReg ); 526 SetControlRegister( dwControlReg ); 527 528 ECHO_DEBUGPRINTF( ("C3gDco::WriteControlReg: Setting 0x%lx, 0x%lx\n", 529 dwControlReg,dwFreqReg) ); 530 531 ClearHandshake(); 532 return SendVector( DSP_VC_WRITE_CONTROL_REG ); 533 } 534 else 535 { 536 ECHO_DEBUGPRINTF( ("C3gDco::WriteControlReg: not written, no change\n") ); 537 } 538 539 return ECHOSTATUS_OK; 540 541} // ECHOSTATUS C3gDco::WriteControlReg 542 543 544//=========================================================================== 545// 546// SetSpdifBits 547// 548//=========================================================================== 549 550void C3gDco::SetSpdifBits(DWORD *pdwCtrlReg,DWORD dwSampleRate) 551{ 552 DWORD dwCtrlReg; 553 554 dwCtrlReg = *pdwCtrlReg; 555 556 // 557 // Clean out the old status bits 558 // 559 dwCtrlReg &= E3G_SPDIF_FORMAT_CLEAR_MASK; 560 561 // 562 // Sample rate 563 // 564 switch (dwSampleRate) 565 { 566 case 32000 : 567 dwCtrlReg |= E3G_SPDIF_SAMPLE_RATE0 | 568 E3G_SPDIF_SAMPLE_RATE1; 569 break; 570 571 case 44100 : 572 if (m_bProfessionalSpdif) 573 dwCtrlReg |= E3G_SPDIF_SAMPLE_RATE0; 574 break; 575 576 case 48000 : 577 dwCtrlReg |= E3G_SPDIF_SAMPLE_RATE1; 578 break; 579 } 580 581 // 582 // Professional mode? 583 // 584 if (m_bProfessionalSpdif) 585 dwCtrlReg |= E3G_SPDIF_PRO_MODE; 586 587 // 588 // Non-audio data? 589 // 590 if (m_bNonAudio) 591 dwCtrlReg |= E3G_SPDIF_NOT_AUDIO; 592 593 // 594 // Always stereo, 24 bit, copy permit 595 // 596 dwCtrlReg |= E3G_SPDIF_24_BIT | E3G_SPDIF_TWO_CHANNEL | E3G_SPDIF_COPY_PERMIT; 597 598 *pdwCtrlReg = dwCtrlReg; 599 600} // SetSpdifBits 601 602 603//=========================================================================== 604// 605// SetSpdifOutNonAudio 606// 607// Set the state of the non-audio status bit in the S/PDIF out status bits 608// 609//=========================================================================== 610 611void C3gDco::SetSpdifOutNonAudio(BOOL bNonAudio) 612{ 613 DWORD dwControlReg; 614 615 m_bNonAudio = bNonAudio; 616 617 dwControlReg = GetControlRegister(); 618 SetSpdifBits( &dwControlReg, SWAP( m_pDspCommPage->dwSampleRate )); 619 WriteControlReg( dwControlReg, Get3gFreqReg() ); 620} 621 622 623//=========================================================================== 624// 625// Set the S/PDIF output format 626// 627//=========================================================================== 628 629void C3gDco::SetProfessionalSpdif 630( 631 BOOL bNewStatus 632) 633{ 634 DWORD dwControlReg; 635 636 m_bProfessionalSpdif = bNewStatus; 637 638 dwControlReg = GetControlRegister(); 639 SetSpdifBits( &dwControlReg, SWAP( m_pDspCommPage->dwSampleRate )); 640 WriteControlReg( dwControlReg, Get3gFreqReg() ); 641 642} // void C3gDco::SetProfessionalSpdif( ... ) 643 644 645//=========================================================================== 646// 647// ASIC status check 648// 649// 3G ASIC status check returns different values depending on what kind of box 650// is hooked up 651// 652//=========================================================================== 653 654BOOL C3gDco::CheckAsicStatus() 655{ 656 DWORD dwBoxStatus,dwBoxType; 657 658 if ( !WaitForHandshake() ) 659 { 660 ECHO_DEBUGPRINTF(("CheckAsicStatus - no handshake!\n")); 661 return FALSE; 662 } 663 664 // 665 // Send the vector command 666 // 667 m_pDspCommPage->dwExtBoxStatus = SWAP( (DWORD) E3G_ASIC_NOT_LOADED); 668 m_bASICLoaded = FALSE; 669 ClearHandshake(); 670 SendVector( DSP_VC_TEST_ASIC ); 671 672 // 673 // Wait for return from DSP 674 // 675 if ( !WaitForHandshake() ) 676 { 677 ECHO_DEBUGPRINTF(("CheckAsicStatus - no handshake after VC\n")); 678 m_pwDspCode = NULL; 679 m_ullLastLoadAttemptTime = 0; // so LoadFirmware will try again right away 680 return FALSE; 681 } 682 683 // 684 // What box type was set? 685 // 686 dwBoxStatus = SWAP(m_pDspCommPage->dwExtBoxStatus); 687 if (E3G_ASIC_NOT_LOADED == dwBoxStatus) 688 { 689 ECHO_DEBUGPRINTF(("CheckAsicStatus - ASIC not loaded\n")); 690 dwBoxType = NO3GBOX; 691 } 692 else 693 { 694 dwBoxType = dwBoxStatus & E3G_BOX_TYPE_MASK; 695 m_bASICLoaded = TRUE; 696 ECHO_DEBUGPRINTF(("CheckAsicStatus - read box type %x\n",dwBoxType)); 697 } 698 699 m_dwCurrentBoxType = dwBoxType; 700 701 // 702 // Has the box type already been set? 703 // 704 if (m_bBoxTypeSet) 705 { 706 // 707 // Did the ASIC load? 708 // Was the box type correct? 709 // 710 if ( (NO3GBOX == dwBoxType) || 711 (dwBoxType != m_dwOriginalBoxType) ) 712 { 713 ECHO_DEBUGPRINTF(("CheckAsicStatus - box type mismatch - original %x, got %x\n",m_dwOriginalBoxType,dwBoxType)); 714 return FALSE; 715 } 716 717 ECHO_DEBUGPRINTF(("CheckAsicStatus - ASIC ok\n")); 718 m_bASICLoaded = TRUE; 719 return TRUE; 720 } 721 722 // 723 // First ASIC load - determine the box type and set up for that kind of box 724 // 725 m_dwOriginalBoxType = dwBoxType; 726 m_bBoxTypeSet = TRUE; 727 728 SetChannelCounts(); 729 730 // 731 // Set the bad board flag if no external box 732 // 733 if (NO3GBOX == dwBoxType) 734 { 735 ECHO_DEBUGPRINTF(("CheckAsicStatus - no external box\n")); 736 m_bBadBoard = TRUE; 737 } 738 739 return m_bASICLoaded; 740 741} // BOOL C3gDco::CheckAsicStatus() 742 743 744//=========================================================================== 745// 746// SetPhantomPower 747// 748//=========================================================================== 749 750void C3gDco::SetPhantomPower(BOOL fPhantom) 751{ 752 DWORD dwControlReg; 753 754 dwControlReg = GetControlRegister(); 755 if (fPhantom) 756 { 757 dwControlReg |= E3G_PHANTOM_POWER; 758 } 759 else 760 { 761 dwControlReg &= ~E3G_PHANTOM_POWER; 762 } 763 764 WriteControlReg( dwControlReg, Get3gFreqReg() ); 765} 766 767 768//=========================================================================== 769// 770// Set channel counts for the current box type 771// 772//=========================================================================== 773 774void C3gDco::SetChannelCounts() 775{ 776 char *pszName; 777 WORD ch,i; 778 779 switch (m_dwOriginalBoxType) 780 { 781 case GINA3G : 782 m_wNumPipesOut = 14; 783 m_wNumPipesIn = 10; 784 m_wFirstDigitalBusOut = 6; 785 m_wFirstDigitalBusIn = 2; 786 787 pszName = "Gina3G"; 788 break; 789 790 791 case NO3GBOX : 792 case LAYLA3G : 793 default : 794 m_wNumPipesOut = 16; 795 m_wNumPipesIn = 16; 796 m_wFirstDigitalBusOut = 8; 797 m_wFirstDigitalBusIn = 8; 798 799 pszName = "Layla3G"; 800 break; 801 } 802 803 m_wNumBussesOut = m_wNumPipesOut; 804 m_wNumBussesIn = m_wNumPipesIn; 805 strcpy( m_szCardName, pszName); 806 807 // 808 // Build a channel mask for ADAT inputs & outputs 3-8 809 // OK to use bus # here since this hardware has no virtual outputs 810 // 811 m_Adat38Mask.Clear(); 812 ch = m_wFirstDigitalBusOut + 2; 813 for (i = 0; i < 6; i++) 814 { 815 m_Adat38Mask.SetIndexInMask(ch); 816 ch++; 817 } 818 819 ch += m_wFirstDigitalBusIn + 2; 820 for (i = 0; i < 6; i++) 821 { 822 m_Adat38Mask.SetIndexInMask(ch); 823 ch++; 824 } 825} 826 827 828//=========================================================================== 829// 830// Return the 3G box type 831// 832//=========================================================================== 833 834void C3gDco::Get3gBoxType(DWORD *pOriginalBoxType,DWORD *pCurrentBoxType) 835{ 836 if (NULL != pOriginalBoxType) 837 *pOriginalBoxType = m_dwOriginalBoxType; 838 839 if (NULL != pCurrentBoxType) 840 { 841 CheckAsicStatus(); 842 843 *pCurrentBoxType = m_dwCurrentBoxType; 844 } 845 846} // Get3gBoxType 847 848 849 850//=========================================================================== 851// 852// Fill out an ECHOGALS_METERS struct using the current values in the 853// comm page. This method is overridden for vmixer cards. 854// 855//=========================================================================== 856 857ECHOSTATUS C3gDco::GetAudioMeters 858( 859 PECHOGALS_METERS pMeters 860) 861{ 862 pMeters->iNumPipesOut = 0; 863 pMeters->iNumPipesIn = 0; 864 865 // 866 // Output 867 // 868 DWORD dwCh = 0; 869 WORD i; 870 871 pMeters->iNumBussesOut = (INT32) m_wNumBussesOut; 872 for (i = 0; i < m_wNumBussesOut; i++) 873 { 874 pMeters->iBusOutVU[i] = 875 DSP_TO_GENERIC( ((INT32) (INT8) m_pDspCommPage->VUMeter[ dwCh ]) ); 876 877 pMeters->iBusOutPeak[i] = 878 DSP_TO_GENERIC( ((INT32) (INT8) m_pDspCommPage->PeakMeter[ dwCh ]) ); 879 880 dwCh++; 881 } 882 883 pMeters->iNumBussesIn = (INT32) m_wNumBussesIn; 884 dwCh = E3G_MAX_OUTPUTS; 885 for (i = 0; i < m_wNumBussesIn; i++) 886 { 887 pMeters->iBusInVU[i] = 888 DSP_TO_GENERIC( ((INT32) (INT8) m_pDspCommPage->VUMeter[ dwCh ]) ); 889 pMeters->iBusInPeak[i] = 890 DSP_TO_GENERIC( ((INT32) (INT8) m_pDspCommPage->PeakMeter[ dwCh ]) ); 891 892 dwCh++; 893 } 894 895 return ECHOSTATUS_OK; 896 897} // GetAudioMeters 898 899 900 901//=========================================================================== 902// 903// Utility function; returns TRUE if double speed mode is set 904// 905//=========================================================================== 906 907BOOL C3gDco::DoubleSpeedMode(DWORD *pdwNewCtrlReg) 908{ 909 DWORD dwControlReg; 910 911 if (NULL == pdwNewCtrlReg) 912 dwControlReg = GetControlRegister(); 913 else 914 dwControlReg = *pdwNewCtrlReg; 915 916 if (0 != (dwControlReg & E3G_DOUBLE_SPEED_MODE)) 917 return TRUE; 918 919 return FALSE; 920} 921 922 923//=========================================================================== 924// 925// Utility function; validates a new control register value. Prevents 926// speed change while transport is running 927// 928//=========================================================================== 929 930ECHOSTATUS C3gDco::ValidateCtrlReg(DWORD dwNewControlReg) 931{ 932 BOOL fCurrDoubleSpeed,fNewDoubleSpeed; 933 934 // 935 // Return OK if transport is off 936 // 937 if (m_cmActive.IsEmpty()) 938 return ECHOSTATUS_OK; 939 940 // 941 // Get the new and current state of things 942 // 943 fNewDoubleSpeed = DoubleSpeedMode(&dwNewControlReg); 944 fCurrDoubleSpeed = DoubleSpeedMode(NULL); 945 946 // 947 // OK to change? 948 // 949 if (fCurrDoubleSpeed != fNewDoubleSpeed) 950 { 951 ECHO_DEBUGPRINTF(("Can't switch to speeds with transport active\n")); 952 return ECHOSTATUS_INVALID_CHANNEL; 953 } 954 955 return ECHOSTATUS_OK; 956} 957 958// **** C3gDco.cpp **** 959