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

Remove all alternative sample conversion code using lrintf in pa_converters.c #403

Merged
merged 1 commit into from
Sep 1, 2023

Conversation

RossBencina
Copy link
Collaborator

This is code guarded by PA_USE_C99_LRINTF. Fixes #390.

@RossBencina
Copy link
Collaborator Author

@dmitrykos I am asking for your review just in case you might care about this change. If you don't care, just say so. See #390 for details.

@RossBencina
Copy link
Collaborator Author

I posted about this to the mailing list. Let's wait and see whether anyone responds there before merging this one.

@RossBencina RossBencina added the src-common Common sources in /src/common label Dec 28, 2020
@dmitrykos
Copy link
Collaborator

@RossBencina, sorry I noticed this thread only now. I am in favor to remove lrintf() taking into account your findings in #390 thread.

The best way would be to use a cast to integer type and modify the rounding mode to - truncate towards zero. It is fast and rounding mode can be set on all platforms (Windows, Apple, Linux).

@Be-ing
Copy link
Collaborator

Be-ing commented Jan 21, 2021

There is a merge conflict now.

@RossBencina
Copy link
Collaborator Author

@dmitrykos cast to integer is unaffected by rounding mode. In fact, on x386 target cast to integer is slow because it always resets the rounding mode to truncate, then restores it, on newer architectures it probably uses some SSE that doesn't require setting the rounding mode. if used correctly lrintf should be faster than cast to integer -- that is a good reason to use it. But it needs to be done properly, then with benchmarks etc etc.

@dmitrykos
Copy link
Collaborator

dmitrykos commented Jan 27, 2021

@RossBencina, thank you for correcting me that a cast to integer is guaranteed to be in Round-Towards-Zero mode. Rounding mode though affects lrint so the change (removal of lrint) made the code portable and unaffected by the rounding mode which could be changed by a user.

I made small experiment and used Visual Studio 2019 (MSVC compiler) targeting Windows 10 (x86, x64).

#include <stdio.h>
#include <math.h>
#include <fenv.h>

int main()
{
	fesetround(FE_UPWARD);

	volatile float vf = 2.2f;

	volatile int vi0 = lrintf(vf);
	volatile int vi1 = (int)vf;

	printf("vi0=%d, vi1=%d", vi0, vi1);

	return 0;
}

The result is - vi0 = 3 when using lrintf and a cast to integer results in vi1 = 2, so it confirms that cast works as expected (Round-Towards-Zero mode) and lrintf is affected by the rounding mode.

Currently for x86 mode the MSVC compiler enforces the usage of SSE SIMD cvttss2si even if SSE is not explicitly specified in the compiler settings when application is targeting Windows 10:

x86:

volatile int vi1 = (int)vf;
00F61031  movss       xmm0,dword ptr [vf]  
00F61036  cvttss2si   eax,xmm0  
00F6103A  mov         dword ptr [vi0],eax  

x64:

volatile int vi1 = (int)vf;
00007FF7627016B4  movss       xmm0,dword ptr [vf]  
00007FF7627016BA  cvttss2si   eax,xmm0  
00007FF7627016BE  mov         dword ptr [vf],eax

In case of lrintf compiler is generating a function call and more instructions in x86 mode:

x86

volatile int vi0 = lrintf(vf);
00591018  movss       xmm0,dword ptr [vf]  
0059101D  movss       dword ptr [esp],xmm0  
00591022  call        dword ptr [__imp__lrintf (0592058h)]  
00591028  mov         dword ptr [ebp-8],eax  
0059102B  add         esp,4  

Shorter for x64 but still a function call:

x64:

volatile int vi0 = lrintf(vf);
00007FF62C8C169D  movss       xmm0,dword ptr [vf]  
00007FF62C8C16A3  call        qword ptr [__imp_lrintf (07FF62C8CA228h)]  
00007FF62C8C16A9  mov         dword ptr [rsp+38h],eax 

I also checked what GCC (MinGW.org GCC-6.3.0-1) is doing and the results are similar for a cast to integer when complier is using SSE SIMD.

x86 + SSE:

movss	20(%esp), %xmm0	 # vf, vf.2_6
cvttss2si	%xmm0, %eax	 # vf.2_6, vi1.3_7
movl	%eax, 28(%esp)	 # vi1.3_7, vi1

For lrintf GCC is using single fistpl FPU instruction:

flds	20(%esp)	 # vf
/APP
 # 764 "c:\mingw\include\math.h" 1
fistpl 28(%esp)	 # retval
 # 0 "" 2
/NO_APP
movl	28(%esp), %eax	 # retval, _9
movl	%eax, 24(%esp)	 # _9, vi0

If no SSE SIMD requested from the compiler then a cast to integer becomes not optimal because compiler has to set Round-Towards-Zero mode with fldcw surrounding fistpl, it makes code slower due to FPU mode switch:

flds	36(%esp)	 # vf
movb	$12, %ah	 #, tmp94
movw	%ax, 28(%esp)	 # tmp94,
fldcw	28(%esp)	 #
fistpl	24(%esp)	 #
fldcw	30(%esp)	 #
movl	24(%esp), %eax	 #, vi1.3_7
movl	%eax, 44(%esp)	 # vi1.3_7, vi1

