You Are Here:

Community: Wiki

This page was last modified on 6 September 2009, at 18:39.

Playing PCM audio streams

From Forum Nokia Wiki

Reviewer Approved   


The CStreamPlayer illustrates how to play PCM encoded audio streams using CMdaAudioOutputStream. The audio needs to be PCM encoded data supplied via byte buffer. If you want to use other formats you need to convert the data to PCM before playing it with the CMdaAudioOutputStream.

CMdaAudioOutputStream requires the player class to implement MMdaAudioOutputStreamCallback callback interface. The MaoscOpenComplete method is called when the construction for the output stream is completed. Playing should never be started until this method has been called by the output stream object.

As shown in the example implementation for the MaoscOpenComplete after setting the final settings the stream is played by calling the WriteL method of the output stream. Calling the method with the PCM buffer will cause the output stream to play the buffer, and after the buffer is played MaoscBufferCopied will be called. Then a new buffer is set for playing by calling the WriteL method again and also new data is copied to be ready for the next call of the MaoscBufferCopied method.

Remarks:

  1. Note this Known Issue about the function of MaoscPlayComplete. Essentially it is not getting called if the stream runs out of buffers on the device (though, confusingly, it is called on the emulator). So you need other workarounds to find out when the last sample of your stream has played.
  2. Keeping the stream open after the last buffer has been played, rather than calling Stop() or destroying it, will leave the audio hardware turned on. This will lead to a severe reduction in battery life on most devices. So you should make sure to stop the stream if you are not planning to play audio for more than a few seconds.


Stream_Play.cpp

CStreamPlayer::CStreamPlayer(void)
:iVolume(10),iReadSize(0),iPlayError(KErrNone)
{
}
 
CStreamPlayer::~CStreamPlayer()
{
Stop();
 
delete iStream;
iStream = NULL;
 
delete iPlayBuffer;
iPlayBuffer = NULL;
 
iBuffer.ResetAndDestroy();
}
 
void CStreamPlayer::PlayL(const TDesC8& aPlayBuffer)
{
Stop();
iReadSize = 0;
 
delete iPlayBuffer;
iPlayBuffer = NULL;
 
delete iStream;
iStream = NULL;
 
iBuffer.ResetAndDestroy();
 
iPlayBuffer = HBufC8::NewL(aPlayBuffer.Length());
iPlayBuffer->Des().Copy(aPlayBuffer);
 
TDes8* buffer = new(ELeave) TBuf8<KPcmBufferSize>;
buffer->SetMax();
CleanupStack::PushL(buffer);
User::LeaveIfError(iBuffer.Append(buffer));
CleanupStack::Pop(buffer);
 
buffer = new(ELeave) TBuf8<KPcmBufferSize>;
buffer->SetMax();
CleanupStack::PushL(buffer);
User::LeaveIfError(iBuffer.Append(buffer));
CleanupStack::Pop(buffer);
 
iReadSize = 0;
iCurrIndex = 0;
for (TInt index = 0; index < iBuffer.Count(); index++)
{
ReadFromFromL(index);
}
 
iStream = CMdaAudioOutputStream::NewL(*this);
iStream->Open(&iSettings);
}
 
void CStreamPlayer::Stop()
{
if(iStream)
iStream->Stop();
}
 
 
void CStreamPlayer::SetVolume(TInt aVol)
{
iVolume = aVol;
 
if(iVolume < 0)
iVolume = 0;
else if(iVolume > 10)
iVolume = 10;
 
if(iStream)
{
iStream->SetVolume(((iStream->MaxVolume() * iVolume) / 10));
}
}
 
void CStreamPlayer::MaoscOpenComplete(TInt aError)
{
iPlayError = aError;
 
if (aError==KErrNone && iStream)
{
iSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate8000Hz;
iSettings.iChannels = TMdaAudioDataSettings::EChannelsMono;
//iSettings.iVolume = ((iStream->MaxVolume() * iVolume) / 10);
 
iStream->SetAudioPropertiesL(iSettings.iSampleRate,
iSettings.iChannels);
SetVolume(iVolume);
iStream->SetPriority(EPriorityNormal, EMdaPriorityPreferenceNone);
 
iStream->WriteL(*iBuffer[0]);
}
}
 
void CStreamPlayer::MaoscBufferCopied(TInt aError, const TDesC8& aBuffer)
{
iPlayError = aError;
 
if(aError == KErrNone && iStream)
{
if (&aBuffer == iBuffer[0])
{
iCurrIndex = 0;
 
if((*iBuffer[1]).Length())
{
iStream->WriteL(*iBuffer[1]);
ReadFromFromL(0);
}
}
else// if (&aBuffer == iBuffer[1])
{
iCurrIndex = 1;
 
if((*iBuffer[0]).Length())
{
iStream->WriteL(*iBuffer[0]);
ReadFromFromL(1);
}
}
}
}
 
