Quantcast
Channel: naudio Work Item Rss Feed
Viewing all articles
Browse latest Browse all 738

Commented Issue: sound does not play because of double to integer truncation, caused by low numFramesAvailable value [16363]

$
0
0
When device format is using 48k-sampling and content format is using 44.1k-sampling, playback problems occur. We observed the following sequence of events.

[WasapiOut::PlayThread]
1. audio buffer is filled at first
2. enter while loop and sleep for a while
3. try to fill buffer again, sometimes 'numFramesAvailable' is only '1'

[WasapiOut::FillBuffer]
4. when argument 'frameCount'='1' and 'playbackProvider' is SRC Dmo (i.e. device format is 48k while content is 44.1k), 'playbackState' will be stopped
5. no sound gets played, or you only hear a click

Step 4 is caused since:
[ResamplerDmoStream::Read]
int inputBytesRequired = (int)OutputToInputPosition(count - outputBytesProvided);
=>
[ResamplerDmoStream::OutputToInputPosition]
long inputPosition = (long)(outputPosition / ratio);
=>
inputPosition is 0 since double to integer truncation

Thus, the idea is only use FillBuffer when available frame count is 'bigger' so that inputPosition does not result in double-to-integer truncation value of 0.

We propose an easy fix by changing WasapiOut.cs, line 138, so that (numFramesAvailable > 10), instead of (numFramesAvailable > 0).

138: if (numFramesAvailable > 10)
139: {
140: FillBuffer(playbackProvider, numFramesAvailable);
141: }

Ten frames are safe and will not cause data loss. Of course, modifying behavior with 'OutputToInputPosition' is another way.

Comments: I have a similar issue with audio content that is played at different speeds (via SoundTouch library). The proposed work-around fixes my issue where playbackState was randomly getting set to stopped. Thank you for documenting this!

Viewing all articles
Browse latest Browse all 738

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>