Analog Television Tuning

[The feature associated with this page, DirectShow, is a legacy feature. It has been superseded by MediaPlayer, IMFMediaEngine, and Audio/Video Capture in Media Foundation. Those features have been optimized for Windows 10 and Windows 11. Microsoft strongly recommends that new code use MediaPlayer, IMFMediaEngine and Audio/Video Capture in Media Foundation instead of DirectShow, when possible. Microsoft suggests that existing code that uses the legacy APIs be rewritten to use the new APIs if possible.]

Tuning is controlled by the TV Tuner filter, through the IAMTVTuner interface. The IAMTVTuner interface inherits IAMTuner. To obtain a pointer to the interface, call the ICaptureGraphBuilder2::FindInterface method as follows:

IAMTVTuner *pTuner = NULL;
hr = pBuild->FindInterface(
    &LOOK_UPSTREAM_ONLY,  // Look upstream from pCap.
    NULL,                 // No particular media type.
    pCap,                 // Pointer to the capture filter.
    IID_IAMTVTuner, (void**)&pTuner);
if (SUCCEEDED(hr))
{
    // Use pTuner ...
    pTuner->Release();
}

The first parameter indicates to search upstream from the capture filter.

Frequency Tables

Internally, the TV Tuner filter keeps a list of frequency tables. Each frequency table corresponds to the broadcast or cable frequencies for a given country/region. There is also a generic "Unicable" frequency table, which is used when a country/region does not have a standard set of frequency assignments.

Each frequency table contains a list of tuning frequencies. For some countries/regions, the indexes in the table correspond directly to channel numbers — in other words, the frequency for channel n is the n th entry in the table. For some countries/regions, however, there is no direct correspondence between channel numbers and frequencies. In that case, the application must keep a list that maps channel numbers (typically chosen by the user) to frequency table entries. For example, what the user sees as "channel 5" might be entry number 12 in the frequency table.

For details, see International Analog TV Tuning.

Basic Tuning Operations

If the tuner supports multiple reception modes, such as television and FM radio, call IAMTuner::put_Mode to select the mode. The IAMTuner::GetAvailableModes method returns all of the modes that the tuner supports. For example, the following code checks whether the tuner supports FM radio, and if so, switches to that mode.

// Check whether the mode is supported.
long lModes = 0;
hr = m_pTuner->GetAvailableModes(&lModes);
if (SUCCEEDED(hr) && (lModes & AMTUNER_MODE_FM_RADIO))
{
    // Set the mode.
    hr = pTuner->put_Mode(AMTUNER_MODE_FM_RADIO);
}

To set the country/region, call the IAMTuner::put_CountryCode method. The tuner uses this value to select the appropriate frequency table. See Country/Region Assignments for more information.

To set the channel, call the IAMTuner::put_Channel method. The argument to this method is actually not a channel number, but rather an index into the current frequency table. As described previously, the index number may or may not correspond to a channel number. The IAMTuner::ChannelMinMax method returns the minimum and maximum index values for the current frequency table.

Overriding Frequency Entries

It is possible that some entries in the frequency tables might be incorrect or become obsolete. Therefore, a mechanism is provided for overriding individual entries using registry keys.

The specifics are explained in the topic International Analog TV Tuning. Each registry key defines a "tuning space" which contains one or more subkeys. Each subkey overrides one frequency entry. To set the current tuning space, use the IAMTuner::put_TuningSpace method. Activating the tuning space overrides the frequency entries in the current frequency table. Therefore, it is up to the application to maintain a correspondence between tuning spaces and countries/regions. The best approach is simply to use the country/region identifier as the name of the tuning space.

Fine Tuning the Frequency Entries

Broadcast frequencies may be adjusted up or down several kHz by the broadcast station to reduce potential interference with neighboring channels. Given the nominal frequency, the tuner card can scan for the exact frequency. The TV Tuner filter has a mechanism for saving the adjusted frequencies in the registry.

For each entry in the frequency table, call the put_Channel method to tune to that frequency. The tuner will scan for the most precise frequency. You can check whether the tuner achieved a horizontal lock by calling IAMTuner::SignalPresent. The TV Tuner filter also stores the result internally.

After scanning all of the frequencies, call the IAMTVTuner::StoreAutoTune method to write the updated values into the registry. The updated values are stored under the registry entry for the current tuning space.

Analog Television