Commit graph

38 commits

Author SHA1 Message Date
Jakub Janků
766a126380 wasapi: split gst_wasapi_util_get_device_client()
The functionality now resides in
gst_wasapi_util_get_device() and
gst_wasapi_util_get_audio_client().

This is a preparatory patch. It will be used in the following
patch to init/deinit the AudioClient separately from the device.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2096>
2021-07-12 13:47:06 +02:00
Matthew Waters
640a65bf96 gst: don't use volatile to mean atomic
volatile is not sufficient to provide atomic guarantees and real atomics
should be used instead.  GCC 11 has started warning about using volatile
with atomic operations.

https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1719

Discovered in https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/issues/868

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2098>
2021-03-22 14:34:36 +11:00
Seungha Yang
c1093e3481 plugins: Use g_win32_error_message for HRESULT to string conversion
We don't need to duplicate a method for HRESULT error code to string
conversion. This patch is intended to
* Remove duplicated code
* Ensure FormatMessageW (Unicode version) and avoid FormatMessageA
  (ANSI version), as the ANSI format is not portable at all.
  Note that if "UNICODE" is not defined, FormatMessageA will be aliased
  as FormatMessage by default.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1442>
2020-07-18 11:05:52 +09:00
Nirbheek Chauhan
6d27c0ac08 wasapisrc: Fix glitching and clock skew issues
We were miscalculating the device period, i.e. the number of frames
we'll get from WASAPI in each IAudioClient::GetBuffer call, due to
a calculation mistake (truncate instead of round).

For example, on my machine when the aux input is set to 44.1KHz, the
reported device period is 101587, which comes out to 447.998 frames
per ::GetBuffer call. In reality we will, of course, get 448 frames
per call, but we were truncating, so we expected 447 and were
discarding one frame every time. This led to glitching, and skew over
time.

Interestingly, I can only see this with 44.1Khz. 48Khz/96Khz are fine,
because the device period is a more 'even' number.

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/issues/806
2019-11-28 08:59:41 +00:00
Seungha Yang
76654539b9 wasapi: Fix build warnings
gstwasapiutil.c(173) : warning C4715: 'gst_wasapi_device_role_to_erole': not all control paths return a value
gstwasapiutil.c(188) : warning C4715: 'gst_wasapi_erole_to_device_role': not all control paths return a value
2019-10-14 14:43:59 +00:00
Seungha Yang
baaa965ebc wasapi: Don't cast GstDeviceProvider to GstElement
The GstDeviceProvider isn't subclass of GstElement.

(gst-device-monitor-1.0:49356): GLib-GObject-WARNING **: 20:21:18.651:
invalid cast from 'GstWasapiDeviceProvider' to 'GstElement'
2019-10-14 14:43:59 +00:00
Ignacio Casal Quinteiro
1181436545 wasapi: fix symbol redefinition build error 2019-08-12 07:20:43 +00:00
Nirbheek Chauhan
fffb2aa12f misc: Fix warnings on Cerbero MinGW
gstladspa.c:360:5: error: zero-length ms_printf format string [-Werror=format-zero-length]

vad_private.c:108:3: error: this decimal constant is unsigned only in ISO C90 [-Werror]

gstdecklinkvideosink.cpp:478:32: error: comparison between 'BMDTimecodeFormat {aka enum _BMDTimecodeFormat}' and 'enum GstDecklinkTimecodeFormat' [-Werror=enum-compare]

win/DeckLinkAPI_i.c:72:8: error: extra tokens at end of #endif directive [-Werror]

win/DeckLinkAPIDispatch.cpp:35:10: error: unused variable 'res' [-Werror=unused-variable]

gstwasapiutil.c:733:3: error: format '%x' expects argument of type 'unsigned int', but argument 8 has type 'DWORD' [-Werror=format]
gstwasapiutil.c:733:3: error: format '%x' expects argument of type 'unsigned int', but argument 9 has type 'guint64' [-Werror=format]