void CStreamPlayer::MaoscPlayComplete(TInt aError)
{
iPlayError = aError;
 
if (aError == KErrUnderflow)
{
if(iPlayBuffer->Des().Length() > iReadSize)
{
iCurrIndex = 0;
for (TInt index = 0; index < iBuffer.Count(); index++)
{
ReadFromFromL(index);
}
 
iStream->WriteL(*iBuffer[0]);
}
}
}
 
 
void CStreamPlayer::ReadFromFromL(TInt aBufferIndex)
{
if((aBufferIndex == 0 || aBufferIndex == 1) && iPlayBuffer)
{
(*iBuffer[aBufferIndex]).FillZ();
(*iBuffer[aBufferIndex]).Zero();
 
if((iPlayBuffer->Des().Length() > iReadSize))
{
TInt ReadFor(KPcmBufferSize);
if(iPlayBuffer->Des().Length() < (iReadSize + ReadFor))
{
ReadFor = iPlayBuffer->Des().Length() - iReadSize;
}
iBuffer[aBufferIndex].Copy(iPlayBuffer->Des().Mid(iReadSize,ReadFor));
iReadSize = iReadSize + ReadFor;
}
}
}

Stream_Play.h

#include <mda\common\audio.h>
#include <Mda\Client\Utility.h>
#include <Mda\Common\Resource.h>
#include <MdaAudioOutputStream.h>
#include <mmf\server\mmfdatabuffer.h>
 
const TInt KPcmBufferSize = 10000;
 
class CStreamPlayer : public CBase, public MMdaAudioOutputStreamCallback
{
public:
CStreamPlayer(void);
~CStreamPlayer();
public:
void PlayL(const TDesC8& aPlayBuffer);
void Stop();
TInt Volume(void){ return iVolume; }
void SetVolume(TInt aVol);
protected:
virtual void MaoscOpenComplete(TInt aError);
virtual void MaoscBufferCopied(TInt aError, const TDesC8& aBuffer);
virtual void MaoscPlayComplete(TInt aError);
private:
void ReadFromFromL(TInt aBufferIndex);
private:
TInt
iVolume,iReadSize,iCurrIndex,iPlayError;
RPointerArray<TDes8> iBuffer;
CMdaAudioOutputStream* iStream;
TMdaAudioDataSettings iSettings;
HBufC8* iPlayBuffer;
TBool iPlaying;
};
  

