btcard.cpp

来自「一个开放源码的bt848/878驱动程序的源码」· C++ 代码 · 共 1,724 行 · 第 1/5 页

CPP
1,724
字号
					m_ksCurrentTunerStandard = ksStandard;

					// And that we changed things successfully.
					st = STATUS_SUCCESS;

				} else {

					DUMP(("TunerChip[%d] does NOT support standard %08X, supported are %08X\n",Idx,ksStandard,TunerChip[Idx]->TVTunerVideoStandardsSupported()));
				}
			} else {
				DUMP(("TunerChip[%d] can NOT tune TV!\n", Idx));
			}
		}

		// If we were able to change...
		if ( st == STATUS_SUCCESS ) {

			// Inform of the video norm change...
			for (Idx = 0 ; Idx < AudioCount ; Idx ++) {
				AudioChip[Idx]->VideoStandardChanged(ksStandard);
			}
			
			// Now, Inform the audioChips that Channel has Changed ...
			for (Idx = 0 ; Idx < AudioCount ; Idx ++) {
				AudioChip[Idx]->ChannelChanged();
			}
		}

	} else {
		st = STATUS_SUCCESS;
	}

	DUMP(("Returning status %d, current standard %d, requested standard %d\n", st, m_ksCurrentTunerStandard, ksStandard));
	return st;
}

NTSTATUS BtCard::TunerSetMode( ULONG Mode )
{
	HwTuner::TunerMode tm = HwTuner::Tm_TV;

	// Translate from WDM to our internal form
	switch (Mode) {
		case 0: // This is the DEFAULT mode based on DirectShow Docs (feature not documented on ntddk)
		case KSPROPERTY_TUNER_MODE_TV:
			tm = HwTuner::Tm_TV;
			break;
		case KSPROPERTY_TUNER_MODE_AM_RADIO:
			tm = HwTuner::Tm_Radio_AM;
			break;
		case KSPROPERTY_TUNER_MODE_FM_RADIO:
			tm = HwTuner::Tm_Radio_FM;
			break;
		default:
			return STATUS_INVALID_PARAMETER;
	}

	// Only do if really changing mode !
	if (m_CurrentTunerMode != tm) {

		// Remember new Tuner Mode
		m_CurrentTunerMode = tm;

		// Make things easier : Despite WDM does not differenciate between Radio and TV tuner, we do, so remember mode 
		if (tm == HwTuner::Tm_TV || m_bTVAudioUsedForFM) {
			// TV Tuner mode
			TunerConnector = AudioConTuner;
		} else {
			// Radio Tuner mode
			TunerConnector = AudioConRadio;
		}

		// Switch to appropiate connector if Tuner is selected
		if ((AudioMux == AudioConTuner ||
			AudioMux == AudioConRadio) && 
			!bAudioMuted ) {

			// Set the correct connector for Tuner!
			AudioMux = TunerConnector;

			// Get card information
			CInfo* Info = GetCardInfo(); 

			// Enable the corresponding GPIO pins to select audio sources...
			GetBtPisces().SetGPOE( GetBtPisces().GetGPOE() | Info->gpoe );

			// Set the correct bits to enable the Line Source
			ULONG Val;
			GetBtPisces().GetGPDATA(&Val,1,0);
			Val &= ~Info->gpoe;							// Keep all bits not involved into audio switching: all the others set to 0
			Val |=  Info->gpoe & Info->audiomux[AudioMux];	// And select the audio source without disrupting the other bits...
			GetBtPisces().SetGPDATA(&Val,1,0);

			// Now, For all the AudioChips, set the input!
			for (DWORD Idx = 0 ; Idx < AudioCount ; Idx ++) {
				AudioChip[Idx]->SetAudioConnector(AudioMux);
			}

		}

		// Now, Set the mode!
		// Based on mode requested, select the adequate handler )a possible IF change makes this a must...)
		switch (m_CurrentTunerMode) {
			case HwTuner::Tm_TV: 
				{
					// Find the right chip
					for (DWORD Idx = 0 ; Idx < TunerCount ; Idx ++) {
						if (TunerChip[Idx]->CanTuneTV()) {
							// This one should work ...
							ULONG RealFreq = TunerChip[Idx]->SetFrequency(m_ksCurrentTunerStandard,m_CurrentTunerMode,m_CurrentTunerFrequency,HwTuner::Tm_Fine);
							if (RealFreq) {
								m_CurrentTunerFrequency = RealFreq;
							}
							m_TunerSignalDetected = (RealFreq != 0);
						}
					}
				}
				break;
			case HwTuner::Tm_Radio_AM: 
				{
					// Find the right chip
					for (DWORD Idx = 0 ; Idx < TunerCount ; Idx ++) {
						if (TunerChip[Idx]->CanTuneAM()) {
							// This one should work ...
							ULONG RealFreq = TunerChip[Idx]->SetFrequency(m_ksCurrentTunerStandard,m_CurrentTunerMode,m_CurrentTunerFrequency,HwTuner::Tm_Fine);
							if (RealFreq) {
								m_CurrentTunerFrequency = RealFreq;
							}
							m_TunerSignalDetected = (RealFreq != 0);
						}
					}
				}
				break;
			case HwTuner::Tm_Radio_FM: 
				{
					// Find the right chip
					for (DWORD Idx = 0 ; Idx < TunerCount ; Idx ++) {
						if (TunerChip[Idx]->CanTuneFM()) {
							// This one should work ...
							ULONG RealFreq = TunerChip[Idx]->SetFrequency(m_ksCurrentTunerStandard,m_CurrentTunerMode,m_CurrentTunerFrequency,HwTuner::Tm_Fine);
							if (RealFreq) {
								m_CurrentTunerFrequency = RealFreq;
							}
							m_TunerSignalDetected = (RealFreq != 0);
						}
					}
				}
				break;
		}
		// Now, Inform the audioChips that Channel has Changed ...
		for (DWORD Idx = 0 ; Idx < AudioCount ; Idx ++) {
			AudioChip[Idx]->ChannelChanged();
		}
		return STATUS_SUCCESS;
	} 
	return STATUS_SUCCESS;
}