kshelpers.c:446:3: error: missing braces around initializer [-Werror=missing-braces]
kshelpers.c:446:3: error: (near initialization for 'known_property_sets[0].guid.Data4') [-Werror=missing-braces]
2019-02-06 00:10:28 +05:30
Jacek Tomaszewski
60146e3097 wasapi: Fixed corner-cases in mapping of channel mask
'channel-mask' field should not be put in caps if channel mask is 0x0

Mapping WASAPI channel mask to GST equivalent was going only over
first nChannels elements of wasapi_to_gst_pos array, translating, for
example, WASAPI's 0x63f to GST's 0x3f instead of 0xc3f.

When 'channel-mask' is specified as NULL, it signifies that there's
need to do downmix or upmix and it makes caps negotiation with
audioconvert element impossible. Just omit it.

Signed-off-by: Nirbheek Chauhan <nirbheek@centricular.com>
2019-01-21 21:10:55 +05:30
Nirbheek Chauhan
f62b7fd712 wasapi: Remove code that sets thread priority
This is now handled directly in gstaudiosrc/sink, and we were setting
it in the wrong thread anyway. prepare() is not the same thread as
sink_write() or src_read().
2018-09-11 01:00:21 +05:30
Christoph Reiter
5a1b37b1f3 wasapisink: fix regression in shared mode segment size
In commit fd806628a8 (839cc3926 in the stable branch) I changed the
segment size to match exactly the buffer size.  I missed that this is
only valid in exclusive mode and in shared mode the buffer size is
a multiple of the device period.

Revert the logic for the shared mode.

https://bugzilla.gnome.org/show_bug.cgi?id=796354

https://bugzilla.gnome.org/show_bug.cgi?id=796858
2018-08-02 17:00:03 +05:30
Christoph Reiter
0aed64426b wasapisink: fix a rounding error when calculating the buffer frame count
The calculation for the frame count in the non-aligned case resulted in
a one too low buffer frame count.

This resulted in:
1) exclusive mode not working as the frame count has to match
   exactly there.
2) Buffer underruns in shared mode as the current write() code doesn't
   handle catching up to low buffer levels (fixed in the next commit)

To fix just use the wasapi API to get the buffer size which will always
be correct.

https://bugzilla.gnome.org/show_bug.cgi?id=796354
2018-05-25 19:06:16 +05:30
Nirbheek Chauhan
ff17a404b3 wasapi: Call CoIn/Uninitialize() around prepare()
Seems to be required for exclusive mode and also for all
initialization on Windows 7

https://bugzilla.gnome.org/show_bug.cgi?id=795274
2018-04-16 19:35:07 +05:30
Nirbheek Chauhan
41a4a8fe0d wasapi: Don't derive device period from latency time
This seems to cause glitches on devices with low CPU availability,
such as virtual machines. Maybe even actual machines under high load.

https://bugzilla.gnome.org/show_bug.cgi?id=794497
2018-04-06 23:11:11 +05:30
Nirbheek Chauhan
affb0182c6 wasapisrc: Implement loopback recording
Now, when you set loopback=true on wasapisrc, the `device` property
should refer to a sink (render) device for loopback recording.

If the `device` property is not set, the default sink device is used.
2018-04-04 01:12:23 +05:30
Tim-Philipp Müller
1da3cd56a0 wasapi: try to satisfy both mingw and msvc
Fix-up for previous commit, hopefully.
2018-03-18 14:13:52 +00:00
Tim-Philipp Müller
ca4cbaef24 wasapi: fix indentation 2018-03-17 23:52:31 +00:00
Tim-Philipp Müller
ec5c3cb714 wasapi: fix unresolved symbol linker error with vs2017 on win10
ERROR: unresolved external symbol PKEY_AudioEngine_DeviceFormat

Apparently the order of the header includes matters, and initguid.h
must be included first. Let's hope this doesn't break anything on
the other toolchains.

https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/ceff4e2d-8f63-4ab6-b09b-fdac65d62a80/pkeyaudioenginedeviceformat-link-error?forum=windowspro-audiodevelopment
2018-03-17 23:48:13 +00:00
Nirbheek Chauhan
16b9e1e444 wasapi: Minor fixes for debug logging 2018-03-10 18:54:59 +05:30
Nirbheek Chauhan
f7d0ce2477 wasapi: Set realtime thread priority at runtime
Use LoadLibrary() to set the thread characteristics at runtime so it
works automagically regardless of where or how the plugin was built.
2018-02-26 16:23:11 +05:30
Nirbheek Chauhan
0cb11c15ed wasapi: Use IAudioClient3 interface when available
This allows us to request ultra-low-latency device periods even in
shared mode. However, this requires good drivers and Windows 10, so
we only enable this when we detect that we are running on Windows 10
at runtime.

You can forcibly disable this feature on Windows 10 by setting
GST_WASAPI_DISABLE_AUDIOCLIENT3=1 in the environment.
2018-02-26 16:23:11 +05:30
Nirbheek Chauhan
16af66ee95 wasapi: __uuidof is simply not available in C
Fix comment, and don't try to use it at all.
2018-02-26 16:23:11 +05:30
Nirbheek Chauhan
28874e15ff wasapi: Set a default category for util functions
Without this, they all go to the default category where they can be
missed
2018-02-26 16:23:11 +05:30
Nirbheek Chauhan
14b2d6b27a wasapi: Use a macro for HRESULT failure paths
Saves a lot of boilerplate across all files.
2018-02-26 16:23:11 +05:30
Nirbheek Chauhan
4dbca8df09 wasapi: Try to use latency-time and buffer-time
So far, we have been completely discarding the values of latency-time
and buffer-time and trying to always open the device in the lowest
latency mode possible. However, sometimes this is a bad idea:

1. When we want to save power/CPU and don't want low latency
2. When the lowest latency setting causes glitches
3. Other audio-driver bugs

Now we will try to follow the user-set values of latency-time and
buffer-time in shared mode, and only latency-time in exclusive mode (we
have no control over the hardware buffer size, and there is no use in
setting GstAudioRingBuffer size to something larger).

The elements will still try to open the devices in the lowest latency
mode possible if you set the "low-latency" property to "true".

https://bugzilla.gnome.org/show_bug.cgi?id=793289
2018-02-08 14:29:58 +05:30
Nirbheek Chauhan
624de04fdb wasapi: Cover more HRESULT error messages
This requires using allocated strings, but it's the best option. For
instance, a call could fail because CoInitialize() wasn't called, or
because some other thing in the stack failed.

https://bugzilla.gnome.org/show_bug.cgi?id=793289
2018-02-08 14:29:58 +05:30
Nirbheek Chauhan
6ecbb7556a wasapi: Allow opening devices in exclusive mode
This provides much lower latency compared to opening in shared mode,
but it also means that the device cannot be opened by any other
application. The advantage is that the achievable latency is much
lower.

In shared mode, WASAPI's engine period is 10ms, and so that is the
lowest latency achievable.

In exclusive mode, the limit is the device period itself, which in my
testing with USB DACs, on-board PCI sound-cards, and HDMI cards is
between 2ms and 3.33ms.

We set our audioringbuffer limits to match the device, so the
achievable sink latency is 6-9ms. Further improvements can be made if
needed.

https://bugzilla.gnome.org/show_bug.cgi?id=793289
2018-02-08 12:04:20 +05:30
Nirbheek Chauhan
3f1e039007 wasapi: Fix indentation issues missed by the commit hook
These were missed because the relevant commits were made on Windows
where `indent` wasn't installed.
2018-02-08 11:46:01 +05:30
Nirbheek Chauhan
ec6a10ed06 wasapi: Implement a device provider for probing
Currently only does probing and does not handle messages from
endpoints/devices. In the future we want to do proper monitoring which
is well-supported in WASAPI.

