Intel® Integrated Performance Primitives
Deliberate problems developing high-performance vision, signal, security, and storage applications.

DSoundAudioRender delay

bendeguy
Beginner
2,673 Views

Hi!

I'm using the DSoundAudioRenderer to play uncompressed pcm sound. The audio data provided by a stream(2 packet/sec).I put the arrived data to a MediaData objectas soon as it arrived. I experienced a delay about 1-2s when I play the sound. What can cause the problem? And how can I solve it?

Thanks in advance,

Bendeguy

0 Kudos
40 Replies
Vladimir_Dudnik
Employee
1,530 Views

Hello,

DS audio render has hardcoded buffer (and there is no methods to change its size). You can try WinMM audio render instead of it (it also has hardcoded buffer size, but it is simplier and you can tune it for your particular needs).

Regards,
Vladimir

0 Kudos
bendeguy
Beginner
1,530 Views

Hello,

Thanks for your answer. You said that DS audio renderer has hardcoded buffer. Is it hardcoded in windows or in the renderer's source code? Is it possible to change in the source?

Thanks in advance,

Bendeguy

0 Kudos
Vladimir_Dudnik
Employee
1,530 Views

I meant UMC class. Of course you can change the buffer size (by modifying sources)to adopt your needs.

Vladimir

0 Kudos
bendeguy
Beginner
1,530 Views

Hello,

First of all, thank you for your answers Vladimir(for my other questions too). Do you think if I change the buffersize to4096 then this will affect the performance too much? Where can I change the buffer size in the source code?

How can I use and set WinMM? I changed the renderer to WinMM and I can hear nothing. Do I have to do something else?

Bendeguy

0 Kudos
Vladimir_Dudnik
Employee
1,530 Views

I don't think it will affect performance. Please look at simple_player sources (where it intialize WinMM render) for example of using WinMM render

Vladimir

0 Kudos
bendeguy
Beginner
1,530 Views

Hello,

I havetried simple_player with WinMM but it didn't work. I found that the problem is the following:

when WinMMAudioRender::Reset() call the waveOutOpen function then it returns with 2 instead of 0. It means that the id defined by WAVE_MAPPER is out of range. I changed it to 1 and the waveOutOpen returned with 0. When the program arrives to the following part of the code

if (UMC_OK == umcRes)
{ umcRes = BasicAudioRender::Reset(); }

thenthe Reset function calls the m_Thread.Wait() which stops the program forever. So I removed the call of the Reset() function and finally the WinMM worked, and I heard the sound.

Is it a bug in UMC? Can I solve this problem easier? Why the m_Thread.Wait() function hangs forever?

Thanks in advance,

Bendeguy

0 Kudos
Intel_C_Intel
Employee
1,530 Views

Hi Bendeguy!

what delays are you talking about? How large is your packet? I have an application where I play audio file feeding the renderer with4096 bytes in a loop. I don't hear any delays. Could you describe the problem more detailed?

-Sergey

0 Kudos
bendeguy
Beginner
1,530 Views

Hi Sergey!

The problem's source is the AudiosRenderers inner buffer size. It is set to 10240 inside the Renderer's code. The renderer doesn't play the file until the buffer isn't full. I get audio packets from a stream and feed it with the renderer. Unfortunatelly the audio packet size is smaller then 10240 so the renderer do nothing. I have to wait for new packets and give those to the renderer too. When the sum of the packet lengthsexceeds 10240 the renderer starts to play the audio. You didn't hear any delay, because when you read from a file, you have a lot of audio data and you can give it to the renderer immediatelly. So when you gave 3*4096 byte to the rendererthen it starts to play. I hope I can help.

Greetings,

Bendeguy

0 Kudos
Sergey_O_Intel1
Employee
1,530 Views

I'm not sure that you're right. The size of the inner buffer is equal to sample_size * number_of_frames (if I understand right 1024x10 in your case) but the renderer must start reading data from the buffer (and throwing it to DS buffer) when it keeps at least m_prefOutputBufferSize bytes. In your case it should be 1024 bytes. (I guess we have different versions of UMC)

-Sergey

0 Kudos
bendeguy
Beginner
1,530 Views

Hi Sergey!

I'm talking about the renderer's inner buffer(DS buffer, WinMMBuffer). It have to be filled to start the audio playing.

Greetings,

Bendeguy

0 Kudos
Sergey_O_Intel1
Employee
1,530 Views

