The audio input stream interface class,
CMdaAudioInputStream
, enables MMF client applications to:
stream audio data from the low level audio controller (which has collected it from a hardware device, such as a microphone) to specified buffers (record audio).
specify the priority of the audio stream relative to other clients trying to use the same audio hardware
set the sample rate and the number of channels to use for recording.
change the gain and channel balance of the input stream.
The low level audio controller stores the audio data in buffers.
CMdaAudioInputStream
reads these buffers incrementally and
does not have to wait until capture is complete.
Typically, using an audio input stream involves the following steps as shown in the sequence diagram below:
The client application creates an audio input stream object using the
static function CMdaAudioInputStream::NewL()
. The input
stream class provides two versions of the constructor: one with the default
priority and preferences, and another with specified priority and preferences.
The client application must also implement the observer class
MMdaAudioInputStreamCallback
to notify it about audio
input streaming progress.
The following code constructs an audio input stream:
CMdaAudioInputStream* aInputStream;
aInputStream = CMdaAudioInputStream::NewL(aCallback, EMdaPriorityNormal, EMdaPriorityPreferenceTimeAndQuality);
where, aCallback
is an
MMdaAudioInputStreamCallback
object.
To open an input stream, use the Open()
member
function, which provides a pointer to the TMdaPackage
object with the required audio settings. You can also open the stream without
the audio settings. For example:
aInputStream->Open(NULL);
Once the stream is open, a
MMdaAudioInputStreamCallback::MaiscOpenComplete()
is
issued to indicate that the stream is ready for use.
void CIOStreamAudio::MaiscOpenComplete(TInt aError)
{
ASSERT(iState==EStateOpeningInput);
if (aError!=KErrNone)
{
Complete(aError);
}
else
{
iMainBuffer.Zero();
iState = EStateReading;
ReadNextBlock(KNullDesC8); // kick off a new read - KNullDesC8 for first buffer
}
}
CMdaAudioInputStream
member functions get and
set the properties of the audio input stream.
To set the sampling rate and number of audio channels, use the
SetAudioPropertiesL()
member function. You can do this
only if the stream is open and if data is not being streamed. Values must be
specified as enum values. For example,
TMdaAudioDataSettings::ESampleRate8000Hz
and not
8000
(Hz). The following code sets the sampling rate to 8000Hz and
audio channel to mono:
aInputStream->SetAudioPropertiesL(TMdaAudioDataSettings::ESampleRate8000Hz,TMdaAudioDataSettings::EChannelsMono));
The Gain()
and
GetBalanceL()
member functions let you determine the
current gain and balance settings.
The SetGain()
and
SetBalanceL()
member functions let you set the gain and
balance respectively. You can use them while the stream is open, with the new
settings taking immediate effect.
To record the audio stream, use the ReadL()
member function, specifying the buffer to use. The first
ReadL()
after a successful Open()
,
starts audio recording. Once the buffer is successfully recorded, a pointer to
it is returned by
MMdaAudioInputStreamCallback::MaiscBufferCopied()
callback.
void CIOStreamAudio::MaiscBufferCopied(TInt aError, const TDesC8& aBuffer)
{
ASSERT(iState==EStateReading);
if (aError!=KErrNone)
{
if (aError!=KErrAbort) // aborts happen on Stop as buffers are recovered, need to ignore
{
Complete(aError);
}
}
else
{
ReadNextBlock(aBuffer);
}
}
The following code reads the next audio block into the buffer in an array of descriptors:
void CIOStreamAudio::ReadNextBlock(const TDesC8& aBuffer)
{
ASSERT(iState==EStateReading);
// buffer will be tail of iMainBuffer. Shift latter's length and get the next bit
TInt lengthRecorded = iMainBuffer.Length()+aBuffer.Length();
iMainBuffer.SetLength(lengthRecorded);
iBufferPtr.Set(const_cast<TUint8*>(iMainBuffer.Ptr())+lengthRecorded, 0, iMainBuffer.MaxLength()-lengthRecorded);
TRAPD(error, iInputStream->ReadL(iBufferPtr));
if (error!=KErrNone)
{
Complete(error);
}
}
To stop recording the audio stream, use the
Stop()
member function. Two callbacks are issued after a
Stop()
.
An
MMdaAudioInputStreamCallback::MaiscBufferCopied()
pointing
to a buffer that contains the last of the recorded audio data (and an
aError
value of KErrAbort
).
An
MMdaAudioInputStreamCallback::MaiscRecordComplete()
,
indicating successful closure of the audio stream.
void CIOStreamAudio::MaiscRecordComplete(TInt aError)
{
ASSERT(iState==EStateReading && aError!=KErrNone);
Complete(aError);
}