-
Notifications
You must be signed in to change notification settings - Fork 308
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enable >16bit output sample widths using DirectSound API #54
Comments
Comment by @RossBencina Some progress made, see also ticket #29 |
Comment by @RossBencina Renamed from "Enable multiple channels and different sample widths..." since multichannel has been implemented since r1268 |
Comment by @RossBencina Changed ticket description with more detail about current status of >16 bit support. |
Comment by @RossBencina TRAC migration: propagating ticket status from TRAC |
Comment by @RossBencina originally added to Trac by alec_rogers 5 years ago. |
Currently, the DirectSound Host API code only creates 16-bit integer DirectSound buffers. All audio data provided by the user is therefore converted by PortAudio to and from 16-bit, regardless of the user buffer format. This basically makes it impossible to pass 24-bit audio through the DirectSound Host API. If the user buffer format is not 16-bit, this also causes pointless conversions to take place, *even if the hardware is running at 16-bit*, because modern Windows versions (Vista+) convert the data to floating point behind the scenes before it is handed off to the hardware. This can lead to silly situations where 32-bit float samples from the user are (lossily) converted to 16-bit by PortAudio, then ended off to Windows via DirectSound, only to be converted back to 32-bit float again, before finally being converted to the format the hardware device is configured to use. This can easily lead to two layers of 16-bit dithering (one from PortAudio, and one from Windows) being piled on top of each other, resulting in an elevated noise floor. This commit fixes this problem by configuring the DirectSound buffers to use the same format as the user buffer. This should stop PortAudio from converting samples in all cases except paInt8, which is not supported by WAVEFORMATEX (only paUInt8 is). The new code assumes that DirectSound will accept whatever format we throw at it. I feel confident that this is always true on Vista+ regardless of hardware, because starting from Vista DirectSound does not access hardware directly - it always goes through the Windows Audio Engine which supports all formats in both directions (I verified this using paloopback). The consequences of this change on pre-Vista Windows are less clear, although [1] suggests that this might just work even on 2000/XP as KMixer should be able to handle these conversions as well. [1]: https://microsoft.public.win32.programmer.directx.audio.narkive.com/elgNlPIn/ Fixes PortAudio#54
Currently, the DirectSound Host API code only creates 16-bit integer DirectSound buffers. All audio data provided by the user is therefore converted by PortAudio to and from 16-bit, regardless of the user buffer format. This basically makes it impossible to pass 24-bit audio through the DirectSound Host API. If the user buffer format is not 16-bit, this also causes pointless conversions to take place, *even if the hardware is running at 16-bit*, because modern Windows versions (Vista+) convert the data to floating point behind the scenes before it is handed off to the hardware. This can lead to silly situations where 32-bit float samples from the user are (lossily) converted to 16-bit by PortAudio, then ended off to Windows via DirectSound, only to be converted back to 32-bit float again, before finally being converted to the format the hardware device is configured to use. This can easily lead to two layers of 16-bit dithering (one from PortAudio, and one from Windows) being piled on top of each other, resulting in an elevated noise floor. This commit fixes this problem by configuring the DirectSound buffers to use the same format as the user buffer. This should stop PortAudio from converting samples in all cases except paInt8, which is not supported by WAVEFORMATEX (only paUInt8 is). The new code assumes that DirectSound will accept whatever format we throw at it. I feel confident that this is always true on Vista+ regardless of hardware, because starting from Vista DirectSound does not access hardware directly - it always goes through the Windows Audio Engine which supports all formats in both directions (I verified this using paloopback). The consequences of this change on pre-Vista Windows are less clear, although [1] suggests that this might just work even on 2000/XP as KMixer should be able to handle these conversions as well. [1]: https://microsoft.public.win32.programmer.directx.audio.narkive.com/elgNlPIn/ Fixes #54
Issue created by arborrhythms on Assembla
Multichannel support is complete in DirectSound. This has been quite extensively tested. The remaining work pertains to >16 bit sample formats. Progress on this issue was made in changesets r1268 r1258. See the checkin comments there.
At the moment input and output sample formats are hardwired to 16 bit in the two lines in pa_win_ds.c reading:
PaSampleFormat nativeInputFormats = paInt16;
It is possible to uncomment the following lines to support other sample formats:
PaSampleFormat nativeFormats = paUInt8 | paInt16 | paInt24 | paInt32 | paFloat32;
However this will make use of DS converters rather than using PortAudio converters to map to the best supported sample format. The main work left to do is to handle renegotiation of sample format if the requested format fails (ie if 24 bit is requested, but dsound fails, we need to fall back to 16 bit).
The issue has been discussed on the mailing list:
http://techweb.rfa.org/pipermail/portaudio/2008-January/008175.html
http://techweb.rfa.org/pipermail/portaudio/2008-February/008195.html
There have been other discussions here on when/why to use WAVEFORMATEX instead of WAVEFORMATEXTENSIBLE:
For example, there are some very popular soundcards with bugs in their WAVEFORMATEXTENSIBLE support:
http://techweb.rfa.org/pipermail/portaudio/2008-February/008237.html
Alec originally wrote:
I have attached a modified version of portaudio/src/hostapi/dsound/pa_win_ds.c, which has been patched to allow multiple (more than two) channels, and sample formats other than paInt16. This is achieved through the use of the WAVEFORMATEXTENSIBLE structure.
Of note:
The text was updated successfully, but these errors were encountered: