Граф коммитов

1565 Коммитов

Автор SHA1 Сообщение Дата
Alex Chronopoulos c6692b1c47 audiounit: avoid access to input buffer on playback case (#460) 2018-10-04 13:27:23 +02:00
Matthew Gregan b832dae6e4 audiounit: Make io_side an enum class. 2018-09-17 21:35:14 +12:00
Matthew Gregan 5c60bc04fc Merge branch 'jyavenard-1489052_2' 2018-09-17 18:55:24 +12:00
Matthew Gregan f48857a956 s/OUTPUT/DEV_OUTPUT/ 2018-09-17 18:53:35 +12:00
Matthew Gregan 78ae261d00 Update CMake sanitizer submodule to current master.
Fixes TSAN on macOS.
2018-09-17 18:09:50 +12:00
Jean-Yves Avenard 7f3726d4b1 Only re-initialise stream on kAudioUnitErr_CannotDoInCurrentContext when an output is present. Otherwise just feed silence. 2018-09-14 15:10:41 +02:00
Jean-Yves Avenard 9e9f4d059e Remove unnecessary variable.
input_linear_buffer size is always directly matching how many frames are available for input
2018-09-14 15:10:41 +02:00
Jean-Yves Avenard b5070a7d86 Don't propagate kAudioUnitErr_CannotDoInCurrentContext error, feed silence instead. 2018-09-14 15:10:41 +02:00
Jean-Yves Avenard cc6c82829e Don't run reinit task when one is already pending 2018-09-14 15:10:39 +02:00
Jean-Yves Avenard 23795835a4 Calculate the amount of input frames missing over the entire capture session
This avoid accumulating rounding errors each time some silence is inserted
2018-09-14 15:10:01 +02:00
Jean-Yves Avenard c381d1b417 Pad with silence according to the input device sampling rate.
Contrary to earlier assumed, even in duplex audio the sampling rate of the input device doesn't always match the rate of the output device.
2018-09-14 15:10:01 +02:00
Jean-Yves Avenard f4968d996d Cancel reinit task when a audiounit_stream_destroy call is pending
It is possible that the callback caused a reinit task to be queued while at the same time audiounit_stream_destroy got called.

We need to abort early as otherwise both stm->input_unit and stm->output_unit would have been cleared.
2018-09-14 15:07:50 +02:00
Jean-Yves Avenard 78359c0e12 Attempt to reuse previous input device before falling back to the default one. 2018-09-14 12:40:57 +02:00
Jean-Yves Avenard df711063da Do not attempt to destroy an aggregate device we failed to create 2018-09-12 19:29:00 +02:00
Jean-Yves Avenard 1b4547f695 Properly reset the number of frames present in the input buffer after re-creating it
Otherwise we would be out of sync triggering the assert. This resolves the issue mentioned in https://bugzilla.mozilla.org/show_bug.cgi?id=1489052#c10
2018-09-12 16:46:01 +02:00
Jean-Yves Avenard c3b504510f Properly adjust the number of frames left to be processed by the resampler.
After calling the resampler, we would reduce the number of frames in the input buffer correctly by the number of frames used, but would always fully clear the input buffer after.
Resulting with a input_buffer and its frame counters to be potentially out of sync
2018-09-12 16:44:09 +02:00
Jean-Yves Avenard ad0d1c1c73 Remove unecessary locks.
In duplex mode, audiounit_input_callback and audiounit_output_callback are always called on the same thread. input_linear_buffer is only ever accessed serially.

Additionally, the use of atomic variables was incorrect as they should only ever be modified when input_linear_buffer was modified.

So we remove the lock and the related atomics.
remove input_buffer_frames member as its value is always latency_frames
2018-09-12 16:40:15 +02:00
Jean-Yves Avenard 0ba48eca34 Clear listeners once removed 2018-09-12 16:40:15 +02:00
Jean-Yves Avenard 44298ecec5 Add .gitignore 2018-09-12 16:40:15 +02:00
Paul Adenot d6a294cde2 Reinit the stream if AudioUnitRender returns kAudioUnitErr_CannotDoInCurrentContext.
This can occur using BT headset which change from A2DP profile to HFP (Hands-free Profle) or HSP (Headset Profile) when opening the microphone.
2018-09-12 09:01:12 +12:00
Jean-Yves Avenard 710df0b676 Ensure input is properly padded with enough silence.
Under some circumstances, like the input couldn't be rendered we could have fed less data than the resampler expected.
2018-09-12 09:01:12 +12:00
orbea 12b78c0edf cmake: Support GNUInstallDirs. 2018-07-23 15:45:18 +12:00
Chun-Min Chang 39b87032ee audiounit: Simplify audiounit_add/remove_listener() by introducing property_listener (#451)
* Use DEVICES_PROPERTY_ADDRESS in audiounit_get_devices_of_type

* Use exactly same AudioObjectPropertyAddress in audiounit_add_device_listener() and audiounit_remove_device_listener()

We have duplicated AudioObjectPropertyAddress variables in audiounit_add_device_listener() and audiounit_remove_device_listener(). This two functions use same values to add and remove listeners on same system events. Therefore, we should use the exactly same value for both instead of creating same values in two functions, in case the local variables are changed carelessly.

* Use global AudioObjectPropertyAddress settings for both audiounit_add_listener() and audiounit_remove_listener()

* audiounit_get_default_device_datasource

* Simplify audiounit_add/remove_listener() by introducing property_listener

audiounit_add_listener() and audiounit_remove_listener() should use exactly same variable to register and unregister event listener. Originally, these two functions are set by different local variables with same values: audiounit_add_listener(X, Y, Z, ...) and audiounit_remove_listener(X', Y', Z', ...), where X = X', Y = Y',...etc. There are too many function parameters so it's not easy to check if we have same parameters for audiounit_add_listener() and audiounit_remove_listener().

property_listener is introduced to simplify the parameter issues by using audiounit_add/remove_listener(property_listener L). A property_listener object L is created to register a event listener, and then be used to unregister the listener later. It'll be safer if audiounit_add_listener() and audiounit_remove_listener() use the exactly same object as their parameters. In addition, The readability is better since there is a "listener" be added/removed when we call audiounit_add/remove_listener().

* Use DEFAULT_INPUT/OUTPUT_DEVICE_PROPERTY_ADDRESS in audiounit_get_default_device_id()

* Make property_listener pointer be const

* Remove stm->XXX_listners if it's not nullptr no matter the input/output_unit exists or not.

stm->XXX_listener will be set based on existence of the input/output_unit. Therefore, if it's not nullptr, the input/output_unit must exist. Removing listeners or not only depends on existeneces of the listeners themselves.
2018-07-20 11:55:15 +12:00
Chun-Min Chang 4b7442ee48 audiounit: Reduce duplicate code in audiounit_stream_get_current_device (#453)
* Add a test for cubeb_stream_get_current_device() and cubeb_stream_device_destroy()

* Reduce duplicates in audiounit_stream_get_current_device()

The audiounit_stream_get_current_device() will set the default device's name for input and output by the following steps:
1. Get default device's data, whose type is uint32
2. Convert the uint32 data into a string
3. Set the string into cubeb_device's name

Hence we can split it into functions to do the above steps:
i. audiounit_get_default_device_data(...)
  Do the step 1
ii. allocate_and_convert_uint32_into_string(...)
  Do the step 2 and 3. It will allocate memory for a string and put the converted string right there. (If we don't allocate and then set the values into the memory at the same time, we need to find a way to check the memory's boundary.)

They are called by a function named audiounit_get_default_device_name(...), with cubeb_device_type parameter to set the device name of input or output. And audiounit_get_default_device_name(...) will be used in audiounit_stream_get_current_device().

* Replace allocate_and_convert_uint32_into_string(...) by convert_uint32_into_string(...)

1. Rename allocate_and_convert_uint32_into_string(...) to convert_uint32_into_string(...)
2. Return a unique_ptr<char[]> from convert_uint32_into_string(...) pointing to an allocated memory

* Hard-coding the convertion from uint32 into string

This change is to make sure the conversion only ever needs to handle 4 bytes.

* Add more information to log when calling audiounit_stream_get_current_device(...)

We add a log with error message when we cannot get datasource data from the devices. However, we don't return an error code in this case since it's quite common when we try getting that data from USB devices. We will convert the datasource data into a string. If there is no data, the string is empty. Instead of logging when we cannot get the datasource data, it's better to log that the converted name is empty. It'll give more meaning (Users are more likely confused about what the empty datasource means.).

* Rename audiounit_get_default_device_data() to audiounit_get_default_device_datasource()

We should use an explicit name for this function since the same device will return different datasources. For example, the default input device on macbook pro will return "imic" if it uses the default internal microphone or "emic" when it uses an external microphone plugged in audio jack.

TODO: it's better to rename audiounit_stream_get_current_device to audiounit_stream_get_current_device_source. The reason is same as above.
2018-07-19 09:36:53 +12:00
Paul Adenot 6c47043042
Remove c-style cast in cubeb_resampler.cpp (#454) 2018-07-17 15:23:38 +02:00
Jean-Yves Avenard 8de5aaec0a Always upmix mono to the first two channels if enough output channels are available #2
Properly fix #448. Change provided by dbd6192473 was incorrect
2018-07-14 16:36:49 +12:00
Jean-Yves Avenard dbd6192473 Always upmix mono to the first two channels if enough output channels are available
This allows to output what people typically expect when playing mono audio: sound coming from both left and right channels.

To force this conversion for happening on mac, we tag that layout are unknown as soon as a channel type is unknown
2018-07-10 18:28:44 +12:00
Jean-Yves Avenard 59f5cb4ba0 Correctly retrieve the output layout on macOS < 10.12.
The method kAudioUnitProperty_AudioChannelLayout used to retrieve the channel layout wasn't introduced until 10.12. So we use kAudioDevicePropertyPreferredChannelLayout instead should it fails.

Fixes #448
2018-07-10 18:28:44 +12:00
Andreas Pehrson 2968cba647 wasapi: Reduce timeout threshold (#447) 2018-06-26 10:58:56 +02:00
Alex Chronopoulos 27be938448 audiounit: new method on failed stream init to avoid deadlock (BMO 1470113). (#445)
* audiounit: new method on failed stream init to avoid deadlock (BMO 1470113).
* use an internal_destroy method to avoid duplication
2018-06-26 09:37:59 +12:00
Jacek Caban bf2c28189f cubeb_winmm.c: Don't define __MSVCRT_VERSION__.
This define was added as part of commit d2c45250 and is mingw-specific (only mingw uses __MSVCRT_VERSION__). I don't know why it was added, it shouldn't be needed.

Recently mingw-w64 added support for UCRT-based toolchains. In this case __MSVCRT_VERSION__ is set to 0x1400 and should not really be changed. UCRT-based builds support a lot of stdio.h function by inline wrappers. Those can't be disabled just for one file as they are not exported by ucrtbase.dll.

I found the problem while working on porting Firefox to clang+mingw-w64 toolchain that uses UCRT by default.
2018-06-26 09:05:23 +12:00
Alexandre Ratchov 0677b3027b Fix volume handling in sndio backend
Apply volume in software as do other backends. This is necessary
because sndio volume may be controlled externally and there's no
volume getter in libcubeb to notify the caller about volume
changes.
2018-06-12 08:48:55 -07:00
Alex Chronopoulos abf6ae235b osx: always access active stream count under context lock, BMO 1462210. (#442) 2018-06-01 13:02:45 +12:00
Alex Chronopoulos 44341a1e06 audiounit: use separate variables for each use of CFStringRef. 2018-05-01 22:09:43 +12:00
achronop 7646920ce3 wasapi: if no playback check for capture device in init 2018-05-01 22:06:20 +12:00
Matthew Gregan 7f4f3b6eae wasapi: Make CO_E_NOTINITIALIZED a soft error.
See https://bugzilla.mozilla.org/show_bug.cgi?id=1449555#c5 for background.
2018-04-13 23:32:06 +12:00
Dan Glastonbury c4a4f55919 audiounit: Fix up channel layout iteration logic. 2018-03-29 23:58:05 +13:00
Matthew Gregan f34f392de5 audiounit: Apply latency correction to stream_get_position. (#434)
The presentation latency of a stream is roughly kAudioDevicePropertyLatency +
kAudioStreamPropertyLatency + kAudioUnitProperty_Latency.  Calculate this at
device setup time and apply the correction when calculating the current stream
position for stream_get_position.
2018-03-27 17:45:10 -04:00
Matthew Gregan 57b4d6b454 Initialize cubeb_stream_params.prefs field in more tests to avoid random failures. 2018-03-27 17:48:59 +13:00
Jean-Yves Avenard 7401fc25a9 Remove output channel count limitation. (#433)
Fixes #432
2018-03-26 16:54:01 +02:00
Jean-Yves Avenard 7712aaabfa Don't use _popcnt intrinsec on windows. (#431)
Not all CPUs support it.
2018-03-25 11:30:38 +02:00
Dan Glastonbury 77cb1a9a37 Eliminate warning from MixerContext constructor. 2018-03-23 14:38:34 +10:00
Jan Malakhovski 3c8205901f pulse: check pa_context_connect return value 2018-03-23 15:41:58 +13:00
Dan Glastonbury 2b368ccfd4 Change cubeb_mixer_mix input to be const void * 2018-03-23 11:35:57 +13:00
Matthew Gregan 13d9e2874c wasapi: Remove COM initialization and require caller to complete.
This addresses the thread local COM initialization lifetime problem
discussed in issue #416 by moving the responsibility for COM
initialization from within cubeb to the caller.
2018-03-21 09:29:30 +13:00
Dan Glastonbury 200bcbd920 Remove stray `1 <<` from CUBEB_LAYOUT_3F2_BACK. 2018-03-20 16:49:55 +10:00
Dan Glastonbury f00570da69 Fix heap overflow found by address sanitizer. 2018-03-20 13:56:40 +13:00
Jean-Yves Avenard 789eaaa3b0 Multi-channels support for windows/mac/linux (#426)
* Add QUAD and QUAD_LFE layouts.

* Remove dual mono layout.

It makes no sense to have a case for those as the data structure
used (a bitmask) do not allow to represent this channel layout (a
channel can only be present once). As such it was a non-functional
layout

* Fix up cubeb_pulse compilation using C++ keyword.

* Remove the concept of preferred layout.

Channel layout is derived by the content being played. The concept of
preferred layout is meaningless. Either we have a layout defined, or
we don't. There's no in-between.

So we remove it.

* Remove CHANNEL_MONO concept.

* Add cubeb_sample_size convenience method.

* Rework cubeb_mixer.

This completely replace the existing remixer which had serious limitations:
1- Had no memory bound checks
2- Could only downmix 5.1 and 7.1 to stereo.

This mixer allows to convert from any sane layout to any other and work directly on interleaved samples.

This cubeb_mixer doesn't have an API compatible with the previous one.

This commit is non-fonctional, and was split for ease of review.

* Fix remixing on mac, windows and pulse backend.

* Make cubeb_mixer creation infallible.

Rather than ignore nonsensical layouts, we attempt to play it according to the stream channels count instead. The audio data will be played as-is, dropping the extra channels or inserting silence where needed.

* User proper sample size when calculating offsets.

Should the user data be of a different type to what the AudioUnit output is set to, we would have written outside the end of our allocated buffer.

* Fix input mixing and clarify frames vs samples terminology

* If a layout is unknown or invalid, always treat it as plain stereo or mono.
2018-03-19 14:57:07 +01:00
Bryce Van Dyk c88a484e1a Relax some of the checks in the loopback test to avoid false positives.
- For the silent loopback test we check that we don't get any sound above an
epsilon. The value of this epsilon has been increased to accommodate a wider
range of systems.
- The delay on all tests has been increased to allow for more time to capture
looped samples. The original 150ms delay was sufficient on the machine I tested
with, however, I've seen the tests fail due to not having enough looped input.
2018-03-13 08:59:20 +13:00
Paul Adenot 34354eb362 When having on or two channel, force mono or stereo.
Some devices (namely, Bose QC35, mark 1 and 2), expose a single channel mapped
to the right for some reason, and this confuses our channel mapping code.
2018-03-01 14:42:49 +01:00