Rate This

 
Bookmark this page: DeliciousDiggFacebookGoogleYahooStumbleUponRedditDiigoTechnocratiTwitter  Share this page Share this page Print this Page Print this page Invite a friend Invite a friend
京ICP备05048969号    Email Newsletters Press Terms & Conditions Privacy Policy Sitemap Contact Us © 2009 Nokia 
RDF Facets: qdcZdescriptionQSxEa0E20WikiE20javaE20symbianE5fosE20s60E20maemoE20cE2bE2bE20WikiE20HomeE20WikiE20HelpE20OverviewE20GlossaryE20CreateE20PageE20ProposeE20anE20ArticleE20SpotlightE20TopicE20E2dE20WE52TE20WidgetsE20ProgrammingE20E4canguageE20E2dE20SymbianE20CE2bE2bE20E2dE20OpenE20CE2fCE2bE2bE20E2dE20JavaE20E2dE20FlashE20E4citeE20E2dE20PythonE20WebE20TechnologiesE20E2dE20WE52TE20WidgetsE20E2dE20WidSetsE20ToolsE20andE20SE44KE20CodeE20E45E78amplesE20KnowledgeE20BaseE20TechnologyE20AreasE20SoftwareE20PlatformsE20E44evelopmentE20ProcessE20E3fE3fWikiE20ChineseE20E3fE3fE3fWikiE20JapaneseE20PortugueseE2fBrazilianE20E52ussianE20WhatE20linksE20hereE20UploadE20fileE20SpecialE20pagesE20PrintableE20versionE44ownloadE20asE20PE44FE20GoE20ToE20E2eE2eE2eX qdcZidentifierQSxhttpE3aE2fE2fwikiE2eforumE2enokiaE2ecomE2findeE78E2ephpE2fPlayingE5fPCME5faudioE5fstreamsX qdcZpublisherQUxhttpE3aE2fE2fswE2enokiaE2ecomE2fidE2fc764fd1cE2d8b06E2d499aE2d9a6aE2d17c3903d5a65E2fforumE5fnokiaE5fcrawlerE5fagentX qdcZtitleQSxPlayingE20PCME20audioE20streamsE20E2dE20ForumE20NokiaE20WikiX qdcZtypeQUqfnZE45E78cludedFromGeneralE4cistingsQ qdcZtypeQUqfntypeZCommunityContentQ qdcZtypeQUqfntypeZE52esourceQ qdcZtypeQUqfntypeZWebpageQ qdcZtypeQUqfntypeZWikiContentQ qdcZtypeQUqmarsZManagedE52esourceQ qdcZtypeQUqwebZInformationE52esourceQ qdcZtypeQUqwebZPageQ qdcZtypeQUqwebZE52esourceQ qdcZtypeQUqrdfsZE52esourceQ qrssZdescriptionQSxEa0E20WikiE20javaE20symbianE5fosE20s60E20maemoE20cE2bE2bE20WikiE20HomeE20WikiE20HelpE20OverviewE20GlossaryE20CreateE20PageE20ProposeE20anE20ArticleE20SpotlightE20TopicE20E2dE20WE52TE20WidgetsE20ProgrammingE20E4canguageE20E2dE20SymbianE20CE2bE2bE20E2dE20OpenE20CE2fCE2bE2bE20E2dE20JavaE20E2dE20FlashE20E4citeE20E2dE20PythonE20WebE20TechnologiesE20E2dE20WE52TE20WidgetsE20E2dE20WidSetsE20ToolsE20andE20SE44KE20CodeE20E45E78amplesE20KnowledgeE20BaseE20TechnologyE20AreasE20SoftwareE20PlatformsE20E44evelopmentE20ProcessE20E3fE3fWikiE20ChineseE20E3fE3fE3fWikiE20JapaneseE20PortugueseE2fBrazilianE20E52ussianE20WhatE20linksE20hereE20UploadE20fileE20SpecialE20pagesE20PrintableE20versionE44ownloadE20asE20PE44FE20GoE20ToE20E2eE2eE2eX qfnZdistributionQUxhttpE3aE2fE2fwikiE2eforumE2enokiaE2ecomE2fX qfnZtopicQUqfnTopicZaudioQRqdcZtypeQUqrdfsZE52esourceQRqmarsZrelevanceQNx100X qfnZtopicQUqfnTopicZentertainmentQRqmarsZrelevanceQNx100X qfnZtopicQUqfnTopicZmultimediaQRqmarsZrelevanceQNx100X qfnZtopicQUqfnTopicZmusicQRqdcZtypeQUqrdfsZE52esourceQRqmarsZrelevanceQNx100X qfnZtypeQUqfntypeZCommunityContentQ qfnZtypeQUqfntypeZE52esourceQ qfnZtypeQUqfntypeZWebpageQ qfnZtypeQUqfntypeZWikiContentQ qfnZupdatedQDx2008E2d10E2d02X qfnZuserE5ftagQSxaudioX qfnZuserE5ftagQSxentertainmentX qfnZuserE5ftagQSxmultimediaX qfnZuserE5ftagQSxmusicX qmarsZdescriptionQSxEa0E20WikiE20javaE20symbianE5fosE20s60E20maemoE20cE2bE2bE20WikiE20HomeE20WikiE20HelpE20OverviewE20GlossaryE20CreateE20PageE20ProposeE20anE20ArticleE20SpotlightE20TopicE20E2dE20WE52TE20WidgetsE20ProgrammingE20E4canguageE20E2dE20SymbianE20CE2bE2bE20E2dE20OpenE20CE2fCE2bE2bE20E2dE20JavaE20E2dE20FlashE20E4citeE20E2dE20PythonE20WebE20TechnologiesE20E2dE20WE52TE20WidgetsE20E2dE20WidSetsE20ToolsE20andE20SE44KE20CodeE20E45E78amplesE20KnowledgeE20BaseE20TechnologyE20AreasE20SoftwareE20PlatformsE20E44evelopmentE20ProcessE20E3fE3fWikiE20ChineseE20E3fE3fE3fWikiE20JapaneseE20PortugueseE2fBrazilianE20E52ussianE20WhatE20linksE20hereE20UploadE20fileE20SpecialE20pagesE20PrintableE20versionE44ownloadE20asE20PE44FE20GoE20ToE20E2eE2eE2eX qmarsZlanguageQUxhttpE3aE2fE2fswE2enokiaE2ecomE2flanguageE2d1E2fenX qrdfZtypeQUqfnZE45E78cludedFromGeneralE4cistingsQ qrdfZtypeQUqfntypeZCommunityContentQ qrdfZtypeQUqfntypeZE52esourceQ qrdfZtypeQUqfntypeZWebpageQ qrdfZtypeQUqfntypeZWikiContentQ qrdfZtypeQUqmarsZManagedE52esourceQ qrdfZtypeQUqwebZInformationE52esourceQ qrdfZtypeQUqwebZPageQ qrdfZtypeQUqwebZE52esourceQ qrdfZtypeQUqrdfsZE52esourceQ