I still can't find the code you're talking about. Could you please point me to the concrete file and the function. All I see isthat SendFrame methodin DSRenderer is called the way I told you(doesn't wait for the buffer to be filled).

-Sergey

0 Kudos
bendeguy
Beginner
1,530 Views

Yes, you are right! The calling of SendFrame doesn't wait for the buffer to be filled. But theaudio don't start till the SendFrames don't put enough data into the inner buffer. Try this:

Give the first 4096 byte to the renderer and no more. You won't hear anything. Dsound Renderer is a little bit too complex (or at least I don't have time tounderstand it completely) but with WinMM renderer I experienced the same problem too. If you open winmm_render.h you can see two line:

#define BUF_NUM_MAX 10
#define BUF_SIZE 1152*16

the first defines how many sample to be buffered and the second defines the sample size. When I change BUF_SIZE to a lower value(lower then the audio data size in my packets) then Iheard the music immediatelly.

Greetings,

Bendeguy

0 Kudos
Sergey_O_Intel1
Employee
1,530 Views

If you use DS renderer and want to render the data the moment you copy it to the internal buffer (call SendFrame) you can change the following:

dsound_buf.cpp, CopyDataToBuffer function.

if (UMC_OK == umcRes && m_bPausedWaitingData &&
(m_dwDSBufferSize /2 < m_dwNextWriteOffset ||
(0 == m_dwNextWriteOffset && 0 != rdwBytesWrote)))

with

if
(UMC_OK == umcRes && m_bPausedWaitingData && rdwBytesWrote)

then DS renderer will not save data before starting to play.

I wonder if you got a delay before the first sample was played only or got delays constantly while you were feeding the renderer with small portions of data in your application?

-Sergey

0 Kudos
bendeguy
Beginner
1,530 Views

Hi Sergey!

Thanks for the information.Thedelay appears only before the first sample start. It is because I get the audio data from a camera. I have exactly as many data as I need to play so I experienced the delay until the bufferbecame filled firstly.

Greetings,

Bendeguy

0 Kudos
bendeguy
Beginner
1,530 Views

Hi!

Cananyone confirm or confute what I said about the WinMMREnderer(it isn't working properly)? I tried to use it on windows xp. Thanks in advance

Bendeguy

0 Kudos
Vladimir_Dudnik
Employee
1,530 Views

As I understood, Sergey (who is audio rendered expert), did not find any issue you mention with WinMM render. What version of media sample do you use? If it is not the latest available (from IPP 5.1.1), could you please upgrade to the latest one?

Regards,
Vladimir

0 Kudos
bendeguy
Beginner
1,530 Views

Hi Vladimir,

I'm using IPP 5.1 and sample 5.1. Unfortunatelly I changed the source of some class according to my needs. So it won't be too easy to upgrade to 5.1.1. Maybe I'm wrong, but I didn'tnoticed the message where Sergey says he didn't findanyproblem with WinMM Renderer. Which message do you talking about?

Greetings,

Bendeguy

0 Kudos
Vladimir_Dudnik
Employee
1,530 Views

I think it should be better to move to the latest version of UMC sources as there can be some bug fixes or changes in interfaces. You probably right, Sergey did not say it emplicitely, but as I understand he was not able to reproduce the issue, that means he has no such a problem (he used 5.1.1 sample)

Vladimir

0 Kudos
bendeguy
Beginner
1,530 Views

Hi,

Thanks for the information Vladimir. You're very helpful. I will upgrade my IPP and IPP sample version soon.
I have seen that the audiorenderer calling sendframe when the renderer finished playing of a portion of data. Is it possible sendframe don't call in time and it causes pauses between playing portion of audios? I've experinced that when the WinMMRenderer hasn't gotdata then it plays nothingand the DirectSoundRenderer replays the previous audiodata. Is it true?

Thanks in advance,

Bendeguy

0 Kudos
Sergey_O_Intel1
Employee
1,424 Views

Concerning WinMMAudioRender:

WinMMAudioRender::Reset should not call BasicAudioRender::Reset. This string is commented in the file winmm_render.cpp in 5.1 version. Are you sure that it is not?

WAVE_MAPPER constant which is used in waveOutOpen says that audio device should be chosen automatically to play the stream with the parameters given. A mistake says that system knows nothing about device with such id.

About playback: DSAudioRender plays its buffer in a loop. So the user should feed it constantly until he gives END_OF_STREAM flag in UnlockInputBuffer function. WinMMAudioRender plays its inner buffers in order. So there's no looping. BTW there's a bug in 5.1 version. WinMMAudioRender doesn't play the last samples if their size is not equal to BUFFER_SIZE. It'll be fixed in the next version.

0 Kudos
Reply