The Tuner API is an abstract API for receiving radio broadcasts such as FM or DAB (provided that the necessary hardware is present on the phone). It provides a consistent API that is independent of the underlying implementation and hardware specifics.
The Tuner API can be used to perform tasks such as:
Create a CMMTunerUtility
object through which
tuner functionality can be accessed.
Tune into and search for a radio station.
Playback received audio signal.
Record received audio signal.
Access Radio Data System (RDS) metadata (only available on FM radio).
Applications wishing to use the Tuner API must include the
<tuner/tuner.h>
header for access to the relevant
declarations and link against tuner.lib
. To begin using the tuner
API, an instance of CMMTunerUtility
must be created using
CMMTunerUtility::NewL()
. This requires:
An implementation of the MMMTunerObserver
interface in the client for receiving notifications of tuner events. This
interface is defined in tuner.h
.
A unique index that identifies the tuner that is to be used.
Legal values are between 0 and
CMMTunerUtility::TunersAvailable()
-1 inclusive. A device
may contain more than one tuner so each tuner utility object relates to one
tuner.
An optional tuner access priority. The access priority defines
the priority for the client’s access to the tuner device. It is used to ensure
that applications using the radio as an alarm are not prevented from doing so
by other clients. The default value is
CMMTunerUtility::ETunerAccessPriorityNormal
. To select
higher priorities, applications need the MultimediaDD capability.
Note: The tuner access priority can also be changed
after construction using CMMTunerUtility::SetPriority()
but the same MultimediaDD capability restriction applies.
When an application has finished using the Tuner API it must delete
the CMMTunerUtility
instance. The destructor takes care of
stopping any ongoing recording or playback activity and powering down the tuner
hardware if no other clients need it. The following code shows an example of
the normal usage pattern:
CMMTunerUtility* iTunerUtil = CMMTunerUtility::NewL( … );
CleanupStack::PushL( iTunerUtil );
// add extra observers, configure tuner utility options
// tune / playback / record
CleanupStack::PopAndDestroy( iTunerUtil );
If the Tuner utility is to be reused at a later point then
CMMTunerUtility::Close()
can be used to free up resources
and the tuner hardware without actually destroying the Tuner utility.
Applications may need to receive notifications when the tuner’s state
changes. The MMMTunerChangeObserver
interface exists for
this purpose. The client receives notifications when:
The tuned frequency changes. This can occur when the client changes frequency or when other applications take control of the tuner and re-tune it.
The tuned channel changes.
The tuner state changes. The tuner states are: active, playing, recording and re-tuning.
The antenna is attached or detached. This is relevant for tuners that rely on an external antenna such as earphone cables.
The device enters or leaves flight mode.
Squelching is enabled or disabled. For more information on squelching, see Seeking for Stations.
To observe any of these notifications,
CMMTunerUtility::NotifyChange()
must be called and passed
to an implementation of the MMMTunerChangeObserver
interface.
Applications can optionally implement the
MMMSignalStrengthObserver
interface to monitor changes in
signal reception. The interface contains one function:
MMMSignalStrengthObserver::MssoSignalStrengthChanged()
:
This function is called when changes in signal strength occur. The amount of
change that triggers a notification depends upon the specific implementation.
Signal strength ranges from 0 to the value of
CMMTunerUtility::GetMaxSignalStrength()
. (The maximum
signal strength value is dependent upon the specific implementation). Note,
these values do not necessarily correspond to physical units such as db.
The MMMSignalStrengthObserver
can then be
registered with the Tuner utility via
CMMTunerUtility::NotifySignalStrength()
. To stop receiving
signal strength notifications call
CMMTunerUtility::CancelNotifySignalStrength()
.
Applications can optionally implement the
MMMTunerStereoObserver
interface to monitor when reception
switches from mono to stereo sound and vice-versa (as can happen with FM
radio). The interface contains two functions:
MMMTunerStereoObserver::MTsoStereoReceptionChanged()
:
This function indicates when stereo reception is lost or restored.
MMMTunerStereoObserver::MTsoForcedMonoChanged()
:
This function indicates when reception is forced to be mono, even when a stereo
signal is available.
The MMMTunerStereoObserver
can then be
registered with the Tuner utility via
CMMTunerUtility::NotifyStereoChange()
. To stop receiving
signal strength notifications call
CMMTunerUtility::CancelNotifyStereoChange()
.
Applications must request control of a tuner before using it to tune
into a particular station. This is to prevent multiple applications trying to
control the same tuner simultaneously. To gain control of a tuner, call
CMMTunerUtility::RequestTunerControl()
.
Control of the tuner is kept until it is explicitly released using
CMMTunerUtility::ReleaseTunerControl()
or it is revoked.
If control is revoked, a callback to
MMMTunerObserver::MToTunerEvent()
with an event type of
MMMTunerObserver::EControlEvent
and an error of
KErrAccessDenied
occurs.
To tune to a particular frequency the
CMMTunerUtility::Tune()
function is used. The required
frequency and band are specified by a TFrequency
object
which represents the frequency in Hertz and a value from the
CMMTunerUtility::TTunerBand
enum respectively.
For example, to tune to 100MHz FM:
const TInt KFreqHundredMHz = 100 * 1000000; // 100MHz
User::LeaveIfError( iTunerUtil->RequestTunerControl() );
TFrequency myFreq( KFreqHundredMHz );
iTunerUtil->Tune( myFreq, ETunerBandFM );
iTunerUtil->ReleaseTunerControl();
This is an asynchronous command and ultimately results in a callback
to MMMTunerObserver::MToTuneComplete()
. Additionally,
MMMTunerChangeObserver::MTcoFrequencyChanged()
is called
if a change observer has been registered (for more information, see
The Tuner Change Observer).
If no error has occurred then the error code passed to the callback
function is KErrNone
, if control of the tuner cannot be granted at
present KErrAccessDenied
is passed, otherwise one of the other
system-wide errors is passed.
If the client does not currently have control of the tuner, a request
for control is made (in the preceding example, the call to
CMMTunerUtility::RequestTunerControl()
could have been
omitted). If control of the tuner is granted then
MMMTunerObserver::MToTunerEvent()
is invoked with an event
type of MMMTunerObserver::EControlEvent
and an error of
KErrNone
.
Once control of the tuner has been granted, it is retained until
either a call to CMMTunerUtility::ReleaseTunerControl()
is
made or the session is pre-empted, in which case there is a callback to
MToTunerEvent
with an event type
MMMTunerObserver::EControlEvent
and an error value
KErrAccessDenied
.
A re-tune currently in progress can be interrupted by calling
CMMTunerUtility::CancelRetune()
. If
CMMTunerUtility::CancelRetune()
is called, the normal
callbacks do not occur. If no tune or seek operation is in progress, this
function has no effect.
The Tuner utility also allows searching for stations using the
asynchronous function CMMTunerUtility::StationSeek()
.
Searching for the next station signal starts from a given starting frequency
and stops when a station is found or when all frequencies have been searched
and nothing is found. When the next station is found (or nothing is found) a
callback to MMMTunerObserver::MToTuneComplete()
occurs
with the appropriate error value (KErrNotFound
if nothing is
found).
If the application needs to be notified of the frequency of the found station, a tuner change observer must be registered. For more information, see The Tuner Change Observer.
Control of the tuner must be requested, likewise, control is not
released once a station has been found. This is done via
CMMTunerUtility::ReleaseTunerControl()
when no further
control is required.
During a search, background noise may be heard at frequencies between
stations. Squelching mutes this noise and is enabled or disabled by calling
CMMTunerUtility::SetSquelch()
.
An ongoing seek operation can be interrupted using
CMMTunerUtility::CancelRetune()
.
The CMMTunerScannerUtility
class augments
CMMTunerUtility
to provide enhanced station scanning
functionality. CMMTunerScannerUtility
searches the
frequency spectrum, pausing for a specified amount of time when a station is
found.
A CMMTunerScannerUtility
instance is created by
using the CMMTunerUtility::GetTunerScannerUtilityL()
function of an instantiated Tuner utility. This function is passed an
implementation of MMMTunerObserver
which is used by the
scanner utility. Only one CMMTunerScannerUtility
instance
may be created per CMMTunerUtility
.
Tip: We recommend reusing the tuner observer passed to
the CMMTunerUtility
to avoid having to check for re-tune
notifications in several places.
The scanner utility provides two methods:
CMMTunerScannerUtility::StationScan()
: Scan
continuously for a radio station, pausing for the time specified before
continuing on to the next station. The starting position of the scan can be
specified as a frequency (in Hz) or digital channel number. Call
CMMTunerScannerUtility::StopScan()
to select the currently
tuned station.
CMMTunerScannerUtility::StopScan()
: Stop
scanning and use the currently tuned station.
The CMMTunerAudioPlayerUtility
class is used to
play audio from the tuner. It is created by calling the
CMMTunerUtility::GetTunerAudioPlayerUtilityL()
function of
an instantiated Tuner utility. This requires an implementation of the
MMMTunerAudioPlayerObserver
interface to monitor callbacks
from the player utility. Only one audio player utility may be created per Tuner
utility.
Before playing an audio signal, the player utility must be initialized
by calling CMMTunerAudioPlayerUtility::InitializeL()
. This
requires:
An audio priority: This is used to resolve conflicts when several
clients try to access the sound output device simultaneously. Requests for high
priorities may be denied depending on the audio policy settings of the device.
aAudioPriority
is an enumerated value of type
TMdaPriority
and legal values range from
EMdaPriorityMin
(-100) to EMdaPriorityMax
(100). The
normal priority is EMdaPriorityNormal
(0).
A priority preference: This defines the behaviour to be adopted by
an audio client if a higher priority client takes over the device.
aPref
is an enumerated value of type
TMdaPriorityPreference
.
The priority and preference can be changed at any time using
CMMTunerAudioPlayerUtility::SetPriority()
.
Once initialization has completed (successfully or otherwise) the audio
player observer receives a
MMMTunerAudioPlayerObserver::MTapoInitializeComplete()
callback. Audio playback can then be commenced using the utility’s
Play()
function and stopped with
Stop()
.
The CMMTunerAudioPlayerUtility
provides methods
to:
mute and unmute playback
start and stop playback
access and modify the current audio priority
access and modify the current volume, the interval between valid volume settings (ramp volume) and the maximum volume supported
access and modify the stereo balance
register for audio resource notifications, in the event that the audio resource is lost due to being pre-empted by a higher priority audio client
cancel an outstanding audio resource notification.
To register for notifications of when control of the audio resource is
lost or regained, use an implementation of the
MMMFAudioResourceNotificationCallback
interface.
The CMMTunerAudioRecorderUtility
class is used to
record audio from the tuner. It is created using the
CMMTunerUtility::GetTunerAudioRecorderUtilityL()
function
and an implementation of the MMMTunerAudioRecorderObserver
interface. Only one instance of a recorder utility may be created per Tuner
utility.
Before use the recorder utility must be initialized using
CMMTunerAudioRecorderUtility::InitializeL()
. This
requires:
A file or descriptor to which the recorded data is to be written.
The details of the required recording format.
The associated Multimedia Framework controller. For more information, see Multi Media Framework Client Overview.
An audio priority and priority preference. For more information, see Playback.
The CMMTunerAudioRecorderUtility
provides
functions for:
starting and stopping recordings
setting the gain
querying and changing the recording format, sample rate, metadata and so on
registering an implementation of the
MMMFAudioResourceNotificationCallback
interface for
monitoring control of the audio resource.
Note: Some recording settings cannot be changed once the recording has started.
RDS is the European standard for broadcasting data about a radio station within the FM frequency band (it is not supported by other frequency bands or broadcast systems). RDS data can be used to provide information such as the station name and the type of programme currently being broadcast. Its North American equivalent is RBDS.
The CMMRdsTunerUtility
class provides methods to
access the RDS capabilities of the tuner device. It supports both RDS and RBDS
standards.
To make use of the RDS capabilities of the tuner, construct a
CMMRdsTunerUtility
object using
CMMTunerUtility::GetRdsTunerUtilityL()
. Only one instance
of CMMRdsTunerUtility
may be created per instance of
CMMTunerUtility
.
RDS has a number of features, these include:
Programme type: For example, News, Sports, Classical Music and so on.
Clock time: Receives an up-to-date time signal from the radio station once every minute.
Radio text: Provides the current station’s name (known as the Programme Identifier) and short text messages (such as song names).
Regional links: Allows the tuner to automatically switch to local regional variations of the current station.
Alternative frequency: Provides the tuner with alternative frequencies for the currently tuned station. If the current signal becomes too weak it can automatically tune to one of the alternatives.
Traffic announcements: Automatically (re-)tunes to traffic announcements that are being broadcast (possibly by another station).
News announcements: Automatically (re-)tunes to news announcements that are being broadcast (possibly by another station).
To find which RDS features are supported by the current tuner call
CMMRdsTunerUtility::GetRdsCapabilities()
.
RDS features can be set on or off by calling the relevant Set
functions of CMMRdsTunerUtility
. For example,
CMMRdsTunerUtility::SetTrafficAnnouncement()
sets the
traffic announcement feature on or off.
Respective Get functions exist for querying which features are currently enabled.
Whenever an RDS feature changes, it causes a callback on a specific
method of the MMMRdsStateChangeObserver
class, for
example, changes to the announcement volume offset causes a callback on
MMMRdsStateChangeObserver::MrscoTrafficAnnouncementChanged()
.
To receive these change notifications an observer class must be set
up and associated with the CMMRdsTunerUtility
object. This
is done by calling
CMMRdsTunerUtility::NotifyRdsStateChange()
with a
reference to an MMMRdsStateChangeObserver
object that can
receive the notifications.
There are similar observer objects and associated notification
request methods (for example,
CMMRdsTunerUtility::NotifyAlternativeFrequencies()
) for
other aspects of the RDS Tuner utility’s operation.
CMMRdsTunerUtility
has a number of methods that
use RDS information to search for a radio station, using the following search
criteria:
RDS data
Programme Type
Programme Identifier
Traffic Programme
For example, to search for a radio station with a traffic programme:
myRdsTunerUtility->StationSearchByTrafficProgramme(ETrue, iFrequency,
ETunerBandFm, SearchDirectionUp , ETrue);
This returns the next radio station with a traffic programme. The
scanning starts at the frequency iFrequency
in the FM frequency
band, in the direction of increasing frequency. Because the parameter
aCircularSeek
is set to ETrue
, when the end of the
band is reached, the search will loop back to the beginning of the band.
The API of the Tuner utility can be extended in the following ways:
Via custom interfaces: These can be obtained by calling:
CMMTunerUtility::CustomInterface()
.
Via asynchronous and/or synchronous commands:
To send a synchronous custom command to the tuner, call the
method CMMTunerUtility::CustomCommandSync()
.
To send an asynchronous custom command to the tuner, call the
function CMMTunerUtility::CustomCommandAsync()
Custom commands specific to the audio player, audio recorder and RDS utilities may also be available.
Note: Details of any such extensions will be provided by the suppliers of the tuner implementation(s).