It is what you mentioned "on x386 target cast to integer is slow because it always resets the rounding mode to truncate, then restores it".

So the conclusion is:

  1. If application is targeting x86 and not requesting SSE from the compiler then cast to integer will be not optimal in terms of performance due to additional usage of fldcw instruction surrounding fistpl.

  2. Usage of lrintf when code is compiled with MSVC or GCC and with SSE SIMD enabled is also not optimal because MSVC is doing a function call to __imp__lrintf while GCC is falling back to a FPU code that is causing more instructions and also vectorized optimization is no longer possible.

  3. Current change to the cast to integer looks optimal for x86/x64 when SSE SIMD is used but less optimal when compiler is using only FPU instructions.

  4. lrint is affected by the rounding mode and the code should be slower (not benchmarked) on Windows platform if generated by MSVC compiler due to a function call (compiler does not substitute it with a single fistpl like GCC does it).

@philburk philburk added this to the V19.8 milestone Mar 16, 2021
@philburk
Copy link
Collaborator

There is some interesting code in Android that does lots of PCM format conversions.
https://android.googlesource.com/platform/system/media/+/refs/heads/master/audio_utils/primitives.c

@RossBencina RossBencina self-assigned this Aug 29, 2022
…erters.c. this is code guarded by PA_USE_C99_LRINTF. Fixes #390.
@RossBencina RossBencina force-pushed the fix-390-remove-lrintf-from-pa-converters branch from 5094303 to 6edbfc7 Compare August 25, 2023 23:21
@RossBencina RossBencina merged commit 67ead0a into master Sep 1, 2023
21 checks passed
@RossBencina RossBencina deleted the fix-390-remove-lrintf-from-pa-converters branch September 1, 2023 22:46
bear101 added a commit to bear101/portaudio that referenced this pull request Mar 6, 2024
* Preparation to start patching - TODOS and directory src/hostapi/Oboe

* Added src/hostapi/oboe/README.md

* Added include/pa_oboe.h and src/hostapi/oboe/pa_oboe.cpp

* Added PA_USE_OBOE section to CMakeLists.txt

* Added PA_USE_OBOE section to CMakeLists.txt

* Heavily reworked CMake dependencies, added FindOboe.cmake, updated pa_oboe.cpp, more work needed

* Included build_all_PaOboe.sh, more work needed on CMake

* Included build_all_PaOboe.sh, more work needed on CMake

* Update src/hostapi/oboe/README.md

* bindings/cpp: CMake: support pkgconfig with RelWithDebInfo (PortAudio#822)

bindings/cpp: add  `RelWithDebInfo` to the configurations allowed to install portaudiocpp.pc, otherwise you won't have support for pkg-config when building a release package with separate debugging information. Besides that, RelWithDebInfo is identical to Release.

* Fix MSVC warning C4018 signed/unsigned mismatch (PortAudio#821)

See PortAudio#810

* Built shared library

* Polished bits

* mme: don't restrict the host buffer to 16-bit

Currently, the MME Host API code only creates 16-bit integer MME
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
MME 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 MME, 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 MME 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). This is pretty much the same idea as
PortAudio#774.

The new code assumes that MME 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 MME 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).

On pre-Vista Windows, this should still work all the way back to Windows
98 SE, because MME goes through KMixer which supports all formats [1].
Nevertheless, it's difficult to be sure, so this code checks the Windows
version it's running on and preserves the old behavior (i.e. always use
Int16) on pre-Vista Windows.

[1]: https://learn.microsoft.com/en-us/windows-hardware/drivers/audio/background-of-non-pcm-support#waveout-api

Fixes PortAudio#139

* Don't use absolute path when linking to macOS frameworks (PortAudio#829)

fixes PortAudio#828

* Fixing old problems

* Added some debug messages

* added new build script

* Added paOboe in the paHostApi array

* Added paOboe in pa_unix_hostapis.c

* Working patch

* win: New PaWinUtil_GetOsVersion() function for getting Windows OS version. Refactored WASAPI, DS, MME and WDMKS host back-ends to use PaWinUtil_GetOsVersion() instead of direct OS API.

* Ready for other users to compile/build

* Updated oboe/Readme.md

* Added sharing mode selection

* Fixed minor issue with sharing mode selection

* Removed references to KCTI

* Fixed error callback, added performance mode autoselection

* Minor change to CMakeLists, added low latency costant in pa_oboe.h

* Deleted Build_PaOboe.sh

* Ready to push (removed my paths to Oboe directory and Android NDK)

* Update README.md

* Update README.md

