Skip to content
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

Closed
PortAudio-admin opened this issue Jul 27, 2007 · 5 comments · Fixed by #774
Closed

Enable >16bit output sample widths using DirectSound API #54

PortAudio-admin opened this issue Jul 27, 2007 · 5 comments · Fixed by #774
Labels
P3 Priority: Normal src-dsound MS DirectSound Host API /src/hostapi/dsound windows Affects MS Windows

Comments

@PortAudio-admin
Copy link
Collaborator

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:

  • I have coded away the PA sample format conversion, which is probably not in model for PortAudio. This can be re-introduced by specifying desired sample formats in the call to PaUtil_SelectClosestAvailableFormat().
  • The use of WAVEFORMATEXTENSIBLE requires us to define a channel mapping. I have used the technique of 1 channel -> FrontCenterSpeaker, N channels -> FirstNSpeakers. This makes sense to me, but be aware of the choice.
@PortAudio-admin
Copy link
Collaborator Author

Comment by @RossBencina

Some progress made, see also ticket #29

@PortAudio-admin
Copy link
Collaborator Author

Comment by @RossBencina

Renamed from "Enable multiple channels and different sample widths..." since multichannel has been implemented since r1268

@PortAudio-admin
Copy link
Collaborator Author

Comment by @RossBencina

Changed ticket description with more detail about current status of >16 bit support.

@PortAudio-admin
Copy link
Collaborator Author

Comment by @RossBencina

TRAC migration: propagating ticket status from TRAC

@PortAudio-admin
Copy link
Collaborator Author

PortAudio-admin commented Jan 27, 2012

Comment by @RossBencina

pa_win_ds.c.txt

originally added to Trac by alec_rogers 5 years ago.

@PortAudio-admin PortAudio-admin added windows Affects MS Windows P3 Priority: Normal src-dsound MS DirectSound Host API /src/hostapi/dsound labels Sep 24, 2020
dechamps added a commit to dechamps/portaudio that referenced this issue Feb 25, 2023
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
RossBencina pushed a commit that referenced this issue Dec 22, 2023
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P3 Priority: Normal src-dsound MS DirectSound Host API /src/hostapi/dsound windows Affects MS Windows
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant