×
Namespaces

Variants
Actions
(Difference between revisions)

Archived:Audiostream playback using Symbian C++

From Nokia Developer Wiki
Jump to: navigation, search
hamishwillee (Talk | contribs)
m (Hamishwillee - Bot update - Fix reviewer approved and ArticleMetaData)
hamishwillee (Talk | contribs)
(2 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{ArticleMetaData <!-- v1.1 -->
+
{{Archived|timestamp=20120313112701|user=roy.debjit| }}
 +
[[Category:Base/System]][[Category:Multimedia]][[Category:Symbian C++]][[Category:Audio]][[Category:Code Snippet]][[Category:S60 2nd Edition (initial release)]]
 +
{{ArticleMetaData <!-- v1.2 -->
 
|sourcecode= <!-- Link to example source code e.g. [[Media:The Code Example ZIP.zip]] -->
 
|sourcecode= <!-- Link to example source code e.g. [[Media:The Code Example ZIP.zip]] -->
 
|installfile= <!-- Link to installation file (e.g. [[Media:The Installation File.sis]]) -->
 
|installfile= <!-- Link to installation file (e.g. [[Media:The Installation File.sis]]) -->
Line 10: Line 12:
 
|capabilities= <!-- Capabilities required by the article/code example (e.g. Location, NetworkServices. -->
 
|capabilities= <!-- Capabilities required by the article/code example (e.g. Location, NetworkServices. -->
 
|keywords= <!-- APIs, classes and methods (e.g. QSystemScreenSaver, QList, CBase -->
 
|keywords= <!-- APIs, classes and methods (e.g. QSystemScreenSaver, QList, CBase -->
|id= <!-- Article Id (Knowledge base articles only) -->
 
 
|language= <!-- Language category code for non-English topics - e.g. Lang-Chinese -->
 
|language= <!-- Language category code for non-English topics - e.g. Lang-Chinese -->
 
|translated-by= <!-- [[User:XXXX]] -->
 
|translated-by= <!-- [[User:XXXX]] -->
Line 22: Line 23:
 
|author= [[User:Toth.b]]
 
|author= [[User:Toth.b]]
 
}}
 
}}
[[Category:Base/System]][[Category:Multimedia]][[Category:Symbian C++]]
 
  
Generally there are two opportunities to play back raw audio data on Symbian OS. We can use [[Audio Playback APIs|<tt>CMdaAudioPlayerUtility</tt> and <tt>MMdaAudioPlayerCallback</tt>]], or <tt>CMdaAudioOutputStream</tt> and <tt>MMdaAudioOutputStreamCallback</tt> classes. The former requires the whole data audio data with a valid WAVE header (in the header are the bitrate, sampling frequency and length defined), the latter opens a stream and we can write to the stream anytime. Consequently the second solution is much more memory friendly; it is preferable especially in case of longer audio data. It may be also prefered in case of remote audiostream playback (e.g. streaming audio from the internet).
+
Generally there are two opportunities to play back raw audio data on Symbian OS. We can use [[Audio Playback APIs|{{Icode|CMdaAudioPlayerUtility}} and {{Icode|MMdaAudioPlayerCallback}}]], or {{Icode|CMdaAudioOutputStream}} and {{Icode|MMdaAudioOutputStreamCallback}} classes. The former requires the whole data audio data with a valid WAVE header (in the header are the bitrate, sampling frequency and length defined), the latter opens a stream and we can write to the stream anytime. Consequently the second solution is much more memory friendly; it is preferable especially in case of longer audio data. It may be also prefered in case of remote audiostream playback (e.g. streaming audio from the internet).
  
 
This article deals with the second solution, also, with audiostream playback. In the first part of the article the main idea and functionality of streaming playback is introduced and the second part discusses the occurring problems on devices. According to my findings, some of these problems have never been publish before.
 
This article deals with the second solution, also, with audiostream playback. In the first part of the article the main idea and functionality of streaming playback is introduced and the second part discusses the occurring problems on devices. According to my findings, some of these problems have never been publish before.
Line 30: Line 30:
 
== The usage of CMdaAudioOutputStream and MMdaAudioPlayerCallback ==
 
== The usage of CMdaAudioOutputStream and MMdaAudioPlayerCallback ==
  
The audio playback class must be inherited from <tt>MMdaAudioPlayerCallback</tt>. In this class we must reference a <tt>CMdaAudioOutputStream</tt> type object:
+
The audio playback class must be inherited from {{Icode|MMdaAudioPlayerCallback}}. In this class we must reference a {{Icode|CMdaAudioOutputStream}} type object:
 
<code cpp>class CAudioStreamPlayer:public MMdaAudioPlayerCallback
 
<code cpp>class CAudioStreamPlayer:public MMdaAudioPlayerCallback
 
{
 
{
Line 50: Line 50:
 
PanicIfError(err);
 
PanicIfError(err);
 
</code>
 
</code>
where <tt>*this</tt> is the inherited class from <tt>MMdaAudioPlayerCallback</tt>. Now we have to open the stream:
+
where {{Icode|*this}} is the inherited class from {{Icode|MMdaAudioPlayerCallback}}. Now we have to open the stream:
 
<code cpp>TMdaAudioDataSettings iStreamSettings;
 
<code cpp>TMdaAudioDataSettings iStreamSettings;
 
iStreamSettings.iChannels = TMdaAudioDataSettings::EChannelsMono;
 
iStreamSettings.iChannels = TMdaAudioDataSettings::EChannelsMono;
Line 56: Line 56:
 
iAudioOutputStream->Open(&iStreamSettings);
 
iAudioOutputStream->Open(&iStreamSettings);
 
</code>
 
</code>
When the stream is opened, the <tt>MaoscOpenComplete(TInt aError)</tt> callback function is called, so we must implement it in our class. In this function we can start to write into the stream (<tt>CAudiostreamPlayer</tt> is derived from <tt>MMdaAudioPlayerCallback</tt>):
+
When the stream is opened, the {{Icode|MaoscOpenComplete(TInt aError)}} callback function is called, so we must implement it in our class. In this function we can start to write into the stream ({{Icode|CAudiostreamPlayer}} is derived from {{Icode|MMdaAudioPlayerCallback}}):
 
<code cpp>void CAudiostreamPlayer::MaoscOpenComplete(TInt aError)
 
<code cpp>void CAudiostreamPlayer::MaoscOpenComplete(TInt aError)
 
{
 
{
Line 66: Line 66:
 
}
 
}
 
</code>
 
</code>
When <tt>iSomeMono8khzRawAudioData</tt> is copied into the stream, the <tt>MaoscBufferCopied(TInt aError, const TDesC8&amp; aBuffer)</tt> callback function is called, consequently it must also be implemented:
+
When {{Icode|iSomeMono8khzRawAudioData}} is copied into the stream, the {{Icode|MaoscBufferCopied(TInt aError, const TDesC8&amp; aBuffer)}} callback function is called, consequently it must also be implemented:
 
<code cpp>void CAudiostreamPlayer::MaoscBufferCopied(TInt aError, const TDesC8& aBuffer)
 
<code cpp>void CAudiostreamPlayer::MaoscBufferCopied(TInt aError, const TDesC8& aBuffer)
 
{
 
{
Line 79: Line 79:
 
}
 
}
 
</code>
 
</code>
''(Note: <tt>aBuffer</tt> points to the copied buffer. <tt>aBuffer</tt> should not be used/deleted untill <tt>MaoscBufferCopied</tt> callback is obtained.)''
+
''(Note: {{Icode|aBuffer}} points to the copied buffer. {{Icode|aBuffer}} should not be used/deleted untill {{Icode|MaoscBufferCopied}} callback is obtained.)''
  
  
Line 85: Line 85:
 
<br>
 
<br>
  
When there is no more audio data, or the last audio data segment has been played, and new data wasn’t written into the stream, then the <tt>MaoscPlayComplete(TInt aError)</tt> callback function is called; it is also called in case of any error or if the <tt>CMdaAudioOutputStream::Stop()</tt> function was called:
+
When there is no more audio data, or the last audio data segment has been played, and new data wasn’t written into the stream, then the {{Icode|MaoscPlayComplete(TInt aError)}} callback function is called; it is also called in case of any error or if the {{Icode|CMdaAudioOutputStream::Stop()}} function was called:
 
<code cpp>void CAudiostreamPlayer::MaoscPlayComplete(TInt aError)
 
<code cpp>void CAudiostreamPlayer::MaoscPlayComplete(TInt aError)
 
{
 
{
Line 117: Line 117:
 
=== Missing MaoscPlayComplete() callback function ===
 
=== Missing MaoscPlayComplete() callback function ===
  
The <tt>MaoscPlayComplete()</tt> callback function is never called on 2nd edition devices (have not tested it on 3rd edition devices) in case of <tt>KErrUnderflow</tt>, so when we stop writing to the stream or when the speed of the audio playback is faster than the speed the buffer is written into the stream. The actual end of playback is indicated by MaoscBufferCopied() being called instead. We can check the identity of the buffer received by <tt>MaoscBufferCopied()</tt>, comparing it with the buffers in the stream (e.g. to see whether it is the last buffer or not). We can still achieve <tt>MaoscPlayComplete()</tt> to be called with <tt>aError==KErrCancel</tt>, if we call the <tt>CMdaAudioOutputStream::Stop()</tt> function.
+
The {{Icode|MaoscPlayComplete()}} callback function is never called on 2nd edition devices (have not tested it on 3rd edition devices) in case of {{Icode|KErrUnderflow}}, so when we stop writing to the stream or when the speed of the audio playback is faster than the speed the buffer is written into the stream. The actual end of playback is indicated by MaoscBufferCopied() being called instead. We can check the identity of the buffer received by {{Icode|MaoscBufferCopied()}}, comparing it with the buffers in the stream (e.g. to see whether it is the last buffer or not). We can still achieve {{Icode|MaoscPlayComplete()}} to be called with {{Icode|aError==KErrCancel}}, if we call the {{Icode|CMdaAudioOutputStream::Stop()}} function.
  
 
=== Memory leaking in MaoscPlayComplete() callback function ===
 
=== Memory leaking in MaoscPlayComplete() callback function ===
  
The developer might like to destroy the <tt>CMdaAudioOutputStream*</tt> object (also <tt>iAudioOutputStream</tt> in the examples) in <tt>MaoscPlayComplet()</tt>, when the whole audio data has been played or stopped to free up memory. But if it is destroyed in <tt>MaoscPlayComplete()</tt>, then it leads to memory leaking.
+
The developer might like to destroy the {{Icode|CMdaAudioOutputStream*}} object (also {{Icode|iAudioOutputStream}} in the examples) in {{Icode|MaoscPlayComplet()}}, when the whole audio data has been played or stopped to free up memory. But if it is destroyed in {{Icode|MaoscPlayComplete()}}, then it leads to memory leaking.
  
''(Note: on 2nd edition devices <tt>MaoscPlayComplet()</tt> callback function is called only if the <tt>CMdaAudioOutputStreamCallback::Stop()</tt> member function is previously called.)''
+
''(Note: on 2nd edition devices {{Icode|MaoscPlayComplet()}} callback function is called only if the {{Icode|CMdaAudioOutputStreamCallback::Stop()}} member function is previously called.)''
  
 
=== MaoscOpenComplete() never called when reopening the stream ===
 
=== MaoscOpenComplete() never called when reopening the stream ===
  
On some 2nd edition devices (have not tested on 3rd edition devices) the <tt>MaoscOpenComplete()</tt> callback function is not called if we reopen the stream, just like when we call the <tt>Open()</tt> function more than once. To overcome the problem we must reconstruct the stream each time before opening it:
+
On some 2nd edition devices (have not tested on 3rd edition devices) the {{Icode|MaoscOpenComplete()}} callback function is not called if we reopen the stream, just like when we call the {{Icode|Open()}} function more than once. To overcome the problem we must reconstruct the stream each time before opening it:
 
<code cpp>if (iAudioOutputStream) delete iAudioOutputStream;
 
<code cpp>if (iAudioOutputStream) delete iAudioOutputStream;
 
iAudioOutputStream = NULL; // In case the following NewL leaves
 
iAudioOutputStream = NULL; // In case the following NewL leaves
Line 139: Line 139:
 
=== Stop() causes crash if it is called in the callback functions ===
 
=== Stop() causes crash if it is called in the callback functions ===
  
Developers may call the <tt>CMdaAudioOutputStream::Stop()</tt> function in <tt>MaoscBufferCopied()</tt> to reach <tt>MaoscPlayComplete()</tt>. But on some 2nd edition devices (have not tested on 3rd edition devices) the application freezes when the <tt>Stop()</tt> function is called in the callback functions. To avoid this problem, the <tt>Stop()</tt> function should not be called directly from the callbacks. A possible solution is to use CIdle object for calling the <tt>Stop()</tt> function. With the help of <tt>CIdle</tt> the <tt>Stop()</tt> function is called only when there are no higher priority active objects running. So we should create and start the <tt>CIdle</tt> object when normally we would call the <tt>Stop()</tt> function and call the <tt>Stop()</tt> function in the CIdle object.
+
Developers may call the {{Icode|CMdaAudioOutputStream::Stop()}} function in {{Icode|MaoscBufferCopied()}} to reach {{Icode|MaoscPlayComplete()}}. But on some 2nd edition devices (have not tested on 3rd edition devices) the application freezes when the {{Icode|Stop()}} function is called in the callback functions. To avoid this problem, the {{Icode|Stop()}} function should not be called directly from the callbacks. A possible solution is to use CIdle object for calling the {{Icode|Stop()}} function. With the help of {{Icode|CIdle}} the {{Icode|Stop()}} function is called only when there are no higher priority active objects running. So we should create and start the {{Icode|CIdle}} object when normally we would call the {{Icode|Stop()}} function and call the {{Icode|Stop()}} function in the CIdle object.
 
<code cpp>iStop = CIdle::NewL(EPriorityIdle);
 
<code cpp>iStop = CIdle::NewL(EPriorityIdle);
 
iStop->Start(TCallBack(BackgroundStop, this));
 
iStop->Start(TCallBack(BackgroundStop, this));
Line 159: Line 159:
 
=== ”Feature not supported!” error message while calling WriteL() ===
 
=== ”Feature not supported!” error message while calling WriteL() ===
  
On some 2nd edition devices (not tested on 3rd edition devices) the ''Feature not supported!'' error message is displayed, when <tt>CMdaAudioOutputStream::WriteL()</tt> is called. It is caused by the inappropriate sampling rate settings. Some devices support 22 kHz, others does not support it. Check out the devices’ specification or try it on the device, and if the ''Feature not supported!'' error message is displayed, than set the sampling rate lower, 8 kHz might be a good solution.
+
On some 2nd edition devices (not tested on 3rd edition devices) the ''Feature not supported!'' error message is displayed, when {{Icode|CMdaAudioOutputStream::WriteL()}} is called. It is caused by the inappropriate sampling rate settings. Some devices support 22 kHz, others does not support it. Check out the devices’ specification or try it on the device, and if the ''Feature not supported!'' error message is displayed, than set the sampling rate lower, 8 kHz might be a good solution.
  
''(Note: the sampling rate can be set when opening the stream in TMdaAudioDataSettings::iSampleRate property or by <tt>CMdaAudioOutputStream::SetAudioPropertiesL(TInt aSampleRate, TInt aChannels)</tt>.)''
+
''(Note: the sampling rate can be set when opening the stream in TMdaAudioDataSettings::iSampleRate property or by {{Icode|CMdaAudioOutputStream::SetAudioPropertiesL(TInt aSampleRate, TInt aChannels)}}.)''
  
 
=== Memory leaking in MaoscBufferCopied() callback function ===
 
=== Memory leaking in MaoscBufferCopied() callback function ===
  
One might like to do some extra calculations in <tt>MaoscBufferCopied()</tt> callback function (e.g. MP3 decoding, downloading from the Internet, text-to-speech conversion, etc.). In this case it is favorable to do the calculations after the last audio data segment was written into the stream. Unfortunately it causes memory leaking on 2nd edition devices (have not tested on 3rd edition devices). We can easily reproduce the problem by putting a for loop after the <tt>CMdaAudioOutputStream::WriteL()</tt> function:
+
One might like to do some extra calculations in {{Icode|MaoscBufferCopied()}} callback function (e.g. MP3 decoding, downloading from the Internet, text-to-speech conversion, etc.). In this case it is favorable to do the calculations after the last audio data segment was written into the stream. Unfortunately it causes memory leaking on 2nd edition devices (have not tested on 3rd edition devices). We can easily reproduce the problem by putting a for loop after the {{Icode|CMdaAudioOutputStream::WriteL()}} function:
 
<code cpp>void CAudiostreamPlayer::MaoscPlayComplete(TInt aError)
 
<code cpp>void CAudiostreamPlayer::MaoscPlayComplete(TInt aError)
 
{
 
{
Line 210: Line 210:
 
* Nokia N70, V 5.0616.2.0.3, 24-04-06, RM-84
 
* Nokia N70, V 5.0616.2.0.3, 24-04-06, RM-84
  
[[Category:Audio]][[Category:Code Snippet]][[Category:S60 2nd Edition]]
+
 
 
== External links ==
 
== External links ==
  

Revision as of 09:56, 15 June 2012

Archived.pngArchived: This article is archived because it is not considered relevant for third-party developers creating commercial solutions today. If you think this article is still relevant, let us know by adding the template {{ReviewForRemovalFromArchive|user=~~~~|write your reason here}}.

Article Metadata
CompatibilityArticle
Created: toth.b (07 Jun 2007)
Last edited: hamishwillee (15 Jun 2012)

Generally there are two opportunities to play back raw audio data on Symbian OS. We can use CMdaAudioPlayerUtility and MMdaAudioPlayerCallback, or CMdaAudioOutputStream and MMdaAudioOutputStreamCallback classes. The former requires the whole data audio data with a valid WAVE header (in the header are the bitrate, sampling frequency and length defined), the latter opens a stream and we can write to the stream anytime. Consequently the second solution is much more memory friendly; it is preferable especially in case of longer audio data. It may be also prefered in case of remote audiostream playback (e.g. streaming audio from the internet).

This article deals with the second solution, also, with audiostream playback. In the first part of the article the main idea and functionality of streaming playback is introduced and the second part discusses the occurring problems on devices. According to my findings, some of these problems have never been publish before.

Contents

The usage of CMdaAudioOutputStream and MMdaAudioPlayerCallback

The audio playback class must be inherited from MMdaAudioPlayerCallback. In this class we must reference a CMdaAudioOutputStream type object:

class CAudioStreamPlayer:public MMdaAudioPlayerCallback
{
public: //Constructor and Destructor
 
public: // Player functions
 
public: //functions derived from MMdaAudioPlayerCallback
 
private:
CMdaAudioOutputStream* iAudioOutputStream;
 
// Other data
// ...
}

Then we can instantiate an object:

TRAPD(err, iAudioOutputStream = CMdaAudioOutputStream::NewL(*this););
PanicIfError(err);

where *this is the inherited class from MMdaAudioPlayerCallback. Now we have to open the stream:

TMdaAudioDataSettings iStreamSettings;
iStreamSettings.iChannels = TMdaAudioDataSettings::EChannelsMono;
iStreamSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate8000Hz;
iAudioOutputStream->Open(&iStreamSettings);

When the stream is opened, the MaoscOpenComplete(TInt aError) callback function is called, so we must implement it in our class. In this function we can start to write into the stream (CAudiostreamPlayer is derived from MMdaAudioPlayerCallback):

void CAudiostreamPlayer::MaoscOpenComplete(TInt aError)
{
if (aError == KErrNone)
{
// the stream is opened
iAudioOutputStream->WriteL(iSomeMono8khzRawAudioData);
}
}

When iSomeMono8khzRawAudioData is copied into the stream, the MaoscBufferCopied(TInt aError, const TDesC8& aBuffer) callback function is called, consequently it must also be implemented:

void CAudiostreamPlayer::MaoscBufferCopied(TInt aError, const TDesC8& aBuffer)
{
if (aError==KErrNone)
{
// if there is more data, then write it into the stream
if (iMoreData==ETrue)
{
iAudioOutputStream->WriteL(iSomeMono8khzRawAudioData);
}
}
}

(Note: aBuffer points to the copied buffer. aBuffer should not be used/deleted untill MaoscBufferCopied callback is obtained.)



When there is no more audio data, or the last audio data segment has been played, and new data wasn’t written into the stream, then the MaoscPlayComplete(TInt aError) callback function is called; it is also called in case of any error or if the CMdaAudioOutputStream::Stop() function was called:

void CAudiostreamPlayer::MaoscPlayComplete(TInt aError)
{
if (aError==KErrUnderflow)
{
if (iMoreData==ETrue)
{
iAudioOutputStream->WriteL(iSomeMono8khzRawAudioData);
}
else
{
// done
}
}
else if (aError==KErrCancel)
{
// stopped
}
}

We can stop playing anytime by calling:

iAudioOutputStream->Stop();

More information on functions and error codes can be found in the Developer Library.


Device specific errors

The audiostream playback as described above works perfectly on the emulator, but unfortunaltey it does not work so on the devices. There are several major issues that are present on some devices. Developers must pay attention to these issues to successfully implement audiostream playback in their application. Most of these issues can be solved.

Missing MaoscPlayComplete() callback function

The MaoscPlayComplete() callback function is never called on 2nd edition devices (have not tested it on 3rd edition devices) in case of KErrUnderflow, so when we stop writing to the stream or when the speed of the audio playback is faster than the speed the buffer is written into the stream. The actual end of playback is indicated by MaoscBufferCopied() being called instead. We can check the identity of the buffer received by MaoscBufferCopied(), comparing it with the buffers in the stream (e.g. to see whether it is the last buffer or not). We can still achieve MaoscPlayComplete() to be called with {{{1}}}, if we call the CMdaAudioOutputStream::Stop() function.

Memory leaking in MaoscPlayComplete() callback function

The developer might like to destroy the CMdaAudioOutputStream* object (also iAudioOutputStream in the examples) in MaoscPlayComplet(), when the whole audio data has been played or stopped to free up memory. But if it is destroyed in MaoscPlayComplete(), then it leads to memory leaking.

(Note: on 2nd edition devices MaoscPlayComplet() callback function is called only if the CMdaAudioOutputStreamCallback::Stop() member function is previously called.)

MaoscOpenComplete() never called when reopening the stream

On some 2nd edition devices (have not tested on 3rd edition devices) the MaoscOpenComplete() callback function is not called if we reopen the stream, just like when we call the Open() function more than once. To overcome the problem we must reconstruct the stream each time before opening it:

if (iAudioOutputStream) delete iAudioOutputStream;
iAudioOutputStream = NULL; // In case the following NewL leaves
TRAPD(err, iAudioOutputStream = CMdaAudioOutputStream::NewL(*this););
PanicIfError(err);



Stop() causes crash if it is called in the callback functions

Developers may call the CMdaAudioOutputStream::Stop() function in MaoscBufferCopied() to reach MaoscPlayComplete(). But on some 2nd edition devices (have not tested on 3rd edition devices) the application freezes when the Stop() function is called in the callback functions. To avoid this problem, the Stop() function should not be called directly from the callbacks. A possible solution is to use CIdle object for calling the Stop() function. With the help of CIdle the Stop() function is called only when there are no higher priority active objects running. So we should create and start the CIdle object when normally we would call the Stop() function and call the Stop() function in the CIdle object.

iStop = CIdle::NewL(EPriorityIdle);
iStop->Start(TCallBack(BackgroundStop, this));
TInt CAudiostreamPlayer::BackgroundStop(TAny *aStream)
{
return ((CAudiostreamPlayer*)aStream)->Stop();
}
 
TBool CAudiostreamPlayer::Stop()
{
iAudioOutputStream->Stop();
return EFalse;
}



”Feature not supported!” error message while calling WriteL()

On some 2nd edition devices (not tested on 3rd edition devices) the Feature not supported! error message is displayed, when CMdaAudioOutputStream::WriteL() is called. It is caused by the inappropriate sampling rate settings. Some devices support 22 kHz, others does not support it. Check out the devices’ specification or try it on the device, and if the Feature not supported! error message is displayed, than set the sampling rate lower, 8 kHz might be a good solution.

(Note: the sampling rate can be set when opening the stream in TMdaAudioDataSettings::iSampleRate property or by CMdaAudioOutputStream::SetAudioPropertiesL(TInt aSampleRate, TInt aChannels).)

Memory leaking in MaoscBufferCopied() callback function

One might like to do some extra calculations in MaoscBufferCopied() callback function (e.g. MP3 decoding, downloading from the Internet, text-to-speech conversion, etc.). In this case it is favorable to do the calculations after the last audio data segment was written into the stream. Unfortunately it causes memory leaking on 2nd edition devices (have not tested on 3rd edition devices). We can easily reproduce the problem by putting a for loop after the CMdaAudioOutputStream::WriteL() function:

void CAudiostreamPlayer::MaoscPlayComplete(TInt aError)
{
if (aError==KErrUnderflow)
{
if (iMoreData==ETrue)
{
iAudioOutputStream->WriteL(iSomeMono8khzRawAudioData);
for (TInt k=0; k<100000; k++)
{
k++;
for (TInt l=0; l<100; l++)
{
k++;
}
k-=101;
}
 
}
else
{
// done
}
}
else if (aError==KErrCancel)
{
// stopped
}
}

Unfortunately this issue has not been solved yet. Any idea and suggestion is welcome.



Tested devices

During the tests the following devices were used:

  • Nokia 3230, V3.0505.2, 19-02-05, Rm-51
  • Nokia 6600, V3.42.1, 16-10-03, NHL-10
  • Nokia 6680, V5.04.07, 15-02-06, RM-36
  • Nokia N70, V 5.0616.2.0.3, 24-04-06, RM-84


External links


(308 members)
263 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×