* remove all alternative sample conversion code using lrintf in pa_converters.c (PortAudio#403)

removes the code guarded by PA_USE_C99_LRINTF
See PortAudio#390

* updated readme

* fixed CMakeLists.txt

* fixed FindOboe.cmake

* Preparation to start patching - TODOS and directory src/hostapi/Oboe

* Added src/hostapi/oboe/README.md

* Added include/pa_oboe.h and src/hostapi/oboe/pa_oboe.cpp

* Added PA_USE_OBOE section to CMakeLists.txt

* Added PA_USE_OBOE section to CMakeLists.txt

* Heavily reworked CMake dependencies, added FindOboe.cmake, updated pa_oboe.cpp, more work needed

* Included build_all_PaOboe.sh, more work needed on CMake

* Included build_all_PaOboe.sh, more work needed on CMake

* Built shared library

* Polished bits

* Fixing old problems

* Added some debug messages

* added new build script

* Added paOboe in the paHostApi array

* Added paOboe in pa_unix_hostapis.c

* Working patch

* Ready for other users to compile/build

* Updated oboe/Readme.md

* Added sharing mode selection

* Fixed minor issue with sharing mode selection

* Removed references to KCTI

* Fixed error callback, added performance mode autoselection

* Minor change to CMakeLists, added low latency costant in pa_oboe.h

* Deleted Build_PaOboe.sh

* Ready to push (removed my paths to Oboe directory and Android NDK)

* Update src/hostapi/oboe/README.md

* Update README.md

* Update README.md

* updated readme

* fixed CMakeLists.txt

* fixed FindOboe.cmake

* corrected oboe/Readme.md

* Updated oboe/Readme.md

* PulseAudio Portaudio HostAPI (PortAudio#336)

Adds support for PulseAudio API on Linux.

For more information about Pulseaudio visit: https://www.freedesktop.org/wiki/Software/PulseAudio/

---------

Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Co-authored-by: sqweek <sqweek@gmail.com>
Co-authored-by: Daniel Schürmann <daschuer@mixxx.org>
Co-authored-by: Mooneer Salem <mooneer@gmail.com>
Co-authored-by: Be <be.0@gmx.com>
Co-authored-by: Mario Kleiner <mario.kleiner.de@gmail.com>

* pulseaudio: Move Pulseaudio include in correct place when using autoconf (PortAudio#843)

As Jack and Pulseaudio both needs Ringbuffer that include can
be done in same place. In configure.in also Pulseaudio header
file was included before it was sure that it was really needed.

Commit makes sure that Pulseaudio include is available only if
it's needed as it can cause failing in build if Pulseaudio
develoment files are not available.

* added .idea to gitignore

* added .idea to gitignore

* restored workflows directory

* Minor fixes to FindOboe.cmake

* Enhanced prebuilt libraries compatibility in FindOboe.cmake

* Minor changes to Pa_Oboe/Readme and pa_oboe.cpp

* Removed auto latency tuning in favor of simpler impleentation in pa_oboe.cpp

* Set paFloat32 as default format in pa_oboe.cpp

* Renamed most of the variables according to best coding practices.

* Added separate callback class to fix the single-stream issue.

* Modified OboeEngine accordingly

* Adjusted the code in the rest of pa_oboe.cpp

* Removed stop and close phases of OboeEngine::restartStream

* Updated functions' description

* minor description corrections

* fixed all compiling errors generated by typos

* Added OboeMediator class in place of OboeCallback, that mediates PortAudio C stream struct and the C++ OboeEngine class

* Fixed allocation problem, working PaOboe implementation

* Fix 'pulseaudioHostApi' use-after-free/null ptr deref in PaPulseAudio_Initialize (PortAudio#847)

The call to PaPulseAudio_UnLock( pulseaudioHostApi->mainloop ) in error-label is performed on 'pulseaudioHostApi' after 'pulseaudioHostApi' has been freed by PaPulseAudio_Free and set to NULL.

* wdmks: declare GUIDs with selectany attribute (PortAudio#846)

* wdmks: declare GUIDs with selectany attribute

Match the behavior of guiddef.h in both mingw and the Windows SDK headers. This prevents linking errors caused by multiply defined symbols when linking against certain Windows SDK libs (like dxguid.lib).

* Make sure this works even if DECLSPEC_SELECTANY is not defined

---------

Co-authored-by: Ross Bencina <rossb@audiomulch.com>

* fixed README.md indenting

* Removed .idea folder from repo

* replaced 'g_' with 'paOboe_' in non-static global variables

* replaced 'm_' prefix with 'm' prefix

* fixed OboeEngine::tryStream as requested

* PulseAudio Portaudio HostAPI (PortAudio#336)

Adds support for PulseAudio API on Linux.

For more information about Pulseaudio visit: https://www.freedesktop.org/wiki/Software/PulseAudio/

---------

Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Co-authored-by: sqweek <sqweek@gmail.com>
Co-authored-by: Daniel Schürmann <daschuer@mixxx.org>
Co-authored-by: Mooneer Salem <mooneer@gmail.com>
Co-authored-by: Be <be.0@gmx.com>
Co-authored-by: Mario Kleiner <mario.kleiner.de@gmail.com>

* pulseaudio: Move Pulseaudio include in correct place when using autoconf (PortAudio#843)

As Jack and Pulseaudio both needs Ringbuffer that include can
be done in same place. In configure.in also Pulseaudio header
file was included before it was sure that it was really needed.

Commit makes sure that Pulseaudio include is available only if
it's needed as it can cause failing in build if Pulseaudio
develoment files are not available.

* restored workflows directory

* Minor fixes to FindOboe.cmake

* Enhanced prebuilt libraries compatibility in FindOboe.cmake

* Minor changes to Pa_Oboe/Readme and pa_oboe.cpp

* Removed auto latency tuning in favor of simpler impleentation in pa_oboe.cpp

* Set paFloat32 as default format in pa_oboe.cpp

* Renamed most of the variables according to best coding practices.

* Added separate callback class to fix the single-stream issue.

* Modified OboeEngine accordingly

* Adjusted the code in the rest of pa_oboe.cpp

* Removed stop and close phases of OboeEngine::restartStream

* Updated functions' description

* minor description corrections

* fixed all compiling errors generated by typos

* Added OboeMediator class in place of OboeCallback, that mediates PortAudio C stream struct and the C++ OboeEngine class

* Fixed allocation problem, working PaOboe implementation

* fixed README.md indenting

* Removed .idea folder from repo

* replaced 'g_' with 'paOboe_' in non-static global variables

* replaced 'm_' prefix with 'm' prefix

* fixed OboeEngine::tryStream as requested

* Changed names to improve readability, i.e. OboeStream -> PaOboeStream

* fixed all compiling errors generated by typos

* Fixed minor problem with TryStream

* fixed long line in FindOboe.cmake

* fixed typos in pa_oboe.cpp

* set to verbose some logs

* Fixed minor problem with TryStream

* fixed long line in FindOboe.cmake

* fixed typos in pa_oboe.cpp

* set to verbose some logs

* Better handling of format in paOboe, removed junk code from CMakeLists

* Improved readability of some variables

* Removed '#include oboe/Oboe.h' from pa_oboe.h, and modified host api implementation accordingly

* static cast fixes

---------

Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Co-authored-by: Carlo Benfatti <benfatti@netresults.it>
Co-authored-by: hopefulGiupplo <116260612+hopefulGiupplo@users.noreply.github.com>
Co-authored-by: Carlo Bramini <30959007+carlo-bramini@users.noreply.github.com>
Co-authored-by: Etienne Dechamps <etienne@edechamps.fr>
Co-authored-by: Daniel Schürmann <daschuer@mixxx.org>
Co-authored-by: dmitrykos <dmitrykos@neutroncode.com>
Co-authored-by: Ross Bencina <rossb@audiomulch.com>
Co-authored-by: Tuukka Pasanen <pasanen.tuukka@gmail.com>
Co-authored-by: sqweek <sqweek@gmail.com>
Co-authored-by: Mooneer Salem <mooneer@gmail.com>
Co-authored-by: Be <be.0@gmx.com>
Co-authored-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Co-authored-by: Tuukka Pasanen <tuukka.pasanen@ilmi.fi>
Co-authored-by: invertego <invertego@users.noreply.github.com>
bear101 added a commit to bear101/portaudio that referenced this pull request Mar 6, 2024
* Preparation to start patching - TODOS and directory src/hostapi/Oboe

* Added src/hostapi/oboe/README.md

* Added include/pa_oboe.h and src/hostapi/oboe/pa_oboe.cpp

* Added PA_USE_OBOE section to CMakeLists.txt

* Added PA_USE_OBOE section to CMakeLists.txt

* Heavily reworked CMake dependencies, added FindOboe.cmake, updated pa_oboe.cpp, more work needed

* Included build_all_PaOboe.sh, more work needed on CMake

* Included build_all_PaOboe.sh, more work needed on CMake

* Update src/hostapi/oboe/README.md

* bindings/cpp: CMake: support pkgconfig with RelWithDebInfo (PortAudio#822)

bindings/cpp: add  `RelWithDebInfo` to the configurations allowed to install portaudiocpp.pc, otherwise you won't have support for pkg-config when building a release package with separate debugging information. Besides that, RelWithDebInfo is identical to Release.

* Fix MSVC warning C4018 signed/unsigned mismatch (PortAudio#821)

See PortAudio#810

* Built shared library

* Polished bits

* mme: don't restrict the host buffer to 16-bit

Currently, the MME Host API code only creates 16-bit integer MME
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
MME 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 MME, 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 MME 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). This is pretty much the same idea as

The new code assumes that MME 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 MME 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).

On pre-Vista Windows, this should still work all the way back to Windows
98 SE, because MME goes through KMixer which supports all formats [1].
Nevertheless, it's difficult to be sure, so this code checks the Windows
version it's running on and preserves the old behavior (i.e. always use
Int16) on pre-Vista Windows.

[1]: https://learn.microsoft.com/en-us/windows-hardware/drivers/audio/background-of-non-pcm-support#waveout-api

Fixes PortAudio#139

* Don't use absolute path when linking to macOS frameworks (PortAudio#829)

fixes PortAudio#828

* Fixing old problems

* Added some debug messages

* added new build script

* Added paOboe in the paHostApi array

* Added paOboe in pa_unix_hostapis.c

* Working patch

* win: New PaWinUtil_GetOsVersion() function for getting Windows OS version. Refactored WASAPI, DS, MME and WDMKS host back-ends to use PaWinUtil_GetOsVersion() instead of direct OS API.

* Ready for other users to compile/build

* Updated oboe/Readme.md

* Added sharing mode selection

* Fixed minor issue with sharing mode selection

* Removed references to KCTI

* Fixed error callback, added performance mode autoselection

* Minor change to CMakeLists, added low latency costant in pa_oboe.h

* Deleted Build_PaOboe.sh

* Ready to push (removed my paths to Oboe directory and Android NDK)

* Update README.md

* Update README.md

* remove all alternative sample conversion code using lrintf in pa_converters.c (PortAudio#403)

removes the code guarded by PA_USE_C99_LRINTF
See PortAudio#390

* updated readme

* fixed CMakeLists.txt

* fixed FindOboe.cmake

* Preparation to start patching - TODOS and directory src/hostapi/Oboe

* Added src/hostapi/oboe/README.md

* Added include/pa_oboe.h and src/hostapi/oboe/pa_oboe.cpp

* Added PA_USE_OBOE section to CMakeLists.txt

* Added PA_USE_OBOE section to CMakeLists.txt

* Heavily reworked CMake dependencies, added FindOboe.cmake, updated pa_oboe.cpp, more work needed

* Included build_all_PaOboe.sh, more work needed on CMake

* Included build_all_PaOboe.sh, more work needed on CMake

* Built shared library

* Polished bits

* Fixing old problems

* Added some debug messages

* added new build script

* Added paOboe in the paHostApi array

* Added paOboe in pa_unix_hostapis.c

* Working patch

* Ready for other users to compile/build

* Updated oboe/Readme.md

* Added sharing mode selection

* Fixed minor issue with sharing mode selection

* Removed references to KCTI

* Fixed error callback, added performance mode autoselection

* Minor change to CMakeLists, added low latency costant in pa_oboe.h

* Deleted Build_PaOboe.sh

* Ready to push (removed my paths to Oboe directory and Android NDK)

* Update src/hostapi/oboe/README.md

* Update README.md

* Update README.md

* updated readme

* fixed CMakeLists.txt

* fixed FindOboe.cmake

* corrected oboe/Readme.md

* Updated oboe/Readme.md

* PulseAudio Portaudio HostAPI (PortAudio#336)

Adds support for PulseAudio API on Linux.

For more information about Pulseaudio visit: https://www.freedesktop.org/wiki/Software/PulseAudio/

---------

Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Co-authored-by: sqweek <sqweek@gmail.com>
Co-authored-by: Daniel Schürmann <daschuer@mixxx.org>
Co-authored-by: Mooneer Salem <mooneer@gmail.com>
Co-authored-by: Be <be.0@gmx.com>
Co-authored-by: Mario Kleiner <mario.kleiner.de@gmail.com>

* pulseaudio: Move Pulseaudio include in correct place when using autoconf (PortAudio#843)

As Jack and Pulseaudio both needs Ringbuffer that include can
be done in same place. In configure.in also Pulseaudio header
file was included before it was sure that it was really needed.

Commit makes sure that Pulseaudio include is available only if
it's needed as it can cause failing in build if Pulseaudio
develoment files are not available.

* added .idea to gitignore

* added .idea to gitignore

* restored workflows directory

* Minor fixes to FindOboe.cmake

* Enhanced prebuilt libraries compatibility in FindOboe.cmake

* Minor changes to Pa_Oboe/Readme and pa_oboe.cpp

* Removed auto latency tuning in favor of simpler impleentation in pa_oboe.cpp

* Set paFloat32 as default format in pa_oboe.cpp

* Renamed most of the variables according to best coding practices.

* Added separate callback class to fix the single-stream issue.

* Modified OboeEngine accordingly

* Adjusted the code in the rest of pa_oboe.cpp

* Removed stop and close phases of OboeEngine::restartStream

* Updated functions' description

* minor description corrections

* fixed all compiling errors generated by typos

* Added OboeMediator class in place of OboeCallback, that mediates PortAudio C stream struct and the C++ OboeEngine class

* Fixed allocation problem, working PaOboe implementation

* Fix 'pulseaudioHostApi' use-after-free/null ptr deref in PaPulseAudio_Initialize (PortAudio#847)

The call to PaPulseAudio_UnLock( pulseaudioHostApi->mainloop ) in error-label is performed on 'pulseaudioHostApi' after 'pulseaudioHostApi' has been freed by PaPulseAudio_Free and set to NULL.

* wdmks: declare GUIDs with selectany attribute (PortAudio#846)

* wdmks: declare GUIDs with selectany attribute

Match the behavior of guiddef.h in both mingw and the Windows SDK headers. This prevents linking errors caused by multiply defined symbols when linking against certain Windows SDK libs (like dxguid.lib).

* Make sure this works even if DECLSPEC_SELECTANY is not defined

---------

Co-authored-by: Ross Bencina <rossb@audiomulch.com>

* fixed README.md indenting

* Removed .idea folder from repo

* replaced 'g_' with 'paOboe_' in non-static global variables

* replaced 'm_' prefix with 'm' prefix

* fixed OboeEngine::tryStream as requested

* PulseAudio Portaudio HostAPI (PortAudio#336)

Adds support for PulseAudio API on Linux.

For more information about Pulseaudio visit: https://www.freedesktop.org/wiki/Software/PulseAudio/

---------

Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Co-authored-by: sqweek <sqweek@gmail.com>
Co-authored-by: Daniel Schürmann <daschuer@mixxx.org>
Co-authored-by: Mooneer Salem <mooneer@gmail.com>
Co-authored-by: Be <be.0@gmx.com>
Co-authored-by: Mario Kleiner <mario.kleiner.de@gmail.com>

* pulseaudio: Move Pulseaudio include in correct place when using autoconf (PortAudio#843)

As Jack and Pulseaudio both needs Ringbuffer that include can
be done in same place. In configure.in also Pulseaudio header
file was included before it was sure that it was really needed.

Commit makes sure that Pulseaudio include is available only if
it's needed as it can cause failing in build if Pulseaudio
develoment files are not available.

* restored workflows directory

* Minor fixes to FindOboe.cmake

* Enhanced prebuilt libraries compatibility in FindOboe.cmake

* Minor changes to Pa_Oboe/Readme and pa_oboe.cpp

* Removed auto latency tuning in favor of simpler impleentation in pa_oboe.cpp

* Set paFloat32 as default format in pa_oboe.cpp

* Renamed most of the variables according to best coding practices.

* Added separate callback class to fix the single-stream issue.

* Modified OboeEngine accordingly

* Adjusted the code in the rest of pa_oboe.cpp

* Removed stop and close phases of OboeEngine::restartStream

* Updated functions' description

* minor description corrections

* fixed all compiling errors generated by typos

* Added OboeMediator class in place of OboeCallback, that mediates PortAudio C stream struct and the C++ OboeEngine class

* Fixed allocation problem, working PaOboe implementation

* fixed README.md indenting

* Removed .idea folder from repo

* replaced 'g_' with 'paOboe_' in non-static global variables

* replaced 'm_' prefix with 'm' prefix

* fixed OboeEngine::tryStream as requested

* Changed names to improve readability, i.e. OboeStream -> PaOboeStream

* fixed all compiling errors generated by typos

* Fixed minor problem with TryStream

* fixed long line in FindOboe.cmake

* fixed typos in pa_oboe.cpp

* set to verbose some logs

* Fixed minor problem with TryStream

* fixed long line in FindOboe.cmake

* fixed typos in pa_oboe.cpp

* set to verbose some logs

* Better handling of format in paOboe, removed junk code from CMakeLists

* Improved readability of some variables

* Removed '#include oboe/Oboe.h' from pa_oboe.h, and modified host api implementation accordingly

* static cast fixes

---------

Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Co-authored-by: Carlo Benfatti <benfatti@netresults.it>
Co-authored-by: hopefulGiupplo <116260612+hopefulGiupplo@users.noreply.github.com>
Co-authored-by: Carlo Bramini <30959007+carlo-bramini@users.noreply.github.com>
Co-authored-by: Etienne Dechamps <etienne@edechamps.fr>
Co-authored-by: Daniel Schürmann <daschuer@mixxx.org>
Co-authored-by: dmitrykos <dmitrykos@neutroncode.com>
Co-authored-by: Ross Bencina <rossb@audiomulch.com>
Co-authored-by: Tuukka Pasanen <pasanen.tuukka@gmail.com>
Co-authored-by: sqweek <sqweek@gmail.com>
Co-authored-by: Mooneer Salem <mooneer@gmail.com>
Co-authored-by: Be <be.0@gmx.com>
Co-authored-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Co-authored-by: Tuukka Pasanen <tuukka.pasanen@ilmi.fi>
Co-authored-by: invertego <invertego@users.noreply.github.com>
bear101 added a commit to bear101/portaudio that referenced this pull request Mar 6, 2024
* Preparation to start patching - TODOS and directory src/hostapi/Oboe

* Added src/hostapi/oboe/README.md

* Added include/pa_oboe.h and src/hostapi/oboe/pa_oboe.cpp

* Added PA_USE_OBOE section to CMakeLists.txt

* Added PA_USE_OBOE section to CMakeLists.txt

* Heavily reworked CMake dependencies, added FindOboe.cmake, updated pa_oboe.cpp, more work needed

* Included build_all_PaOboe.sh, more work needed on CMake

* Included build_all_PaOboe.sh, more work needed on CMake

* Update src/hostapi/oboe/README.md

* bindings/cpp: CMake: support pkgconfig with RelWithDebInfo (PortAudio#822)

bindings/cpp: add  `RelWithDebInfo` to the configurations allowed to install portaudiocpp.pc, otherwise you won't have support for pkg-config when building a release package with separate debugging information. Besides that, RelWithDebInfo is identical to Release.

* Fix MSVC warning C4018 signed/unsigned mismatch (PortAudio#821)

See PortAudio#810

* Built shared library

* Polished bits

* mme: don't restrict the host buffer to 16-bit

Currently, the MME Host API code only creates 16-bit integer MME
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
MME 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 MME, 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 MME 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). This is pretty much the same idea as

The new code assumes that MME 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 MME 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).

On pre-Vista Windows, this should still work all the way back to Windows
98 SE, because MME goes through KMixer which supports all formats [1].
Nevertheless, it's difficult to be sure, so this code checks the Windows
version it's running on and preserves the old behavior (i.e. always use
Int16) on pre-Vista Windows.

[1]: https://learn.microsoft.com/en-us/windows-hardware/drivers/audio/background-of-non-pcm-support#waveout-api

Fixes PortAudio#139

* Don't use absolute path when linking to macOS frameworks (PortAudio#829)

fixes PortAudio#828

* Fixing old problems

* Added some debug messages

* added new build script

* Added paOboe in the paHostApi array

* Added paOboe in pa_unix_hostapis.c

* Working patch

* win: New PaWinUtil_GetOsVersion() function for getting Windows OS version. Refactored WASAPI, DS, MME and WDMKS host back-ends to use PaWinUtil_GetOsVersion() instead of direct OS API.

* Ready for other users to compile/build

* Updated oboe/Readme.md

* Added sharing mode selection

* Fixed minor issue with sharing mode selection

* Removed references to KCTI

* Fixed error callback, added performance mode autoselection

* Minor change to CMakeLists, added low latency costant in pa_oboe.h

* Deleted Build_PaOboe.sh

* Ready to push (removed my paths to Oboe directory and Android NDK)

* Update README.md

* Update README.md

* remove all alternative sample conversion code using lrintf in pa_converters.c (PortAudio#403)

removes the code guarded by PA_USE_C99_LRINTF
See PortAudio#390

* updated readme

* fixed CMakeLists.txt

* fixed FindOboe.cmake

* Preparation to start patching - TODOS and directory src/hostapi/Oboe

* Added src/hostapi/oboe/README.md

* Added include/pa_oboe.h and src/hostapi/oboe/pa_oboe.cpp

* Added PA_USE_OBOE section to CMakeLists.txt

* Added PA_USE_OBOE section to CMakeLists.txt

* Heavily reworked CMake dependencies, added FindOboe.cmake, updated pa_oboe.cpp, more work needed

* Included build_all_PaOboe.sh, more work needed on CMake

* Included build_all_PaOboe.sh, more work needed on CMake

* Built shared library

* Polished bits

* Fixing old problems

* Added some debug messages

* added new build script

* Added paOboe in the paHostApi array

* Added paOboe in pa_unix_hostapis.c

* Working patch

* Ready for other users to compile/build

* Updated oboe/Readme.md

* Added sharing mode selection

* Fixed minor issue with sharing mode selection

* Removed references to KCTI

* Fixed error callback, added performance mode autoselection

* Minor change to CMakeLists, added low latency costant in pa_oboe.h

* Deleted Build_PaOboe.sh

* Ready to push (removed my paths to Oboe directory and Android NDK)

* Update src/hostapi/oboe/README.md

* Update README.md

* Update README.md

* updated readme

* fixed CMakeLists.txt

* fixed FindOboe.cmake

* corrected oboe/Readme.md

* Updated oboe/Readme.md

* PulseAudio Portaudio HostAPI (PortAudio#336)

Adds support for PulseAudio API on Linux.

For more information about Pulseaudio visit: https://www.freedesktop.org/wiki/Software/PulseAudio/

---------

Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Co-authored-by: sqweek <sqweek@gmail.com>
Co-authored-by: Daniel Schürmann <daschuer@mixxx.org>
Co-authored-by: Mooneer Salem <mooneer@gmail.com>
Co-authored-by: Be <be.0@gmx.com>
Co-authored-by: Mario Kleiner <mario.kleiner.de@gmail.com>

* pulseaudio: Move Pulseaudio include in correct place when using autoconf (PortAudio#843)

As Jack and Pulseaudio both needs Ringbuffer that include can
be done in same place. In configure.in also Pulseaudio header
file was included before it was sure that it was really needed.

Commit makes sure that Pulseaudio include is available only if
it's needed as it can cause failing in build if Pulseaudio
develoment files are not available.

* added .idea to gitignore

* added .idea to gitignore

* restored workflows directory

* Minor fixes to FindOboe.cmake

* Enhanced prebuilt libraries compatibility in FindOboe.cmake

* Minor changes to Pa_Oboe/Readme and pa_oboe.cpp

* Removed auto latency tuning in favor of simpler impleentation in pa_oboe.cpp

* Set paFloat32 as default format in pa_oboe.cpp

* Renamed most of the variables according to best coding practices.

* Added separate callback class to fix the single-stream issue.

* Modified OboeEngine accordingly

* Adjusted the code in the rest of pa_oboe.cpp

* Removed stop and close phases of OboeEngine::restartStream

* Updated functions' description

* minor description corrections

* fixed all compiling errors generated by typos

* Added OboeMediator class in place of OboeCallback, that mediates PortAudio C stream struct and the C++ OboeEngine class

* Fixed allocation problem, working PaOboe implementation

* Fix 'pulseaudioHostApi' use-after-free/null ptr deref in PaPulseAudio_Initialize (PortAudio#847)

The call to PaPulseAudio_UnLock( pulseaudioHostApi->mainloop ) in error-label is performed on 'pulseaudioHostApi' after 'pulseaudioHostApi' has been freed by PaPulseAudio_Free and set to NULL.

* wdmks: declare GUIDs with selectany attribute (PortAudio#846)

* wdmks: declare GUIDs with selectany attribute

Match the behavior of guiddef.h in both mingw and the Windows SDK headers. This prevents linking errors caused by multiply defined symbols when linking against certain Windows SDK libs (like dxguid.lib).

* Make sure this works even if DECLSPEC_SELECTANY is not defined

---------

Co-authored-by: Ross Bencina <rossb@audiomulch.com>

* fixed README.md indenting

* Removed .idea folder from repo

* replaced 'g_' with 'paOboe_' in non-static global variables

* replaced 'm_' prefix with 'm' prefix

* fixed OboeEngine::tryStream as requested

* PulseAudio Portaudio HostAPI (PortAudio#336)

Adds support for PulseAudio API on Linux.

For more information about Pulseaudio visit: https://www.freedesktop.org/wiki/Software/PulseAudio/

---------

Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Co-authored-by: sqweek <sqweek@gmail.com>
Co-authored-by: Daniel Schürmann <daschuer@mixxx.org>
Co-authored-by: Mooneer Salem <mooneer@gmail.com>
Co-authored-by: Be <be.0@gmx.com>
Co-authored-by: Mario Kleiner <mario.kleiner.de@gmail.com>

* pulseaudio: Move Pulseaudio include in correct place when using autoconf (PortAudio#843)

As Jack and Pulseaudio both needs Ringbuffer that include can
be done in same place. In configure.in also Pulseaudio header
file was included before it was sure that it was really needed.

Commit makes sure that Pulseaudio include is available only if
it's needed as it can cause failing in build if Pulseaudio
develoment files are not available.

* restored workflows directory

* Minor fixes to FindOboe.cmake

* Enhanced prebuilt libraries compatibility in FindOboe.cmake

* Minor changes to Pa_Oboe/Readme and pa_oboe.cpp

* Removed auto latency tuning in favor of simpler impleentation in pa_oboe.cpp

* Set paFloat32 as default format in pa_oboe.cpp

* Renamed most of the variables according to best coding practices.

* Added separate callback class to fix the single-stream issue.

* Modified OboeEngine accordingly

* Adjusted the code in the rest of pa_oboe.cpp

* Removed stop and close phases of OboeEngine::restartStream

* Updated functions' description

* minor description corrections

* fixed all compiling errors generated by typos

* Added OboeMediator class in place of OboeCallback, that mediates PortAudio C stream struct and the C++ OboeEngine class

* Fixed allocation problem, working PaOboe implementation

* fixed README.md indenting

* Removed .idea folder from repo

* replaced 'g_' with 'paOboe_' in non-static global variables

* replaced 'm_' prefix with 'm' prefix

* fixed OboeEngine::tryStream as requested

* Changed names to improve readability, i.e. OboeStream -> PaOboeStream

* fixed all compiling errors generated by typos

* Fixed minor problem with TryStream

* fixed long line in FindOboe.cmake

* fixed typos in pa_oboe.cpp

* set to verbose some logs

* Fixed minor problem with TryStream

* fixed long line in FindOboe.cmake

* fixed typos in pa_oboe.cpp

* set to verbose some logs

* Better handling of format in paOboe, removed junk code from CMakeLists

* Improved readability of some variables

* Removed '#include oboe/Oboe.h' from pa_oboe.h, and modified host api implementation accordingly

* static cast fixes

---------

Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Co-authored-by: Carlo Benfatti <benfatti@netresults.it>
Co-authored-by: hopefulGiupplo <116260612+hopefulGiupplo@users.noreply.github.com>
Co-authored-by: Carlo Bramini <30959007+carlo-bramini@users.noreply.github.com>
Co-authored-by: Etienne Dechamps <etienne@edechamps.fr>
Co-authored-by: Daniel Schürmann <daschuer@mixxx.org>
Co-authored-by: dmitrykos <dmitrykos@neutroncode.com>
Co-authored-by: Ross Bencina <rossb@audiomulch.com>
Co-authored-by: Tuukka Pasanen <pasanen.tuukka@gmail.com>
Co-authored-by: sqweek <sqweek@gmail.com>
Co-authored-by: Mooneer Salem <mooneer@gmail.com>
Co-authored-by: Be <be.0@gmx.com>
Co-authored-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Co-authored-by: Tuukka Pasanen <tuukka.pasanen@ilmi.fi>
Co-authored-by: invertego <invertego@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
src-common Common sources in /src/common
Projects
None yet
Development

Successfully merging this pull request may close these issues.

pa_converters.c lrintf usage is [was] suspect: does not reproduce the same values as non-lrintf code
4 participants