Commit graph

25 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
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
d56aec8b0c wasapi: Fix infinite loop when the device disappears
When the audio device goes away during playback or capture, we were
going into an infinite loop of AUDCLNT_E_DEVICE_INVALIDATED. Return -1
and post an error message so the ringbuffer thread exits with an error.
2019-01-15 03:29:58 +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
2d98a5c1d7 wasapi: use FAILED to detect errors
S_FALSE is a valid return value which does not indicate an error.
For example IAudioClient_Stop() returns S_FALSE when it is already stopped.
Use the FAILED macro instead which just checks if an error occured or not.

This fixes spurious warnings when using the wasapisink element.

https://bugzilla.gnome.org/show_bug.cgi?id=796280
2018-05-23 13:24:00 +05:30
Nirbheek Chauhan
fc989ce544 wasapi: Squelch warning about %x and HRESULT
HRESULT is always a 32-bit value, as is guint.
2018-04-04 18:36:38 +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
Nirbheek Chauhan
a08d333e56 wasapi: Print the hresult hex value on error
This helps figure out precisely what error enum value was returned,
which can be necessary when the description is too generic
2018-03-27 12:02:21 +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
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
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
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
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
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
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