×

Discussion Board

Results 1 to 10 of 10
  1. #1
    Nokia Developer Champion
    Join Date
    Mar 2004
    Location
    Czech Republic
    Posts
    2,037

    Using CMdaAudioOutputStream for playing network stream audio

    Hello,

    I am using the CMdaAudioOutputStream class for playing the MP3 data (128 kbps), which I am streaming from the Internet (icecast server). For getting data I am using the RSocket class and 64 kB circular cache buffer. Data are downloaded in stream from internet into buffer of 8kB size by RSocket::Read() call.

    The problem is that streaming and playing works well for a while - less then 5-7 seconds (for 1 second audio play I need 16kB data). It means that play is stopped after the initial cache buffer is emptied + 5-8 chunks of data received from RSocket are played).

    At the beginning data are read/received by socket and added to the circular buffer, from which they are taken when the MaoscBufferCopied() callback is called by CMdaAudioOutputStream. The problem is that after a while the data from socket are stopped to be added to the buffer, which after few MaoscBufferCopied() calls leads to the buffer underflow situation. After this happens, data are delivered from sockets in a burst – it looks to me like that playing the music might block the sockets.

    Both – the RSocket and CMdaAudioOutputStream are used withing the application thread. The RSocket active object priority is EPriorityStandard and for the CMdaAudioOutputStream the priority is the EMdaPriorityMax – 40.

    Any ideas where the problem can be? Would it help to put both – playing and data fetching processes into 2 separated threads? Or might be I am doing something completely wrong...

    Thanks a lot
    BR
    STeN

  2. #2
    Nokia Developer Moderator
    Join Date
    Feb 2006
    Location
    Budapest, Hungary
    Posts
    28,572

    Re: Using CMdaAudioOutputStream for playing network stream audio

    That circular buffer sounds suspicious. If the network happens to be faster than the player (which is a rather probable situation when you are testing on a local network), are you really overwriting data which has not been fed to the player yet? That will certainly "shorten" whatever you are streaming.

  3. #3
    Nokia Developer Champion
    Join Date
    Mar 2004
    Location
    Czech Republic
    Posts
    2,037

    Re: Using CMdaAudioOutputStream for playing network stream audio

    Hi,

    1/ I am testing only over wireless data connection (EDGE/UMTS), because emulator works only with PCM 16bit stream, which I do not have.

    2/ Buffer handling I hope is correct - I am checking both conditions - data overflow (data from the socket are discarded then) and data underflow (music play is stopped). By circular I mean that the buffer is a normal linear memory area, but pre-allocated with the defined size of 128 kB. I use two pointers - one for the position of the data, which should be copied to the CMdaAudioOutputStream to be played and second for the position, where data received from socket should be copied.

    I am logging to file for debugging quite extensively, so I see that both regions are not overlapping and there is still about 34-64 kB of data pre-buffered. I can see that at the beginning the callback MaoscBufferCopied() call alternates with the active object RunL() for the RSocket Read() completion, so the data are buffered on more or less same speed they are played. But at a certain point the RunL() stops to be called, but there are several MaoscBufferCopied() callback called until the pre-buffered data are all consumed and I have to raise buffer underflow event...
    Then the RunL() starts to be called again - seems to me like CMdaAudioOutputStream playback blocks the data delivery from sockets...


    Any idea about it? Will separating both tasks into standalone threads help? - I am probably going to try that since I have no other idea.

    BR
    STeN

  4. #4
    Nokia Developer Moderator
    Join Date
    Feb 2006
    Location
    Budapest, Hungary
    Posts
    28,572

    Re: Using CMdaAudioOutputStream for playing network stream audio

    Is there a Read issued when there are no more RunL-s invoked? Do you also log errors in RunL?
    When Read does not complete any more, where the "read pointer" points? (or "read index" indexes). Can it happen to be at the end of the buffer? Might there be some bug in the buffer-wraparound code? Are there successful wrap-arounds happening for both the receiver and the player code prior to the receiver part stops functioning?

    It is doubtful that threads would solve anything. However if you simply comment all audio stuff in the code (and assume that buffers are always empty and can be "overRead" any time), the result would behave exactly the same way as if the networking code would be moved to an separate thread.

  5. #5
    Nokia Developer Champion
    Join Date
    Mar 2004
    Location
    Czech Republic
    Posts
    2,037

    Re: Using CMdaAudioOutputStream for playing network stream audio

    Hi,

    I have removed all the CMdaAudioOutputStream handling and the data from sockets were delivered perfectly - the buffer pointer was working in a 'circular manner' as expected. My feeling is really that the CMdaAudioOutputStream is too demanding and blocks the delivery of the data by the socket from network interface to application, so the buffer is not filled regularly and the buffer underflow occurs in few seconds - at least this is the only idea I have

    If you have any other - it is really welcomed by me.
    Thanks wizard_hu_!!

    BR
    STeN

  6. #6
    Nokia Developer Moderator
    Join Date
    Feb 2006
    Location
    Budapest, Hungary
    Posts
    28,572

    Re: Using CMdaAudioOutputStream for playing network stream audio

    Assuming that you are using 128 kbit/s data and 8 kbyte buffers, one buffer is expected to last for 0.5 seconds. During that time the network code should be able to receive something in my opinion. Of course it also matters what other active objects/threads/applications are doing.
    You can try some hacks
    - what happens if you increase the priority of your communication active object?
    - a wilder hack would be putting something like
    Code:
    TInt err;
    if(CActiveScheduler::RunIfReady(err,0))User::WaitForAnyRequest();
    into the beginning of MaoscBufferCopied.

    By the way, where do you invoke CMdaAudioOutputStream::WriteL?

  7. #7
    Nokia Developer Champion
    Join Date
    Mar 2004
    Location
    Czech Republic
    Posts
    2,037

    Re: Using CMdaAudioOutputStream for playing network stream audio

    Hi,

    1/ Socket handling active object priority - If everything is in one thread, the socket active object the priority must be set to the higher one - e.g. EPriorityUserInput. It has positive effect - the buffer underflow comes later, but does not solve the problem.

    2/ Separate thread - Since active object priority did not help, I put all socket handling into a separate thread - the situation improves a lot - now I have no problems with data read from sockets. To make it working the thread priority must be set to EPriorityMuchMore relative value, while the active object priority for socket reading now probably does not matter, since there is only one or two active objects in the new thread.

    3/ But with the new thread I have new problem now:

    The data are delivered perfectly as I have said and for some seconds (even 30-60seconds) everything works - with use of the 2nd thread the difference is really significant. Now the new problem probably lies in fact that the CMdaAudioOutputStream handling is in the UI thread and not separated into its own thread like sockets are. Symptoms are following: When the playback starts the UI becomes extremely slow and after some time I start to have an opposite problem - buffer overflow. Seems to me that the CPU/DSP does not decode and play the delivered music data enough fast and music play is 'jammed'...

    I will try to put the CMdaAudioOutputStream handling into separate thread - but I am wondering why is such a simple task (on iOS it is more or less question of one method call) so difficult to be handled... or might be I am doing something wrong ...

    4/ Regarding your tips/questions

    4A/ Do I understand it correctly that CActiveScheduler::RunIfReady() checks if there is pending active object (probably socket one in our case), causes its RunL() to be called and we wait for the RunL() completion?

    4B/ The CMdaAudioOutputStream::WriteL() I call in MaoscBufferCopied() callback.

    Thanks for a reply
    Kind Regards,
    STeN
    Last edited by stenlik; 2011-05-29 at 05:39.

  8. #8
    Nokia Developer Moderator
    Join Date
    Feb 2006
    Location
    Budapest, Hungary
    Posts
    28,572

    Re: Using CMdaAudioOutputStream for playing network stream audio

    4B) you can try if it behaves better in RunL. CMdaAudioOutputStream::WriteL builds a list of descriptors to be played, so you can safely add data as soon as it is available. Though it will probably delay the problem only, when the network counter catches the playback counter, 3 will step into the picture

    3) it may have something to do with 4B: "late" delivery of data results in that there is always something to do in every 0.5th second, which may result noticeable slowdown

    4A) RunIfReady simply checks if any active object is ready to run, and runs the first one it finds, it is a synchronous call. However it does not "consume" the related semaphore event, that is why it has to be consumed manually

    Also consider playing a bit with those constants, 16* 8k buffers.

  9. #9
    Nokia Developer Champion
    Join Date
    Mar 2004
    Location
    Czech Republic
    Posts
    2,037

    Re: Using CMdaAudioOutputStream for playing network stream audio

    Hi,

    now the playing is much more better - I am streaming the 128 kbps .mp3 for more then 60 minutes without problem. Crucial were:


    1. Putting sockets into 2nd thread
    2. Do not wait with CMdaAudioOutputStream::WriteL() for MaoscBufferCopied, but filling the buffer as soon as data are provided by sockets from network interface. This was not without problems (see http://discussion.forum.nokia.com/fo...100#post844100 )
    3. Removing the play buffer (I had the circular buffer for sockets, but each time MaoscBufferCopied was called I done memmove() of the buffer part to the dedicated play buffer). Now I fully share the buffer for delivering the data from sockets with the play buffer for CMdaAudioOutputStream, while I play the game only with pointers.


    But still:
    1. The GUI is slow so I think that CMdaAudioOutputStream should be in separate thread
    2. And the biggest issue is that it does not work on Symbian^3. Everything is fine, but instead of music i hear only the noise... This is the next big issue, since there must be some changes between S60 5th and Symbian^3 that introduces this problem.


    Thanks a lot for help - if you have any tips for remaining 2 issues i welcome your comments.

    BR
    STeN

  10. #10
    Nokia Developer Champion
    Join Date
    Mar 2004
    Location
    Czech Republic
    Posts
    2,037

    Re: Using CMdaAudioOutputStream for playing network stream audio

    Hi,

    problem marked as 2. in my previous reply is solved - see there: http://discussion.forum.nokia.com/fo...305#post844305. The only issue was the sequence in which CMdaAudioOutputStream methods should be called + some methods are deprecated.

    What remains now is the separate thread for the CMdaAudioOutputStream - but this I am not sure I will implement.

    BR
    SteN

Similar Threads

  1. Problem with Audio Stream - stops playing
    By michi2805 in forum Audio
    Replies: 2
    Last Post: 2009-04-15, 11:19
  2. Can I play MPEG Audio Layer-3 file using CMdaAudioOutputStream
    By anand_zain76 in forum Symbian Media (Closed)
    Replies: 7
    Last Post: 2008-03-17, 09:27
  3. HELP me , Using Audio Stream record AMR
    By tennist in forum Symbian Media (Closed)
    Replies: 7
    Last Post: 2006-04-13, 10:12
  4. Playing audio stream(WAV) from small chunks
    By khurshed79 in forum Symbian
    Replies: 4
    Last Post: 2005-10-15, 05:36
  5. Replies: 2
    Last Post: 2003-08-27, 04:40

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •