Recording

Recording is made possible through the CMdaAudioRecorderUtility class. In addition to recording in different audio formats, this class also offers a playback facility. While this can save resources, by removing the need to instantiate a separate player object, use of one of the player objects discussed later in this section, such as CMdaAudioPlayerUtility, is recommended for dedicated playback.

In terms of physical storage, recording can take place to a file, a descriptor and in Series 60 2.x, a URL. Recording is essentially a three-stage process of gaining a handle to a data store, setting the desired configurations and then recording.

Accessing the data store and physically recording are asynchronous operations, and the MMdaObjectStateChangeObserver::MoscoStateChangeEvent() function informs applications of the completion of each operation. This architecture requires the class calling the asynchronous functions to derive from MMdaObjectStateChangeObserverand implement MoscoStateChangeEvent().

The AnsPhone example application has a class CAnsPhoneEngine, which derives from MMdaObjectStateChangeObserverand implements MoscoStateChangeEvent():

IView full width!

class CAnsPhoneEngine : public CBase, public MMdaObjectStateChangeObserver, public MAnsPhoneTimerObserver, public MAnsPhoneCallWatcherObserver, public MAnsPhoneCallMakerObserver, public MAnsPhoneCallLogObserver public: // MMdaObjectStateChangeObserver virtual void MoscoStateChangeEvent(CBase* aObject, Tint aPreviousState, Tint * aCurrentState, Tint aErrorCode);

CMdaAudioRecorderUtility* ¡Sound;

// Recording message settings TMdaFileClipLocation ¡MessageLocation; TMdaAudioDataSettings ¡MessageSettings; TMdaWavClipFormat ¡MessageFormat; TMdaPcmWavCodec ¡MessageCodec;

CMdaAudioRecorderUtility provides an OpenL() function that opens a channel to the data store that should be used as the destination for the recording or, if the class is being employed for playback, the audio data that will be played. As the correct codec for handling raw audio data cannot be selected automatically, an explicit reference to a codec may be necessary.

In addition to OpenL(), functions are also available for specific destination types. Series 60 1.x offers OpenFileL()and OpenDesL() for files and descriptors, respectively, while Series 60 2.x also hasOpenUrlL().

In the AnsPhone application, CMdaAudioRecorderUtility::OpenL() is used in the RecordMessageL() method:

¡Sound = CMdaAudioRecorderUtility::NewL(*this);

¡Sound->OpenL(&iMessageLocation, &iMessageFormat, &iMessageCodec, &iMessageSettings);

Once the open operation has completed, the function MoscoStateChangeEvent() (from the MMdaObjectStateChangeObservermixin) will be called.

Before recording, a variety of configuration settings are available, including: volume, sample rate and balance. These settings are extensively covered in the SDK documentation. The AnsPhone application sets the gain, volume and recording position before recording.

Once the required configuration is set, CMdaAudioRecorderUtility::RecordL() can be invoked, remembering that MoscoStateChangeEventQ will be called once more when recording has finished:

[View full widthl void CAnsPhoneEngine::MoscoStateChangeEventl_(CBase* /*aObject*/, Tint /*aPreviousState*/, * Tint aCurrentState, Tint aErrorCode)

case ERecordlnit: // Record from the telephony line // and set to max gain if (ilsLocal) {

¡Sound->SetAudioDeviceMode(CMdaAudioRecorderUtility::ELocal);

¡Sound->SetAudioDeviceMode(CMdaAudioRecorderUtility::ETelephonyNonMixed); Tint maxGain = ¡Sound->MaxGain();

// Delete current audio sample from beginning of file

¡Sound->SetPosition(TTimelntervalMicroSeconds(0)); iSound->CropL();

// start recording ¡Sound->RecordL(); ¡State = E Record; break;

Note that the above function is actually called from MoscoStateChangeEvent() within a trap harness, as it may

Another important consideration is the tdeviceMode enumeration, which determines how the audio device handles playback and recording. This enumeration is defined in the file \epoc32\include\MdaAudioSampleEditor.h in the root directory of your SDK. Table 11-14 examines the options available.

Table 11-14. Audio Device Modes

Enumeration Value

Effect

If a call Is currently taking place, then the line and the device microphone will be recorded, and playback will be made down the line.

If there Is no call, then the device microphone will be recorded, and playback will be through the device speaker.

ETelephonyOrLocal = EDefault

As with EDefault.

ETelephonyMixed = 1

If a call is in progress, then the audio source is the device microphone, mixed with the telephony line. Playback will be both through the device speaker and down the phone line.

If there is no call, then recording is not attempted to the device microphone, and playback will not take place to the device speaker.

ETelephonyNonMixed = 2

If there is a call in progress, then only the telephone line is used for recording and playback—it is not mixed with the device microphone or speaker.

ELocal = 3

The telephone line is ignored. The device microphone will be recorded, and the device speaker is used for playback.

WAR NINO

There is a known issue with Series 60 1.x and some early devices—the default mode will always be used by CMdaAudioRecorderUtility, despite any values passed into SetAudioDeviceMode(). An up-to-date list of known Series 60 issues can be found at www.forum.nokia.com.

Although primarily used for recording, as highlighted earlier, CMdaAudioRecorderUtility can be used for playback purposes. Opening the data source and configuring the playback options are the same as for recording; however, the CMdaAudioRecorderUtility::PlayL() function is used to play the audio data.

[View full widthl void CAnsPhoneEngine::MoscoStateChangeEventl_(CBase* /*aObject*/, Tint /*aPreviousState*/, * Tint aCurrentState, Tint aErrorCode)

case EPIaylnit: {

// Play through the device speaker // and set to max volume if (ilsLocal) {

¡Sound->SetAudioDeviceMode(CMdaAudioRecorderUtility::ELocal); }

¡Sound->SetAudioDeviceMode(CMdaAudioRecorderUtility::ETelephonyOrLocal); }

¡Sound->SetVolume(iSound->MaxVolume());

// Set the playback position to the start

¡Sound->SetPosition(TTimelntervalMicroSeconds(0)); iSound->PlayL();

0 0

Post a comment

  • Receive news updates via email from this site