ULONG BtCard::TunerGetMode()
{
	// Translate from our internal form to WDM
	switch (m_CurrentTunerMode) {
		default:
		case HwTuner::Tm_TV:
			return KSPROPERTY_TUNER_MODE_TV;
		case HwTuner::Tm_Radio_AM:
			return KSPROPERTY_TUNER_MODE_AM_RADIO;
		case HwTuner::Tm_Radio_FM:
			return KSPROPERTY_TUNER_MODE_FM_RADIO;
	}
	return KSPROPERTY_TUNER_MODE_TV;
}

// Get capabilities for a given mode
NTSTATUS BtCard::TunerGetModeCaps( PKSPROPERTY_TUNER_MODE_CAPS_S pCaps)
{
	switch (pCaps->Mode) {
		case KSPROPERTY_TUNER_MODE_TV:
			{
				// Look for the first tuner that handles this ... And Get Caps!
				for (DWORD Idx = 0 ; Idx < TunerCount ; Idx ++) {
					if (TunerChip[Idx]->CanTuneTV()) {
						// This one should work ...
						TunerChip[Idx]->TVTunerCaps(
							pCaps->MinFrequency,pCaps->MaxFrequency,
							pCaps->TuningGranularity,pCaps->SettlingTime);
						pCaps->StandardsSupported = TunerChip[Idx]->TVTunerVideoStandardsSupported();
						return STATUS_SUCCESS;
					}
				}
				break;
			}
		case KSPROPERTY_TUNER_MODE_AM_RADIO:
			{
				// Look for the first tuner that handles this ... And Get Caps!
				for (DWORD Idx = 0 ; Idx < TunerCount ; Idx ++) {
					if (TunerChip[Idx]->CanTuneAM()) {
						// This one should work ...
						TunerChip[Idx]->AMTunerCaps(
							pCaps->MinFrequency,pCaps->MaxFrequency,
							pCaps->TuningGranularity,pCaps->SettlingTime);
						pCaps->StandardsSupported = 0;
						return STATUS_SUCCESS;
					}
				}
				break;
			}
		case KSPROPERTY_TUNER_MODE_FM_RADIO:
			{
				// Look for the first tuner that handles this ... And Get Caps!
				for (DWORD Idx = 0 ; Idx < TunerCount ; Idx ++) {
					if (TunerChip[Idx]->CanTuneFM()) {
						// This one should work ...
						TunerChip[Idx]->FMTunerCaps(
							pCaps->MinFrequency,pCaps->MaxFrequency,
							pCaps->TuningGranularity,pCaps->SettlingTime);
						pCaps->StandardsSupported = 0;
						return STATUS_SUCCESS;
					}
				}
				break;
			}
	}
	return STATUS_INVALID_PARAMETER;
}