https://bugzilla.gnome.org/show_bug.cgi?id=792897
2018-01-31 14:58:21 +05:30
Nirbheek Chauhan
d6d31064b4 wasapi: Implement support for >2 channels
We need to parse the WAVEFORMATEXTENSIBLE structure, figure out what
positions the channels have (if they are positional), and reorder them
as necessary.

https://bugzilla.gnome.org/show_bug.cgi?id=792897
2018-01-31 14:58:21 +05:30
Nirbheek Chauhan
c8c32a7200 wasapi: Fix some leaks, bugs, and compiler warnings
Also improve logging.
2018-01-25 17:57:23 +05:30
Nirbheek Chauhan
1450851095 wasapi: Rewrite most of the code to make it work
Both the source and the sink elements were broken in a number of ways:

* prepare() was assuming that the format was always S16LE 2ch 44.1KHz.
  We now probe the preferred format with GetMixFormat().
* Device initialization was done with the wrong buffer size
  (buffer_time is in microseconds, not nanoseconds).
* sink_write() and src_read() were just plain wrong and would never
  write or read anything useful.
* Some functions in prepare() were always returning FALSE which meant
  trying to use the elements would *always* fail.
* get_caps() and delay() were not implemented at all.

TODO: support for >2 channels
TODO: pro-audio low-latency
TODO: SPDIF and other encoded passthroughs

Three new properties are now implemented: role, mute, and device.

* 'role' designates the stream role of the initialized device, see:
   https://msdn.microsoft.com/en-us/library/windows/desktop/dd370842(v=vs.85).aspx
* 'device' is a system-wide GUIDesque string for a specific device.
* 'mute' is a sink property and simply mutes it.

On my Windows 8.1 system, the lowest latency that works is:

  wasapisrc buffer-time=20000
  wasapisink buffer-time=10000

aka, 20ms and 10ms respectively. These values are close to the lowest
possible with the IAudioClient interface. Further improvements require
porting to IAudioClient2 or IAudioClient3.

https://docs.microsoft.com/en-us/windows-hardware/drivers/audio/low-latency-audio
2018-01-22 14:18:53 +05:30
Sebastian Dröge
363aa90a10 wasapisrc: Port to GstAudioSrc 2013-04-23 18:57:04 +02:00
Sebastian Dröge
1445438a8b wasapi: Port wasapisink to GstAudioSink 2013-04-23 18:57:04 +02:00
Sebastian Dröge
e7a69bb8de wasapi: Initial port to 1.0
This should really use GstAudioSink and GstAudioSrc.
2013-03-26 15:43:51 +01:00
Sebastian Dröge
d5d37fafa7 wasapi: Include config.h before anything else 2013-03-26 15:01:08 +01:00
Tim-Philipp Müller
9e1b75fda3 Fix FSF address
https://bugzilla.gnome.org/show_bug.cgi?id=687520
2012-11-04 00:09:59 +00:00
Ole André Vadla Ravnås
69fad589ac sys/: New plugin for audio capture and playback using Windows Audio Session
Original commit message from CVS:
* sys/Makefile.am:
* sys/wasapi/Makefile.am:
* sys/wasapi/gstwasapi.c:
* sys/wasapi/gstwasapisink.c:
* sys/wasapi/gstwasapisink.h:
* sys/wasapi/gstwasapisrc.c:
* sys/wasapi/gstwasapisrc.h:
* sys/wasapi/gstwasapiutil.c:
* sys/wasapi/gstwasapiutil.h:
New plugin for audio capture and playback using Windows Audio Session
API (WASAPI) available with Vista and newer (#520901).
Comes with hardcoded caps and obviously needs lots of love. Haven't
had time to work on this code since it was written, was initially just
a quick experiment to play around with this new API.
2008-09-30 11:19:10 +00:00