|
|
|
|
The Multimedia Tuner component (Radio Data System capable tuner) provides the features to control the tuner hardware present on a device. This overview shows you how to play and record the audio signals and scan for a specific radio station.
The Multimedia Tuner component uses the following components:
Multimedia Framework controller plug-in for formats and audio data types.
Media Device Framework-DevSound; the interface to the audio processing hardware for playback and recording functionality (audio input and output).
A tuner device converts antenna signals into analog audio and video signals and allows the user to select a specific broadcast channel, for example a radio station.
The Tuner API allows an application to access and control the tuner hardware present on the device. It allows you to:
create a Tuner utility object
(CMMTunerUtility) through which Tuner functionality is
accessed
tune to or search for a radio station
play the audio signal received on a channel (for example from a tuned-in radio station)
record the audio signal received on a channel
access the Radio Data System(RDS) data
Note: Refer to Access the RDS data for details.
call custom tuner functions.
CMMTunerUtility is the key class which provides
the tuner utility functionality. There are a number of additional tuner utility
classes which provide enhanced tuner functionality that are accessed through
CMMTunerUtility, such as
CMMTunerScannerUtility
CMMTunerAudioPlayerUtility
CMMTunerAudioRecorderUtility
CMMRdsTunerUtility.
To create an instance of these classes call the relevant factory
function. For example, call
CMMTunerUtility::GetTunerScannerUtilityL() to obtain an
instance of CMMTunerScannerUtility.
CMMTunerScannerUtility *scannerUtility =
pTunerUtility->GetTunerScannerUtilityL(iObserver);
where pTunerUtility is an object of type
CMMTunerUtility and iObserver is a reference
to the MMMTunerObserver object specified when
CMMTunerUtility was created.
Note: In some of the coding examples that follow, the identifier
pTunerUtility has the same meaning as above.
The following diagram shows the Tuner classes and their relationships.
The following sections describe in more detail how to use the Multimedia Tuner API.
The CMMTunerUtility class allows you to control
the tuner hardware on the device.
To use the tuner hardware, you need to first construct a Tuner
utility object using the CMMTunerUtility::NewL() method.
CMMTunerUtility *NewL(MMMTunerObserver &aObserver, TInt aTunerIndex, TTunerAccessPriority aAccessPriority=ETunerAccessPriorityNormal);
When constructing the Tuner utility object, provide a reference to an
MMMTunerObserver in the aObserver parameter
to receive notifications of tuner events.
The device might contain more than one tuner. A Tuner utility object
relates to one tuner and has a unique index associated with it. This index is
specified by the aTunerIndex parameter which takes a value between
0 and CMMTunerUtility::TunersAvailable() - 1.
The TTunerAccessPriority setting ensures that
the applications using the radio as an alarm sound are not prevented from doing
so by other clients. Access priority can be set at a later stage using
CMMTunerUtility::SetPriority(), to set this you need
MultimediaDD capability.
Note: In some of the coding examples that follow there is a data
member called iFrequency. This is of type
TFrequency and contains a station frequency in Hz. For
example:
TFrequency iFrequency(105.2*1000000); //Frequency of 105.2 MegaHertz
Basic functions supported by the Tuner utility
CMMTunerUtility include:
Tuning to a specified frequency or channel number using
Tune().
For example:
pTunerUtility->Tune(iFrequency, ETunerBandFm);
//Tune to 105.2 MHz in the FM band
Searching for a radio station at a specified frequency or channel
number in the given direction for a given tuner band using
CMMTunerUtility::StationSeek(). Before you start the
StationSeek() call
CMMTunerUtility::RequestTunerControl() to determine if a
search is possible. Once the search is complete, call
CMMTunerUtility::ReleaseTunerControl() to release the
tuner so that other clients can access the tuner hardware. See also 'Searching for a station'.
For example:
retVal = pTunerUtility->RequestTunerControl();
if (retVal == KErrNone) //Control granted
{
pTunerUtility->StationSeek(iFrequency, ETunerBandFm,ESearchDirectionUp, ETrue);
pTunerUtility->ReleaseTunerControl();
}
When the aCircularSeek parameter of StationSeek() is set to
ETrue, the station seek will loop back to the other end of the
band once the end of the band has been reached.
The CMMTunerUtility class provides advanced
station seek facilities as follows:
Enable or disable squelching using SetSquelch().
When squelching is enabled the background noise received at frequencies between
the broadcast stations is muted during a station search
Stop any playback or recording in progress, and release control
of the tuner using Close(). This allows any other clients in the
priority list to access the tuner hardware.
Whenever the state of the tuner changes (for example, when audio
playback stops) or the channel or the frequency changes, call
CMMTunerUtility::NotifyChange() to receive notification,
passing an MMMTunerChangeObserver object.
Note that the MMMTunerChangeObserver class needs
to be implemented to receive these change notifications from the tuner.
CMMTunerUtility provides the following tuner
related information:
The number of tuners available on a device, by calling
CMMTunerUtility::TunersAvailable()
A list of the capabilities supported by a specific tuner, by
calling CMMTunerUtility::GetCapabilities(). These include:
audio recording capability
simultaneous record and playback capability
whether the tuner needs an external antenna
whether RDS features are supported
whether the tuner is usable in flight mode.
The CMMTunerScannerUtility class provides
enhanced station scanning functionality. You can scan through a frequency band
or across channels, pausing for a specific amount of time when a station is
found and then resuming the scan.
To do this you need to first construct the scanner utility object
using the relevant factory function of the CMMTunerUtility
class:
CMMTunerScannerUtility *scannerUtility =
pTunerUtility-> GetTunerScannerUtilityL(iObserver);
where iObserver is a reference to the
MMMTunerObserver object specified when
CMMTunerUtility was created.
Only one CMMTunerScannerUtility object may be
created per instance of CMMTunerUtility.
The functions which support channel searching are as follows:
StationScan() to search for a specific channel. This
search can be initiated either from a specific frequency (in Hz) or by the
digital channel number of the tuner band.
StopScan() to stop scanning. This uses the currently
tuned radio station to play or record the audio signal.
Use the CMMTunerAudioPlayerUtility class to
initiate and control playback of audio from the tuner. First construct an audio
player utility object using the relevant factory function of the
CMMTunerUtility class:
CMMTunerAudioPlayerUtility* playerUtility = pTunerUtility-> GetTunerAudioPlayerUtilityL(iObserver);
Only one CMMTunerAudioPlayerUtility object may
be created per instance of CMMTunerUtility.
Before you start playing the audio signal from the tuner you need to
perform the initial set-up to link to the audio playback hardware in the
device, by calling
CMMTunerAudioPlayerUtility::InitializeL():
CMMTunerAudioPlayerUtility::InitializeL(TInt aAudioPriority=EMdaPriorityNormal, TMdaPriorityPreference aPref=EMdaPriorityPreferenceTimeAndQuality);
For example:
//Setup the tuner with highest priority and to be played with best quality
playerUtility->InitializeL(EMdaPriorityMax, EMdaPriorityPreferenceQuality);
aAudioPriority is an enumerated value of type
TMdaPriority and defines the priority for the
client’s access to the sound output device. It is used to resolve
conflicts when more than one client tries to access the sound output device
simultaneously. Its values are:
EMdaPriorityMin Lowest priority (–100) which
means that the client can be interrupted by any other client.
EMdaPriorityNormal Normal priority (0), which means
that the client can be interrupted only by higher priority clients.
EMdaPriorityMax Highest priority (100) which means
that the client cannot be interrupted by other clients.
The priority can be affected by the audio policy and high priorities can be denied.
aPref is an enumerated value of type
TMdaPriorityPreference which defines the behaviour to be
adopted by the tuner if a higher priority client takes over the sound output
device. In the example above the audio data is played at the best possible
quality (for example, it must not be degraded by muting or mixing). If a higher
priority client takes over, the radio playback is muted until the sound device
is available for exclusive use again.
Both these priority settings can be changed after initialization by
calling CMMTunerAudioPlayerUtility::SetPriority().
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 pre-emption by a higher priority audio client
cancel an outstanding audio resource notification.
Use the CMMTunerAudioRecorderUtility class to
record an audio signal from the tuner into a file or a descriptor. First create
a recorder utility object using the relevant factory function of the
CMMTunerUtility class:
CMMTunerAudioRecorderUtility *recorderUtility = pTunerUtility-> GetTunerAudioRecorderUtilityL(iObserver);
Only one CMMTunerAudioRecorderUtility object may
be created per instance of CMMTunerUtility.
Before you start recording the audio signal from the tuner, do the
initial set-up to connect to the audio recording hardware in the device by
calling CMMTunerAudioRecorderUtility::InitializeL().
//Set up the tuner to record with highest priority and with best quality
recorderUtility -> InitializeL(destinationRecordFilename,
destinationDataEncoding, recControllerUid, destinationFormatUid,
EMdaPriorityMax, EMdaPriorityPreferenceQuality);
The first parameter of the InitializeL() method,
TDesC
destinationRecordFilename is the name of a file
or a descriptor defining the destination where the recording would be done. The
next three parameters are respectively, the data type of the audio signal to be
recorded, the UID of the controller used for recording and the identifier for
the recording format.
The last two parameters EMdaPriorityMax and
EMdaPriorityPreferenceQuality are as in
CMMTunerAudioPlayerUtility::InitializeL().
CMMTunerAudioRecorderUtility provides methods
to:
start recording of the tuner output using Record()
pause the recording. Recording can be resumed with another call to Record()
stop recording, and release the output device for use by other clients by calling Stop()
access the maximum value for the gain. The gain can be any value
from zero to the value returned by a call to MaxGain(). A value
which is less than zero is set to zero. A value which is greater than
MaxGain() is set to MaxGain()
register for audio resource notifications
cancel an outstanding audio resource notification
return a list of the following:
the supported data types for the record destination
the supported bit rates for recording.
access and modify the following:
the data type of the destination audio clip
the bit rate for recording
the sample rate for the record destination
the format of the audio clip
the number of channels for the recorded audio clip.
Note that the above need to be set before starting to record.
access and modify the following:
the gain for the audio device
the current recording balance
the current audio priority
the metadata in the current clip
RDS (Radio Data System) is the European standard for broadcasting data about a radio station within the FM frequency band. This data can be used to provide information on an electronic screen, 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 the relevant factory
function of the CMMTunerUtility class:
CMMRdsTunerUtility *pRdsTunerUtility = pTunerUtility-> GetRdsTunerUtilityL(iObserver);
Only one CMMRdsTunerUtility object may be
created per instance of CMMTunerUtility.
RDS has a number of features; these include:
Traffic announcement
Regional links
News announcement
Programme type (for example: News, Sports, Classical Music, etc.)
Clock time
Alternative frequency
Radio text
To find out the available RDS features call
CMMRdsTunerUtility::GetRdsCapabilities():
RDS features can be set on or off by calling the relevant
SetXxxx() methods of CMMRdsTunerUtility. For
example, CMMRdsTunerUtility::SetTrafficAnnouncement() sets
the traffic announcement feature on or off depending on the value of the
boolean parameter passed:
//Turn on the RDS traffic announcement function
errorCode = pRdsTunerUtility->SetTrafficAnnouncement(ETrue);
The above example sets the 'Traffic Announcement' feature on.
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 by
calling CMMRdsTunerUtility::NotifyRdsStateChange().
errorCode = pRdsTunerUtility->NotifyRdsStateChange(iRdsStateChangeObserver);
where iRdsStateChangeObserver is a reference to an
MMMRdsStateChangeObserver object that will receive the
notifications.
There are similar observer objects and associated notification
request methods (NotifyXXX()) 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, this is how to search for a radio station with a traffic programme:
pRdsTunerUtility->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 CMMTunerUtility can
be customised as follows:
it can be provided with custom interfaces via a tuner plugin.
it can have synchronous or asynchronous custom commands.
To obtain a custom interface from the tuner plugin, call the method
CMMTunerUtility::CustomInterface().
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()
The CMMTunerAudioPlayerUtility and
CMMTunerAudioRecorderUtility classes may also have
synchronous or asynchronous custom commands that are invoked using methods with
the same names as those of CMMTunerUtility.
A controller plug-in supports playing or recording one or more multimedia formats for a media type, such as audio.
To get the array of play or record formats supported by the
controller, call
CMMTunerAudioRecorderUtility::ControllerImplementationInformationL().
If no controller is in use, the function call leaves with an error. For more
information on the controller plugins refer to
How to write a controller plugin.