NTSTATUS BtCard::TunerSetFrequency(	DWORD Frequency ,KS_TUNER_TUNING_FLAGS tf)			// Frequency of channel
{
	TRACE(("BtCard::TunerSetFrequency"));

	// Translate the Tuning Method
	HwTuner::TuningMethod method = HwTuner::Tm_Fine;

	DUMP(("  Frequency requested %d, using tuning flags %d\n",
		Frequency, tf ));

	// This should be in this way, but the Default TV tuner dialog box does not 
	// pass KS_TUNER_TUNING_FINE, so we will have to add some workarounds...
	if (tf == KS_TUNER_TUNING_COARSE) {
		method = HwTuner::Tm_Coarse;
	} else if (tf == KS_TUNER_TUNING_EXACT) {
		method = HwTuner::Tm_Exact;
	}


	// Remember the current tuning method...
	m_TunerCurrMethod = tf;

	// Only set Frequency if frequency and/or tuning mode has really changed!
	if (Frequency != m_CurrentTunerFrequency || method != m_TunerLastMethod) {

		// Remember last tuning method
		m_TunerLastMethod = method;

		// Remember muted state and mute
		BOOL PrevMuted = bAudioMuted;
		AudioMute();

		// Based on mode requested, select the adequate handler
		switch (m_CurrentTunerMode) {
			case HwTuner::Tm_TV: 
				{
					// Find the right chip
					for (DWORD Idx = 0 ; Idx < TunerCount ; Idx ++) {
						if (TunerChip[Idx]->CanTuneTV()) {
							// This one should work ...
							ULONG RealFreq = TunerChip[Idx]->SetFrequency(m_ksCurrentTunerStandard,m_CurrentTunerMode,Frequency,method);

							// Delay to allow the video signal to stabilise
							mdelay( 35 );

							// If the requested method isn't fine tuning, but we locked on a signal
							// then tune again with fine tuning but only when the new tuning
							// has been selected
							if (method != HwTuner::Tm_Fine && IsHLocked() ) {
								DUMP(( "SetFrequency found signal lock, fine tuning\n" ));
								RealFreq = TunerChip[Idx]->SetFrequency(m_ksCurrentTunerStandard,m_CurrentTunerMode,Frequency,HwTuner::Tm_Fine );
							}

							if (RealFreq) {
								m_CurrentTunerFrequency = RealFreq;
							} else {
								m_CurrentTunerFrequency = Frequency;
							}
							m_TunerSignalDetected = (RealFreq != 0);
						}
					}
				}
				break;
			case HwTuner::Tm_Radio_AM: 
				{
					// Find the right chip
					for (DWORD Idx = 0 ; Idx < TunerCount ; Idx ++) {
						if (TunerChip[Idx]->CanTuneAM()) {
							// This one should work ...
							ULONG RealFreq = TunerChip[Idx]->SetFrequency(m_ksCurrentTunerStandard,m_CurrentTunerMode,Frequency,method);
							if (RealFreq) {
								m_CurrentTunerFrequency = RealFreq;
							} else {
								m_CurrentTunerFrequency = Frequency;
							}
							m_TunerSignalDetected = (RealFreq != 0);
						}
					}
				}
				break;
			case HwTuner::Tm_Radio_FM: 
				{
					// Find the right chip
					for (DWORD Idx = 0 ; Idx < TunerCount ; Idx ++) {
						if (TunerChip[Idx]->CanTuneFM()) {
							// This one should work ...
							ULONG RealFreq= TunerChip[Idx]->SetFrequency(m_ksCurrentTunerStandard,m_CurrentTunerMode,Frequency,method);
							if (RealFreq) {
								m_CurrentTunerFrequency = RealFreq;
							} else {
								m_CurrentTunerFrequency = Frequency;
							}
							m_TunerSignalDetected = (RealFreq != 0);
						}
					}
				}
				break;
		}

		// If previously unmuted, unmute now!
		if (!PrevMuted) {
			AudioUnmute();
		}

		// Now, Inform the audioChips that Channel has Changed ...
		for (DWORD Idx = 0 ; Idx < AudioCount ; Idx ++) {
			AudioChip[Idx]->ChannelChanged();
		}

	}
	return STATUS_SUCCESS;
}

// Power management
NTSTATUS BtCard::PowerDown()
{
	

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?