mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-12-25 03:30:06 +01:00
Compare commits
No commits in common. "master" and "v14.99.2" have entirely different histories.
245 changed files with 22479 additions and 48387 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -37,4 +37,3 @@ stamp-*
|
|||
.dirstamp
|
||||
*.orig
|
||||
*.rej
|
||||
subprojects/*/
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# container and push it to the project's container registry on fd.o GitLab.
|
||||
# This step is only run when the tag for the container changes, else it is
|
||||
# effectively a no-op. All of this infrastructure is inherited from the
|
||||
# freedesktop/ci-templates repository which is the recommended way to set up CI
|
||||
# wayland/ci-templates repository which is the recommended way to set up CI
|
||||
# infrastructure on fd.o GitLab.
|
||||
#
|
||||
# Once the container stage is done, we move on to the 'build' stage where we
|
||||
|
|
@ -10,15 +10,6 @@
|
|||
# there doesn't seem to be significant value to splitting the stages at the
|
||||
# moment.
|
||||
|
||||
# Create merge request pipelines for open merge requests, branch pipelines
|
||||
# otherwise. This allows MRs for new users to run CI.
|
||||
workflow:
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
|
||||
when: never
|
||||
- if: $CI_COMMIT_BRANCH
|
||||
|
||||
stages:
|
||||
- container
|
||||
- build
|
||||
|
|
@ -28,21 +19,22 @@ variables:
|
|||
# CI runs, for example when adding new packages to FDO_DISTRIBUTION_PACKAGES.
|
||||
# The tag is an arbitrary string that identifies the exact container
|
||||
# contents.
|
||||
FDO_DISTRIBUTION_TAG: '2023-08-13-00'
|
||||
FDO_DISTRIBUTION_VERSION: '20.04'
|
||||
FDO_DISTRIBUTION_TAG: '2021-03-01-02'
|
||||
FDO_DISTRIBUTION_VERSION: '18.04'
|
||||
FDO_UPSTREAM_REPO: 'pulseaudio/pulseaudio'
|
||||
UBUNTU_IMAGE: "$CI_REGISTRY_IMAGE/ubuntu/$FDO_DISTRIBUTION_VERSION:$FDO_DISTRIBUTION_TAG"
|
||||
|
||||
include:
|
||||
# We pull templates from master to avoid the overhead of periodically
|
||||
# scanning for changes upstream. This does means builds might occasionally
|
||||
# break due to upstream changing things, so if you see unexpected build
|
||||
# failures, this might be one cause.
|
||||
- project: 'freedesktop/ci-templates'
|
||||
- project: 'wayland/ci-templates'
|
||||
ref: 'master'
|
||||
file: '/templates/ubuntu.yml'
|
||||
|
||||
build-container:
|
||||
extends: .fdo.container-build@ubuntu
|
||||
extends: .fdo.container-ifnot-exists@ubuntu
|
||||
stage: container
|
||||
variables:
|
||||
GIT_STRATEGY: none # no need to pull the whole tree for rebuilding the image
|
||||
|
|
@ -56,7 +48,6 @@ build-container:
|
|||
check
|
||||
curl
|
||||
dbus-x11
|
||||
doxygen
|
||||
g++
|
||||
gcc
|
||||
gettext
|
||||
|
|
@ -97,19 +88,17 @@ build-container:
|
|||
wget
|
||||
|
||||
build-meson:
|
||||
extends: .fdo.distribution-image@ubuntu
|
||||
stage: build
|
||||
image: $UBUNTU_IMAGE
|
||||
script:
|
||||
# Install meson (higher than our min version to support our wrap file)
|
||||
- wget -q https://github.com/mesonbuild/meson/releases/download/0.63.2/meson-0.63.2.tar.gz
|
||||
- tar -xf meson-0.63.2.tar.gz
|
||||
- cd meson-0.63.2
|
||||
# Install meson
|
||||
- wget -q https://github.com/mesonbuild/meson/releases/download/0.50.0/meson-0.50.0.tar.gz
|
||||
- tar -xf meson-0.50.0.tar.gz
|
||||
- cd meson-0.50.0
|
||||
- python3 setup.py install
|
||||
- cd ..
|
||||
# needed to generate a version
|
||||
- git fetch https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git --tags
|
||||
# Do the actual build
|
||||
- meson build -Dwebrtc-aec=enabled
|
||||
- meson build
|
||||
- cd build
|
||||
- ninja
|
||||
- ulimit -c 0 # don't dump core files on tests that are supposed to assert
|
||||
|
|
|
|||
|
|
@ -28,10 +28,10 @@ Please take a look at the [coding style
|
|||
documentation](https://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/Developer/CodingStyle/)
|
||||
on our wiki.
|
||||
|
||||
## Commit messages
|
||||
## Commit messagse
|
||||
|
||||
We follow the standard git commit message format of a summary on the first line
|
||||
(<=50 characters for preference, <=72 characters otherwise), followed by a new
|
||||
(<=50 characterss for preference, <=72 characters otherwise), followed by a new
|
||||
line, followed by a detailed commit message. An additional line at the end may
|
||||
link to an issue being fixed by this MR.
|
||||
|
||||
|
|
|
|||
300
NEWS
300
NEWS
|
|
@ -1,303 +1,3 @@
|
|||
PulseAudio 17.0
|
||||
|
||||
Changes at a glance:
|
||||
* Notes for end users
|
||||
* Updates to ALSA UCM-based setups
|
||||
* Battery level indication to Bluetooth devices
|
||||
* Support for the Bluetooth FastStream codec
|
||||
* webrtc-audio-processing dependency updated
|
||||
* Trigger role groups added to module-role-cork
|
||||
* XDG base directory spec for profile-set loading
|
||||
* Notes for application developers
|
||||
* PA_RATE_MAX increased
|
||||
* Notes for packagers
|
||||
* webrtc-audio-processing dependency updated
|
||||
|
||||
Contributors
|
||||
|
||||
Alistair Leslie-Hughes
|
||||
Alper Nebi Yasak
|
||||
Arun Raghavan
|
||||
Asier Sarasua Garmendia
|
||||
Ataberk Özen
|
||||
Balázs Meskó
|
||||
Biswapriyo Nath
|
||||
Dylan Van Assche
|
||||
Eero Nurkkala
|
||||
Ettore Atalan
|
||||
Fabrice Fontaine
|
||||
Fran Diéguez
|
||||
Georg Chini
|
||||
Gioele Barabucci
|
||||
Gogo Gogsi
|
||||
Hector Martin
|
||||
Hugo Carvalho
|
||||
Hui Wang
|
||||
Igor V. Kovalenko
|
||||
Jaechul Lee
|
||||
Jan Kuparinen
|
||||
Jan Palus
|
||||
Jaroslav Kysela
|
||||
Jiri Grönroos
|
||||
Joachim Philipp
|
||||
Jordi Mas
|
||||
Marijn Suijten
|
||||
Mart Raudsepp
|
||||
Nicolas Cavallari
|
||||
Peter Meerwald-Stadler
|
||||
Philip Goto
|
||||
Rosen Penev
|
||||
Rudi Heitbaum
|
||||
Sabri Ünal
|
||||
Sean Greenslade
|
||||
Seong-ho Cho
|
||||
Shunsuke Shimizu
|
||||
SimonP
|
||||
Takashi Sakamoto
|
||||
Tanu Kaskinen
|
||||
Temuri Doghonadze
|
||||
Toni Estevez
|
||||
Weijia Wang
|
||||
Wim Taymans
|
||||
Yureka
|
||||
acheronfail
|
||||
flyingOwl
|
||||
grimst
|
||||
hashitaku
|
||||
mooo
|
||||
peijiankang
|
||||
redfast00
|
||||
wael
|
||||
김인수
|
||||
|
||||
|
||||
PulseAudio 16.1
|
||||
|
||||
A bug fix release.
|
||||
|
||||
* Fix parsing of percentage volumes with decimal points in pactl
|
||||
* Fix crash with the "pacmd play-file" command when reads from the disk aren't frame-aligned
|
||||
* Fix module-rtp-recv sometimes thinking it's receiving an Opus stream when it's not
|
||||
* Fix frequent crashing in module-combine-sink, regression in 16.0
|
||||
* Fix crashing on 32-bit architectures when using the GStreamer codecs for LDAC and AptX
|
||||
|
||||
Contributors
|
||||
|
||||
Georg Chini
|
||||
Igor V. Kovalenko
|
||||
Jaechul Lee
|
||||
Jan Palus
|
||||
Sean Greenslade
|
||||
|
||||
|
||||
PulseAudio 16.0
|
||||
|
||||
Changes at a glance:
|
||||
* Notes for end users
|
||||
* Opus support in RTP modules
|
||||
* Improved hardware support
|
||||
* EPOS/Sennheiser GSP 670 USB/wireless headset
|
||||
* SteelSeries GameDAC
|
||||
* Behringer UMC22 generalized to Texas Instruments PCM2902 to support more products
|
||||
* NI Komplete Audio 6 MK2 profiles
|
||||
* Tunnel latency is now configurable
|
||||
* Bluetooth device battery level reporting added
|
||||
* Tunnel and combine-sunk latency fixes
|
||||
* patcl can show information in JSON format
|
||||
* Channel remixing can be disabled for module-combine-sink
|
||||
* A lot of fixes to ALSA, bluetooth, and other components.
|
||||
* Notes for application developers
|
||||
* Stream latency reports now include resampler delay
|
||||
* Module installation location changed, remember to upgrade paprefs to the latest version!
|
||||
* Notes for packagers
|
||||
* Opus support in the RTP modules requires enabling GStreamer
|
||||
* Bluetooth battery level reporting via BlueZ requires enabling experimentals features in BlueZ
|
||||
* New time smoother implementation
|
||||
* Change Meson option 'daemon-only' to 'client'
|
||||
* glib and fftw are now common dependencies, not only for the client.
|
||||
* Enable GStreamer-based RTP by default when available
|
||||
|
||||
Detailed change log:
|
||||
|
||||
https://www.freedesktop.org/wiki/Software/PulseAudio/Notes/16.0/
|
||||
|
||||
Contributors
|
||||
|
||||
Alexey Rubtsov
|
||||
Anders Jonsson
|
||||
Andika Triwidada
|
||||
Arun Raghavan
|
||||
Biswapriyo Nath
|
||||
BtbN
|
||||
Chengyi Zhao
|
||||
Chupligin Sergey
|
||||
Craig Howard
|
||||
Daniel Dantur
|
||||
Daniel Hernandez
|
||||
Diederik de Haas
|
||||
Dylan Van Assche
|
||||
Emilio Herrera
|
||||
Ettore Atalan
|
||||
Fran Diéguez
|
||||
Georg Chini
|
||||
Gogo Gogsi
|
||||
Göran Uddeborg
|
||||
Hela Basa
|
||||
Hui Wang
|
||||
Igor V. Kovalenko
|
||||
Jan Kuparinen
|
||||
Jaroslav Kysela
|
||||
Josef Haider
|
||||
João Paulo Rechi Vita
|
||||
Juho Hämäläinen
|
||||
Karl Ove Hufthammer
|
||||
Laurent Bigonville
|
||||
Luna Jernberg
|
||||
Lv Genggeng
|
||||
Marijn Suijten
|
||||
Mart Raudsepp
|
||||
Mathy Vanvoorden
|
||||
Olivier Gayot
|
||||
Ovari
|
||||
Oğuz Ersen
|
||||
Piotr Drąg
|
||||
Rafael Fontenelle
|
||||
Rico Tzschichholz
|
||||
Sanchayan Maity
|
||||
Sebastian Reichel
|
||||
Sergey A
|
||||
Sibo Dong
|
||||
Sungjoon Moon
|
||||
Takashi Sakamoto
|
||||
Takuro Onoue
|
||||
Tanu Kaskinen
|
||||
Temuri Doghonadze
|
||||
Will Thompson
|
||||
Yuri Chornoivan
|
||||
acheronfail
|
||||
baek inchan
|
||||
guest271314
|
||||
liaohanqin
|
||||
simmon
|
||||
simple
|
||||
tensorknower69
|
||||
김인수
|
||||
|
||||
|
||||
PulseAudio 15.0
|
||||
|
||||
Changes at a glance:
|
||||
|
||||
* Notes for end users
|
||||
* Support for LDAC and AptX bluetooth codecs, plus "SBC XQ" (SBC with higher-quality parameters)
|
||||
* Support for HFP bluetooth profiles
|
||||
* Support for Bluetooth A2DP AVRCP Absolute Volume
|
||||
* ALSA path configuration files can now be placed in user home directory
|
||||
* module-virtual-surround-sink rewritten
|
||||
* More options for module-jackdbus-detect
|
||||
* Improved hardware support
|
||||
* SteelSeries Arctis 9
|
||||
* HP Thunderbolt Dock 120W G2
|
||||
* Behringer U-Phoria UMC22
|
||||
* OnePlus Type-C Bullets
|
||||
* Sennheiser GSX 1000/1200 PRO
|
||||
* New udev variable: PULSE_MODARGS
|
||||
* max_latency_msec argument added to module-null-source
|
||||
* module-filter-apply can take filter parameters from device properties
|
||||
* module-match can now be loaded multiple times
|
||||
* Improvements to FreeBSD support
|
||||
* Windows support added to Meson
|
||||
* Additional commands for pactl
|
||||
* Card profiles can be set to sticky
|
||||
* Notes for application developers
|
||||
* New API for sending messages from clients to PulseAudio objects
|
||||
* New mechanism for applications to disable shared memory on their connection to PulseAudio
|
||||
* Notes for packagers
|
||||
* Autotools build system have been dropped
|
||||
* The startup script can now read additional configuration from the /etc/pulse/default.pa.d/ directory
|
||||
* Option to build client library and utilities only
|
||||
* Avoid loading X11 modules on Wayland (GNOME-only for now)
|
||||
* OSS support is now configurable in Meson
|
||||
* Valgrind support is now configurable in Meson
|
||||
|
||||
Detailed change log:
|
||||
|
||||
https://www.freedesktop.org/wiki/Software/PulseAudio/Notes/15.0/
|
||||
|
||||
Contributors
|
||||
|
||||
Alexey Rubtsov
|
||||
Alper Nebi Yasak
|
||||
Anders Jonsson
|
||||
Arun Raghavan
|
||||
Ben Buchwald
|
||||
Benjamin Valentin
|
||||
Carlos Garnacho
|
||||
Carmen Bianca Bakker
|
||||
Christopher Arndt
|
||||
Christopher Snowhill
|
||||
David
|
||||
Dusan Kazik
|
||||
Edward Lee
|
||||
Emilio Herrera
|
||||
Evan Miller
|
||||
Fabian Affolter
|
||||
Faidon Liambotis
|
||||
Felipe Sateler
|
||||
Frédéric Danis
|
||||
Georg Chini
|
||||
Greg V
|
||||
Göran Uddeborg
|
||||
Hela Basa
|
||||
Henri Chain
|
||||
Hui Wang
|
||||
Igor V. Kovalenko
|
||||
Ilja van Sprundel
|
||||
Jaechul Lee
|
||||
James Bottomley
|
||||
Jan Alexander Steffens (heftig)
|
||||
Jan Kuparinen
|
||||
Jaroslav Kysela
|
||||
Jason Nader
|
||||
Johannes Wolf
|
||||
Julien Humbert
|
||||
Kai-Heng Feng
|
||||
Karl Ove Hufthammer
|
||||
Klaas van Schelven
|
||||
Laurent Bigonville
|
||||
Laurențiu Nicola
|
||||
Lyndon Brown
|
||||
Marijn Suijten
|
||||
Martin Wilck
|
||||
Mattias Jernberg
|
||||
Milo Casagrande
|
||||
Nazar Mokrynskyi
|
||||
Oğuz Ersen
|
||||
Patrick Gaskin
|
||||
Patrick McLean
|
||||
Paul Seyfert
|
||||
Pierre Ossman
|
||||
Piotr Drąg
|
||||
Pjotr Vertaalt
|
||||
Ricky Tigg
|
||||
Robin Lahtinen
|
||||
Samuel Thibault
|
||||
Sanchayan Maity
|
||||
Scott Worley
|
||||
Sebastian Krzyszkowiak
|
||||
SimonP
|
||||
Takashi Sakamoto
|
||||
Tanu Kaskinen
|
||||
Tobias Weise
|
||||
Toni Estevez
|
||||
Yaron Shahrabani
|
||||
Yuri Chornoivan
|
||||
morrishoresh
|
||||
pseyfert
|
||||
scootergrisen
|
||||
simmon
|
||||
|
||||
|
||||
PulseAudio 14.2
|
||||
|
||||
A bug fix release.
|
||||
|
|
|
|||
|
|
@ -1,8 +1,3 @@
|
|||
doxygen = find_program('doxygen', required: get_option('doxygen'))
|
||||
if not doxygen.found()
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
cdata.set('DOXYGEN_OUTPUT_DIRECTORY', meson.current_build_dir())
|
||||
|
||||
doxygen_conf = configure_file(
|
||||
|
|
@ -12,4 +7,4 @@ doxygen_conf = configure_file(
|
|||
)
|
||||
|
||||
run_target('doxygen',
|
||||
command : [doxygen, doxygen_conf])
|
||||
command : ['doxygen', doxygen_conf])
|
||||
|
|
|
|||
|
|
@ -14,24 +14,22 @@ if get_option('daemon')
|
|||
]
|
||||
endif
|
||||
|
||||
if get_option('client')
|
||||
manpages += [
|
||||
['pacat', '1', ['paplay', 'parec', 'parecord', 'pamon']],
|
||||
['pactl', '1'],
|
||||
['pulse-client.conf', '5'],
|
||||
]
|
||||
|
||||
if cdata.has('HAVE_OSS_WRAPPER')
|
||||
manpages += [
|
||||
['pacat', '1', ['paplay', 'parec', 'parecord', 'pamon']],
|
||||
['pactl', '1'],
|
||||
['pulse-client.conf', '5'],
|
||||
['padsp', '1'],
|
||||
]
|
||||
endif
|
||||
|
||||
if cdata.has('HAVE_OSS_WRAPPER')
|
||||
manpages += [
|
||||
['padsp', '1'],
|
||||
]
|
||||
endif
|
||||
|
||||
if x11_dep.found()
|
||||
manpages += [
|
||||
['pax11publish', '1'],
|
||||
]
|
||||
endif
|
||||
if x11_dep.found()
|
||||
manpages += [
|
||||
['pax11publish', '1'],
|
||||
]
|
||||
endif
|
||||
|
||||
# FIXME: Add esdcompat if HAVE_ESOUND
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
|
|||
<option>
|
||||
<p><opt>-d | --device</opt><arg>=SINKORSOURCE</arg></p>
|
||||
|
||||
<optdesc><p>Specify the symbolic name of the sink/source to play/record this stream on/from. The special names @DEFAULT_SINK@, @DEFAULT_SOURCE@ and @DEFAULT_MONITOR@ can be used to specify the default sink, source and monitor respectively.</p></optdesc>
|
||||
<optdesc><p>Specify the symbolic name of the sink/source to play/record this stream on/from.</p></optdesc>
|
||||
</option>
|
||||
|
||||
<option>
|
||||
|
|
|
|||
|
|
@ -53,12 +53,6 @@ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
|
|||
<optdesc><p>Choose the server to connect to.</p></optdesc>
|
||||
</option>
|
||||
|
||||
<option>
|
||||
<p><opt>-f | --format</opt><arg>=FORMAT</arg></p>
|
||||
|
||||
<optdesc><p>Choose output format, available options are "text" or "json".</p></optdesc>
|
||||
</option>
|
||||
|
||||
<option>
|
||||
<p><opt>-n | --client-name</opt><arg>=NAME</arg></p>
|
||||
|
||||
|
|
@ -69,7 +63,7 @@ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<section name="Commands">
|
||||
<p>
|
||||
When supplied as arguments to the commands below, the special names \@DEFAULT_SINK@, \@DEFAULT_SOURCE@ and \@DEFAULT_MONITOR@
|
||||
When supplied as arguments to the commands below, the special names \@DEFAULT_SINK@, \@DEFAULT_SOURCE@ and \@DEFAULT_MONITOR@
|
||||
can be used to specify the default sink, source and monitor respectively.
|
||||
</p>
|
||||
|
||||
|
|
@ -174,9 +168,7 @@ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<option>
|
||||
<p><opt>set-default-sink</opt> <arg>SINK</arg></p>
|
||||
<optdesc><p>Make the specified sink (identified by its symbolic name or numerical index) the default sink.
|
||||
Use the special name \@NONE@ to unset the user defined default sink. This will make pulseaudio return to the default
|
||||
sink selection based on sink priority.</p></optdesc>
|
||||
<optdesc><p>Make the specified sink (identified by its symbolic name or numerical index) the default sink.</p></optdesc>
|
||||
</option>
|
||||
|
||||
<option>
|
||||
|
|
@ -191,9 +183,7 @@ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<option>
|
||||
<p><opt>set-default-source</opt> <arg>SOURCE</arg></p>
|
||||
<optdesc><p>Make the specified source (identified by its symbolic name or numerical index) the default source.
|
||||
Use the special name \@NONE@ to unset the user defined default source. This will make pulseaudio return to the default
|
||||
source selection based on source priority.</p></optdesc>
|
||||
<optdesc><p>Make the specified source (identified by its symbolic name or numerical index) the default source.</p></optdesc>
|
||||
</option>
|
||||
|
||||
<option>
|
||||
|
|
|
|||
|
|
@ -143,10 +143,8 @@ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
|
|||
<p><opt>set-default-sink|set-default-source</opt> <arg>index|name</arg></p>
|
||||
<optdesc><p>Make a sink (resp. source) the default. You may specify the
|
||||
sink (resp. source) by its index in the sink (resp. source) list or by its
|
||||
name. Use the special name \@NONE@ to unset the user defined default sink or
|
||||
source. In this case, pulseaudio will return to the default sink or source
|
||||
selection based on priority.</p><p>Note that defaults may be overridden by
|
||||
various policy modules or by specific stream configurations.</p></optdesc>
|
||||
name.</p><p>Note that defaults may be overridden by various policy modules
|
||||
or by specific stream configurations.</p></optdesc>
|
||||
</option>
|
||||
|
||||
<option>
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
|
|||
</option>
|
||||
|
||||
<option>
|
||||
<p><opt>default-server=</opt> The default server to connect
|
||||
<p><opt>default-server=</opt> The default sever to connect
|
||||
to. The environment variable <opt>$PULSE_SERVER</opt> takes
|
||||
precedence.</p>
|
||||
</option>
|
||||
|
|
|
|||
676
meson.build
676
meson.build
|
|
@ -1,12 +1,10 @@
|
|||
project('pulseaudio', 'c',
|
||||
version : run_command(find_program('git-version-gen'), join_paths(meson.current_source_dir(), '.tarball-version'), check : false).stdout().strip(),
|
||||
meson_version : '>= 0.56.0',
|
||||
default_options : [ 'c_std=gnu11', 'cpp_std=c++17' ]
|
||||
project('pulseaudio', 'c', 'cpp',
|
||||
version : run_command(find_program('git-version-gen'), join_paths(meson.current_source_dir(), '.tarball-version')).stdout().strip(),
|
||||
meson_version : '>= 0.50.0',
|
||||
default_options : [ 'c_std=gnu11', 'cpp_std=c++11' ]
|
||||
)
|
||||
|
||||
if not meson.is_subproject()
|
||||
meson.add_dist_script('scripts/save-tarball-version.sh', meson.project_version())
|
||||
endif
|
||||
meson.add_dist_script('scripts/save-tarball-version.sh', meson.project_version())
|
||||
|
||||
pa_version_str = meson.project_version()
|
||||
# For tarballs, the first split will do nothing, but for builds in git, we
|
||||
|
|
@ -27,7 +25,7 @@ pa_protocol_version = 35
|
|||
|
||||
# The stable ABI for client applications, for the version info x:y:z
|
||||
# always will hold x=z
|
||||
libpulse_version_info = [24, 3, 24]
|
||||
libpulse_version_info = [24, 0, 24]
|
||||
|
||||
# A simplified, synchronous, ABI-stable interface for client
|
||||
# applications, for the version info x:y:z always will hold x=z
|
||||
|
|
@ -55,8 +53,6 @@ libpulse_mainloop_glib_version = '@0@.@1@.@2@'.format(
|
|||
libpulse_mainloop_glib_version_info[1],
|
||||
)
|
||||
|
||||
i18n = import('i18n')
|
||||
|
||||
# Paths
|
||||
|
||||
prefix = get_option('prefix')
|
||||
|
|
@ -72,7 +68,6 @@ localedir = join_paths(prefix, get_option('localedir'))
|
|||
localstatedir = join_paths(prefix, get_option('localstatedir'))
|
||||
sysconfdir = join_paths(prefix, get_option('sysconfdir'))
|
||||
privlibdir = join_paths(libdir, 'pulseaudio')
|
||||
po_dir = join_paths(meson.current_source_dir(), 'po')
|
||||
|
||||
if host_machine.system() == 'windows'
|
||||
# Windows only supports loading libraries from the same dir as the executable
|
||||
|
|
@ -90,12 +85,7 @@ pulsesysconfdir = join_paths(sysconfdir, 'pulse')
|
|||
|
||||
modlibexecdir = get_option('modlibexecdir')
|
||||
if modlibexecdir == ''
|
||||
modlibexecdir = join_paths(libdir, 'pulseaudio', 'modules')
|
||||
endif
|
||||
|
||||
if host_machine.system() == 'windows'
|
||||
# Windows only supports loading libraries from the same dir as the executable
|
||||
modlibexecdir = bindir
|
||||
modlibexecdir = join_paths(libdir, 'pulse-' + pa_version_major_minor, 'modules')
|
||||
endif
|
||||
|
||||
padsplibdir = get_option('padsplibdir')
|
||||
|
|
@ -123,7 +113,7 @@ bashcompletiondir = get_option('bashcompletiondir')
|
|||
if bashcompletiondir == ''
|
||||
bash_completion_dep = dependency('bash-completion', required : false)
|
||||
if bash_completion_dep.found()
|
||||
bashcompletiondir = bash_completion_dep.get_variable(pkgconfig : 'completionsdir')
|
||||
bashcompletiondir = bash_completion_dep.get_pkgconfig_variable('completionsdir')
|
||||
else
|
||||
bashcompletiondir = join_paths(datadir, 'bash-completion', 'completions')
|
||||
endif
|
||||
|
|
@ -150,11 +140,7 @@ cdata.set_quoted('PA_MACHINE_ID', join_paths(sysconfdir, 'machine-id'))
|
|||
cdata.set_quoted('PA_MACHINE_ID_FALLBACK', join_paths(localstatedir, 'lib', 'dbus', 'machine-id'))
|
||||
cdata.set_quoted('PA_SRCDIR', join_paths(meson.current_source_dir(), 'src'))
|
||||
cdata.set_quoted('PA_BUILDDIR', meson.current_build_dir())
|
||||
if host_machine.system() == 'windows'
|
||||
cdata.set_quoted('PA_SOEXT', '.dll')
|
||||
else
|
||||
cdata.set_quoted('PA_SOEXT', '.so')
|
||||
endif
|
||||
cdata.set_quoted('PA_SOEXT', '.so')
|
||||
cdata.set_quoted('PA_DEFAULT_CONFIG_DIR', pulsesysconfdir)
|
||||
cdata.set('PA_DEFAULT_CONFIG_DIR_UNQUOTED', pulsesysconfdir)
|
||||
cdata.set_quoted('PA_BINARY', join_paths(bindir, 'pulseaudio'))
|
||||
|
|
@ -166,12 +152,13 @@ cdata.set_quoted('PA_SYSTEM_USER', get_option('system_user'))
|
|||
cdata.set_quoted('PA_SYSTEM_GROUP', get_option('system_group'))
|
||||
cdata.set_quoted('PA_ACCESS_GROUP', get_option('access_group'))
|
||||
cdata.set_quoted('PA_CFLAGS', 'Not yet supported on meson')
|
||||
cdata.set_quoted('PA_ALSA_DATA_DIR', alsadatadir)
|
||||
cdata.set_quoted('PA_ALSA_PATHS_DIR', join_paths(alsadatadir, 'paths'))
|
||||
cdata.set_quoted('PA_ALSA_PROFILE_SETS_DIR', join_paths(alsadatadir, 'profile-sets'))
|
||||
cdata.set_quoted('DESKTOPFILEDIR', join_paths(datadir, 'applications'))
|
||||
cdata.set_quoted('PULSE_LOCALEDIR', localedir)
|
||||
cdata.set_quoted('GETTEXT_PACKAGE', 'pulseaudio')
|
||||
cdata.set('ENABLE_NLS', 1)
|
||||
cdata.set('top_srcdir', meson.project_source_root())
|
||||
cdata.set('top_srcdir', meson.source_root())
|
||||
|
||||
# Platform specifics
|
||||
# First some defaults to keep config file generation happy
|
||||
|
|
@ -190,7 +177,6 @@ endif
|
|||
# rather than ending up in the config.h file?
|
||||
if host_machine.system() == 'darwin'
|
||||
cdata.set('OS_IS_DARWIN', 1)
|
||||
cdata.set('HAVE_COREAUDIO', 1)
|
||||
cdata.set('_DARWIN_C_SOURCE', '200112L') # Needed to get NSIG on Mac OS
|
||||
elif host_machine.system() == 'windows'
|
||||
cdata.set('OS_IS_WIN32', 1)
|
||||
|
|
@ -230,6 +216,7 @@ endif
|
|||
check_headers = [
|
||||
'arpa/inet.h',
|
||||
'byteswap.h',
|
||||
'cpuid.h',
|
||||
'dlfcn.h',
|
||||
'execinfo.h',
|
||||
'grp.h',
|
||||
|
|
@ -289,19 +276,6 @@ if cc.has_header_symbol('pthread.h', 'PTHREAD_PRIO_INHERIT')
|
|||
cdata.set('HAVE_PTHREAD_PRIO_INHERIT', 1)
|
||||
endif
|
||||
|
||||
# Headers which are usable
|
||||
|
||||
check_usable_headers = [
|
||||
'cpuid.h',
|
||||
]
|
||||
|
||||
foreach h : check_usable_headers
|
||||
if cc.check_header(h)
|
||||
define = 'HAVE_' + h.underscorify().to_upper()
|
||||
cdata.set(define, 1)
|
||||
endif
|
||||
endforeach
|
||||
|
||||
# Functions
|
||||
|
||||
check_functions = [
|
||||
|
|
@ -430,7 +404,7 @@ cdata.set('MESON_BUILD', 1)
|
|||
# so we request the nodelete flag to be enabled.
|
||||
# On other systems, we don't really know how to do that, but it's welcome if somebody can tell.
|
||||
# Windows doesn't support this flag.
|
||||
if host_machine.system() != 'windows' and host_machine.system() != 'darwin'
|
||||
if host_machine.system() != 'windows'
|
||||
nodelete_link_args = ['-Wl,-z,nodelete']
|
||||
else
|
||||
nodelete_link_args = []
|
||||
|
|
@ -439,7 +413,6 @@ endif
|
|||
# Code coverage
|
||||
|
||||
if get_option('gcov')
|
||||
add_languages('cpp', native: false)
|
||||
add_project_arguments('--coverage', language: ['c', 'cpp'])
|
||||
add_project_link_arguments('--coverage', language: ['c', 'cpp'])
|
||||
endif
|
||||
|
|
@ -505,24 +478,22 @@ endif
|
|||
|
||||
need_libatomic_ops = false
|
||||
|
||||
atomictest = '''int main() {
|
||||
atomictest = '''void func() {
|
||||
volatile int atomic = 2;
|
||||
__sync_bool_compare_and_swap (&atomic, 2, 3);
|
||||
return 0;
|
||||
}
|
||||
'''
|
||||
|
||||
if cc.links(atomictest)
|
||||
if cc.compiles(atomictest)
|
||||
cdata.set('HAVE_ATOMIC_BUILTINS', 1)
|
||||
|
||||
newatomictest = '''int main() {
|
||||
newatomictest = '''void func() {
|
||||
int c = 0;
|
||||
__atomic_store_n(&c, 4, __ATOMIC_SEQ_CST);
|
||||
return 0;
|
||||
}
|
||||
'''
|
||||
|
||||
if(cc.links(newatomictest))
|
||||
if(cc.compiles(newatomictest))
|
||||
cdata.set('HAVE_ATOMIC_BUILTINS_MEMORY_MODEL', 1)
|
||||
endif
|
||||
|
||||
|
|
@ -594,245 +565,219 @@ if host_machine.cpu_family() == 'arm'
|
|||
endif
|
||||
# NEON checks are automatically done by the unstable-simd module
|
||||
|
||||
# Dependencies common to client, daemon and modules
|
||||
if get_option('daemon')
|
||||
# FIXME: make sure it's >= 2.2
|
||||
ltdl_dep = cc.find_library('ltdl', required : true)
|
||||
endif
|
||||
|
||||
# FIXME: can meson support libtool -dlopen/-dlpreopen things?
|
||||
# and do we still want to support this at all?
|
||||
cdata.set('DISABLE_LIBTOOL_PRELOAD', 1)
|
||||
|
||||
if get_option('database') == 'tdb'
|
||||
database_dep = dependency('tdb')
|
||||
elif get_option('database') == 'gdbm'
|
||||
database_dep = cc.find_library('gdbm', required : true)
|
||||
else
|
||||
database_dep = dependency('', required: false)
|
||||
endif
|
||||
|
||||
if get_option('ipv6')
|
||||
cdata.set('HAVE_IPV6', 1)
|
||||
endif
|
||||
|
||||
if get_option('legacy-database-entry-format')
|
||||
cdata.set('ENABLE_LEGACY_DATABASE_ENTRY_FORMAT', 1)
|
||||
endif
|
||||
|
||||
if get_option('stream-restore-clear-old-devices')
|
||||
cdata.set('STREAM_RESTORE_CLEAR_OLD_DEVICES', 1)
|
||||
endif
|
||||
|
||||
if get_option('running-from-build-tree')
|
||||
cdata.set('HAVE_RUNNING_FROM_BUILD_TREE', 1)
|
||||
endif
|
||||
|
||||
alsa_dep = dependency('alsa', version : '>= 1.0.24', required : get_option('alsa'))
|
||||
if alsa_dep.found()
|
||||
cdata.set('HAVE_ALSA', 1)
|
||||
cdata.set('HAVE_ALSA_UCM', 1)
|
||||
endif
|
||||
|
||||
asyncns_dep = dependency('libasyncns', version : '>= 0.1', required : get_option('asyncns'))
|
||||
if asyncns_dep.found()
|
||||
cdata.set('HAVE_LIBASYNCNS', 1)
|
||||
endif
|
||||
|
||||
dbus_dep = dependency('dbus-1', version : '>= 1.4.12', required : get_option('dbus'))
|
||||
if dbus_dep.found()
|
||||
cdata.set('HAVE_DBUS', 1)
|
||||
endif
|
||||
|
||||
gio_dep = dependency('gio-2.0', version : '>= 2.26.0', required : get_option('gsettings'))
|
||||
if gio_dep.found()
|
||||
cdata.set('HAVE_GSETTINGS', 1)
|
||||
endif
|
||||
|
||||
glib_dep = dependency('glib-2.0', version : '>= 2.28.0', required: get_option('glib'))
|
||||
if glib_dep.found()
|
||||
cdata.set('HAVE_GLIB', 1)
|
||||
cdata.set('HAVE_GLIB20', 1) # to match the AM_CONDITIONAL for CMake file generation
|
||||
endif
|
||||
|
||||
gtk_dep = dependency('gtk+-3.0', required : get_option('gtk'))
|
||||
if gtk_dep.found()
|
||||
cdata.set('HAVE_GTK', 1)
|
||||
endif
|
||||
|
||||
have_orcc = false
|
||||
orcc_args = []
|
||||
orc_dep = dependency('orc-0.4', version : '>= 0.4.11', required : get_option('orc'))
|
||||
orcc = find_program('orcc', required : get_option('orc'))
|
||||
if orc_dep.found() and orcc.found()
|
||||
have_orcc = true
|
||||
orcc_args = [orcc]
|
||||
#orcc_args = [orcc, '--include', 'glib.h']
|
||||
cdata.set('HAVE_ORC', 1)
|
||||
else
|
||||
cdata.set('DISABLE_ORC', 1)
|
||||
endif
|
||||
|
||||
samplerate_dep = dependency('samplerate', version : '>= 0.1.0', required : get_option('samplerate'))
|
||||
if samplerate_dep.found()
|
||||
cdata.set('HAVE_LIBSAMPLERATE', 1)
|
||||
endif
|
||||
|
||||
sndfile_dep = dependency('sndfile', version : '>= 1.0.20')
|
||||
|
||||
soxr_dep = dependency('soxr', version : '>= 0.1.1', required : get_option('soxr'))
|
||||
if soxr_dep.found()
|
||||
cdata.set('HAVE_SOXR', 1)
|
||||
endif
|
||||
|
||||
libsystemd_dep = dependency('libsystemd', required : get_option('systemd'))
|
||||
if libsystemd_dep.found()
|
||||
cdata.set('HAVE_SYSTEMD_DAEMON', 1)
|
||||
cdata.set('HAVE_SYSTEMD_LOGIN', 1)
|
||||
cdata.set('HAVE_SYSTEMD_JOURNAL', 1)
|
||||
endif
|
||||
systemd_dep = dependency('systemd', required : get_option('systemd'))
|
||||
if systemd_dep.found() and systemduserunitdir == ''
|
||||
systemduserunitdir = systemd_dep.get_pkgconfig_variable('systemduserunitdir')
|
||||
endif
|
||||
|
||||
libelogind_dep = dependency('libelogind', required : get_option('elogind'))
|
||||
if libelogind_dep.found()
|
||||
cdata.set('HAVE_SYSTEMD_LOGIN', 1)
|
||||
endif
|
||||
|
||||
tcpwrap_dep = cc.find_library('wrap', required: get_option('tcpwrap'))
|
||||
if cc.has_header('tcpd.h') and cc.has_function('hosts_access', dependencies : tcpwrap_dep)
|
||||
cdata.set('HAVE_LIBWRAP', 1)
|
||||
endif
|
||||
|
||||
x11_dep = dependency('x11-xcb', required : get_option('x11'))
|
||||
if x11_dep.found()
|
||||
xcb_dep = dependency('xcb', required : true, version : '>= 1.6')
|
||||
ice_dep = dependency('ice', required : true)
|
||||
sm_dep = dependency('sm', required : true)
|
||||
xtst_dep = dependency('xtst', required : true)
|
||||
cdata.set('HAVE_X11', 1)
|
||||
if cc.has_function('XSetIOErrorExitHandler', dependencies: x11_dep)
|
||||
cdata.set('HAVE_XSETIOERROREXITHANDLER', 1)
|
||||
endif
|
||||
endif
|
||||
|
||||
# OSS support
|
||||
# Module dependencies
|
||||
if cc.has_header('sys/soundcard.h', required: get_option('oss-output'))
|
||||
# OSS output via daemon module-detect
|
||||
cdata.set('HAVE_OSS_OUTPUT', 1)
|
||||
# OSS wrapper
|
||||
cdata.set('HAVE_OSS_WRAPPER', 1)
|
||||
cdata.set('PULSEDSP_LOCATION', pulsedsp_location)
|
||||
endif
|
||||
|
||||
if get_option('hal-compat')
|
||||
cdata.set('HAVE_HAL_COMPAT', 1)
|
||||
endif
|
||||
|
||||
avahi_dep = dependency('avahi-client', version : '>= 0.6.0', required : get_option('avahi'), disabler : true)
|
||||
if avahi_dep.found()
|
||||
cdata.set('HAVE_AVAHI', 1)
|
||||
endif
|
||||
|
||||
sbc_dep = dependency('sbc', version : '>= 1.0', required : false)
|
||||
|
||||
if get_option('bluez5')
|
||||
assert(dbus_dep.found(), 'BlueZ requires D-Bus support')
|
||||
assert(sbc_dep.found(), 'BlueZ requires SBC support')
|
||||
cdata.set('HAVE_SBC', 1)
|
||||
cdata.set('HAVE_BLUEZ', 1)
|
||||
cdata.set('HAVE_BLUEZ_5', 1)
|
||||
if get_option('bluez5-native-headset')
|
||||
cdata.set('HAVE_BLUEZ_5_NATIVE_HEADSET', 1)
|
||||
endif
|
||||
if get_option('bluez5-ofono-headset')
|
||||
cdata.set('HAVE_BLUEZ_5_OFONO_HEADSET', 1)
|
||||
endif
|
||||
endif
|
||||
|
||||
fftw_dep = dependency('fftw3f', required : get_option('fftw'))
|
||||
if fftw_dep.found()
|
||||
cdata.set('HAVE_FFTW', 1)
|
||||
endif
|
||||
|
||||
# Client library dependencies
|
||||
|
||||
if get_option('client')
|
||||
asyncns_dep = dependency('libasyncns', version : '>= 0.1', required : get_option('asyncns'))
|
||||
if asyncns_dep.found()
|
||||
cdata.set('HAVE_LIBASYNCNS', 1)
|
||||
endif
|
||||
|
||||
gtk_dep = dependency('gtk+-3.0', required : get_option('gtk'))
|
||||
if gtk_dep.found()
|
||||
cdata.set('HAVE_GTK', 1)
|
||||
endif
|
||||
jack_dep = dependency('jack', version : '>= 0.117.0', required : get_option('jack'))
|
||||
if jack_dep.found()
|
||||
cdata.set('HAVE_JACK', 1)
|
||||
endif
|
||||
|
||||
# Daemon and module dependencies
|
||||
lirc_dep = dependency('lirc', required : get_option('lirc'))
|
||||
if lirc_dep.found()
|
||||
cdata.set('HAVE_LIRC', 1)
|
||||
endif
|
||||
|
||||
if get_option('daemon')
|
||||
# FIXME: make sure it's >= 2.2
|
||||
ltdl_dep = cc.find_library('ltdl', required : true)
|
||||
openssl_dep = dependency('openssl', version : '>= 0.9', required : get_option('openssl'))
|
||||
if openssl_dep.found()
|
||||
cdata.set('HAVE_OPENSSL', 1)
|
||||
endif
|
||||
|
||||
# FIXME: can meson support libtool -dlopen/-dlpreopen things?
|
||||
# and do we still want to support this at all?
|
||||
cdata.set('DISABLE_LIBTOOL_PRELOAD', 1)
|
||||
speex_dep = dependency('speexdsp', version : '>= 1.2', required : get_option('speex'))
|
||||
if speex_dep.found()
|
||||
cdata.set('HAVE_SPEEX', 1)
|
||||
endif
|
||||
|
||||
if get_option('database') == 'tdb'
|
||||
database_dep = dependency('tdb')
|
||||
elif get_option('database') == 'gdbm'
|
||||
database_dep = cc.find_library('gdbm', required : true)
|
||||
else
|
||||
database_dep = dependency('', required: false)
|
||||
endif
|
||||
udev_dep = dependency('libudev', version : '>= 143', required : get_option('udev'))
|
||||
if udev_dep.found()
|
||||
cdata.set('HAVE_UDEV', 1)
|
||||
endif
|
||||
|
||||
if get_option('legacy-database-entry-format')
|
||||
cdata.set('ENABLE_LEGACY_DATABASE_ENTRY_FORMAT', 1)
|
||||
endif
|
||||
webrtc_dep = dependency('webrtc-audio-processing', version : '>= 0.2', required : get_option('webrtc-aec'))
|
||||
if webrtc_dep.found()
|
||||
cdata.set('HAVE_WEBRTC', 1)
|
||||
endif
|
||||
|
||||
if get_option('stream-restore-clear-old-devices')
|
||||
cdata.set('STREAM_RESTORE_CLEAR_OLD_DEVICES', 1)
|
||||
endif
|
||||
gst_dep = dependency('gstreamer-1.0', version : '>= 1.14', required : get_option('gstreamer'))
|
||||
gstapp_dep = dependency('gstreamer-app-1.0', required : get_option('gstreamer'))
|
||||
gstrtp_dep = dependency('gstreamer-rtp-1.0', required : get_option('gstreamer'))
|
||||
|
||||
if get_option('running-from-build-tree')
|
||||
cdata.set('HAVE_RUNNING_FROM_BUILD_TREE', 1)
|
||||
endif
|
||||
have_gstreamer = false
|
||||
if gst_dep.found() and gstapp_dep.found() and gstrtp_dep.found()
|
||||
have_gstreamer = true
|
||||
endif
|
||||
|
||||
if get_option('enable-smoother-2')
|
||||
cdata.set('USE_SMOOTHER_2', 1)
|
||||
endif
|
||||
|
||||
alsa_dep = dependency('alsa', version : '>= 1.0.24', required : get_option('alsa'))
|
||||
if alsa_dep.found()
|
||||
cdata.set('HAVE_ALSA', 1)
|
||||
cdata.set('HAVE_ALSA_UCM', 1)
|
||||
endif
|
||||
|
||||
gio_dep = dependency('gio-2.0', version : '>= 2.26.0', required : false)
|
||||
if get_option('gsettings').enabled()
|
||||
assert(gio_dep.found(), 'GSettings support needs glib I/O library (GIO)')
|
||||
cdata.set('HAVE_GSETTINGS', 1)
|
||||
else
|
||||
cdata.set('HAVE_GSETTINGS', 0)
|
||||
endif
|
||||
|
||||
have_orcc = false
|
||||
orcc_args = []
|
||||
orc_dep = dependency('orc-0.4', version : '>= 0.4.11', required : get_option('orc'))
|
||||
orcc = find_program('orcc', required : get_option('orc'))
|
||||
if orc_dep.found() and orcc.found()
|
||||
have_orcc = true
|
||||
orcc_args = [orcc]
|
||||
#orcc_args = [orcc, '--include', 'glib.h']
|
||||
cdata.set('HAVE_ORC', 1)
|
||||
else
|
||||
cdata.set('DISABLE_ORC', 1)
|
||||
endif
|
||||
|
||||
samplerate_dep = dependency('samplerate', version : '>= 0.1.0', required : get_option('samplerate'))
|
||||
if samplerate_dep.found()
|
||||
cdata.set('HAVE_LIBSAMPLERATE', 1)
|
||||
endif
|
||||
|
||||
speex_dep = dependency('speexdsp', version : '>= 1.2', required : get_option('speex'))
|
||||
if speex_dep.found()
|
||||
cdata.set('HAVE_SPEEX', 1)
|
||||
endif
|
||||
|
||||
soxr_dep = dependency('soxr', version : '>= 0.1.1', required : get_option('soxr'))
|
||||
if soxr_dep.found()
|
||||
cdata.set('HAVE_SOXR', 1)
|
||||
endif
|
||||
|
||||
webrtc_dep = dependency('webrtc-audio-processing-1', version : '>= 1.0', required : get_option('webrtc-aec'))
|
||||
if webrtc_dep.found()
|
||||
cdata.set('HAVE_WEBRTC', 1)
|
||||
endif
|
||||
|
||||
systemd_dep = dependency('systemd', required : get_option('systemd'))
|
||||
if systemd_dep.found() and systemduserunitdir == ''
|
||||
systemduserunitdir = systemd_dep.get_variable(pkgconfig: 'systemduserunitdir')
|
||||
endif
|
||||
|
||||
libelogind_dep = dependency('libelogind', required : get_option('elogind'))
|
||||
if libelogind_dep.found()
|
||||
cdata.set('HAVE_SYSTEMD_LOGIN', 1)
|
||||
endif
|
||||
|
||||
if get_option('consolekit').enabled()
|
||||
assert(dbus_dep.found(), 'ConsoleKit requires D-Bus support')
|
||||
endif
|
||||
|
||||
tcpwrap_dep = cc.find_library('wrap', required: get_option('tcpwrap'))
|
||||
if cc.has_header('tcpd.h') and cc.has_function('hosts_access', dependencies : tcpwrap_dep)
|
||||
cdata.set('HAVE_LIBWRAP', 1)
|
||||
endif
|
||||
|
||||
if x11_dep.found()
|
||||
xcb_dep = dependency('xcb', required : true, version : '>= 1.6')
|
||||
ice_dep = dependency('ice', required : true)
|
||||
sm_dep = dependency('sm', required : true)
|
||||
xtst_dep = dependency('xtst', required : true)
|
||||
cdata.set('HAVE_X11', 1)
|
||||
if cc.has_function('XSetIOErrorExitHandler', dependencies: x11_dep)
|
||||
cdata.set('HAVE_XSETIOERROREXITHANDLER', 1)
|
||||
endif
|
||||
endif
|
||||
|
||||
avahi_dep = dependency('avahi-client', version : '>= 0.6.0', required : get_option('avahi'), disabler : true)
|
||||
if avahi_dep.found()
|
||||
cdata.set('HAVE_AVAHI', 1)
|
||||
else
|
||||
cdata.set('HAVE_AVAHI', 0)
|
||||
endif
|
||||
|
||||
sbc_dep = dependency('sbc', version : '>= 1.0', required : false)
|
||||
|
||||
bluez_dep = dependency('bluez', required : get_option('bluez5'))
|
||||
|
||||
if bluez_dep.found()
|
||||
assert(dbus_dep.found(), 'BlueZ requires D-Bus support')
|
||||
assert(sbc_dep.found(), 'BlueZ requires SBC support')
|
||||
cdata.set('HAVE_SBC', 1)
|
||||
cdata.set('HAVE_BLUEZ', 1)
|
||||
cdata.set('HAVE_BLUEZ_5', 1)
|
||||
if get_option('bluez5-native-headset')
|
||||
cdata.set('HAVE_BLUEZ_5_NATIVE_HEADSET', 1)
|
||||
endif
|
||||
if get_option('bluez5-ofono-headset')
|
||||
cdata.set('HAVE_BLUEZ_5_OFONO_HEADSET', 1)
|
||||
endif
|
||||
endif
|
||||
|
||||
jack_dep = dependency('jack', version : '>= 0.117.0', required : get_option('jack'))
|
||||
if jack_dep.found()
|
||||
cdata.set('HAVE_JACK', 1)
|
||||
endif
|
||||
|
||||
lirc_dep = dependency('lirc', required : get_option('lirc'))
|
||||
if lirc_dep.found()
|
||||
cdata.set('HAVE_LIRC', 1)
|
||||
endif
|
||||
|
||||
openssl_dep = dependency('openssl', version : '>= 0.9', required : get_option('openssl'))
|
||||
if openssl_dep.found()
|
||||
cdata.set('HAVE_OPENSSL', 1)
|
||||
endif
|
||||
|
||||
udev_dep = dependency('libudev', version : '>= 143', required : get_option('udev'))
|
||||
if udev_dep.found()
|
||||
cdata.set('HAVE_UDEV', 1)
|
||||
endif
|
||||
|
||||
if get_option('hal-compat')
|
||||
cdata.set('HAVE_HAL_COMPAT', 1)
|
||||
endif
|
||||
|
||||
gst_dep = dependency('gstreamer-1.0', version : '>= 1.14', required : get_option('gstreamer'))
|
||||
gstapp_dep = dependency('gstreamer-app-1.0', required : get_option('gstreamer'))
|
||||
gstrtp_dep = dependency('gstreamer-rtp-1.0', required : get_option('gstreamer'))
|
||||
|
||||
have_gstreamer = false
|
||||
if gst_dep.found() and gstapp_dep.found() and gstrtp_dep.found()
|
||||
assert(gio_dep.found(), 'GStreamer-based RTP needs glib I/O library (GIO)')
|
||||
have_gstreamer = true
|
||||
endif
|
||||
|
||||
bluez5_gst_dep = dependency('gstreamer-1.0', version : '>= 1.14', required : get_option('bluez5-gstreamer'))
|
||||
bluez5_gstapp_dep = dependency('gstreamer-app-1.0', required : get_option('bluez5-gstreamer'))
|
||||
have_bluez5_gstreamer = false
|
||||
if bluez5_gst_dep.found() and bluez5_gstapp_dep.found()
|
||||
have_bluez5_gstreamer = true
|
||||
cdata.set('HAVE_GSTLDAC', 1)
|
||||
cdata.set('HAVE_GSTAPTX', 1)
|
||||
endif
|
||||
bluez5_gst_dep = dependency('gstreamer-1.0', version : '>= 1.14', required : get_option('bluez5-gstreamer'))
|
||||
bluez5_gstapp_dep = dependency('gstreamer-app-1.0', required : get_option('bluez5-gstreamer'))
|
||||
have_bluez5_gstreamer = false
|
||||
if bluez5_gst_dep.found() and bluez5_gstapp_dep.found()
|
||||
have_bluez5_gstreamer = true
|
||||
cdata.set('HAVE_GSTLDAC', 1)
|
||||
cdata.set('HAVE_GSTAPTX', 1)
|
||||
endif
|
||||
|
||||
# These are required for the CMake file generation
|
||||
cdata.set('PA_LIBDIR', libdir)
|
||||
cdata.set('PA_INCDIR', includedir)
|
||||
if glib_dep.found()
|
||||
cdata.set('HAVE_GLIB20', 1) # to match the AM_CONDITIONAL for CMake file generation
|
||||
endif
|
||||
|
||||
# Test dependencies
|
||||
|
||||
|
|
@ -840,90 +785,84 @@ check_dep = dependency('check', version : '>= 0.9.10', required : get_option('te
|
|||
|
||||
# Subdirs
|
||||
|
||||
subdir('doxygen')
|
||||
if get_option('client')
|
||||
subdir('po')
|
||||
if get_option('doxygen')
|
||||
subdir('doxygen')
|
||||
endif
|
||||
subdir('po')
|
||||
if get_option('man')
|
||||
subdir('man')
|
||||
endif
|
||||
subdir('shell-completion/bash')
|
||||
subdir('shell-completion/zsh')
|
||||
subdir('src')
|
||||
if get_option('client')
|
||||
subdir('vala')
|
||||
endif
|
||||
subdir('vala')
|
||||
|
||||
# Now generate config.h from everything above
|
||||
configure_file(output : 'config.h', configuration : cdata)
|
||||
|
||||
if get_option('client')
|
||||
# pkg-config files
|
||||
|
||||
# pkg-config files
|
||||
pc_cdata = configuration_data()
|
||||
|
||||
pc_cdata = configuration_data()
|
||||
pc_cdata.set('prefix', prefix)
|
||||
pc_cdata.set('exec_prefix', prefix)
|
||||
pc_cdata.set('libdir', libdir)
|
||||
pc_cdata.set('includedir', includedir)
|
||||
pc_cdata.set('modlibexecdir', modlibexecdir)
|
||||
pc_cdata.set('PACKAGE_VERSION', pa_version_str)
|
||||
pc_cdata.set('PA_MAJORMINOR', pa_version_major_minor)
|
||||
# FIXME: the line below is wrong. Currently the meson thread dep lacks documentation,
|
||||
# and doesn't allow introspection, ie. none of get_pkgconfig_variable() or
|
||||
# get_configtool_variable() work with it, so we have no way to get this flag right,
|
||||
# unless we do all the work ourselves. See current work in glib, also meson #553.
|
||||
pc_cdata.set('PTHREAD_LIBS', '-pthread')
|
||||
|
||||
pc_cdata.set('prefix', prefix)
|
||||
pc_cdata.set('exec_prefix', prefix)
|
||||
pc_cdata.set('libdir', libdir)
|
||||
pc_cdata.set('includedir', includedir)
|
||||
pc_cdata.set('modlibexecdir', modlibexecdir)
|
||||
pc_cdata.set('PACKAGE_VERSION', pa_version_str)
|
||||
pc_cdata.set('PA_MAJORMINOR', pa_version_major_minor)
|
||||
# FIXME: the line below is wrong. Currently the meson thread dep lacks documentation,
|
||||
# and doesn't allow introspection, ie. none of get_pkgconfig_variable() or
|
||||
# get_configtool_variable() work with it, so we have no way to get this flag right,
|
||||
# unless we do all the work ourselves. See current work in glib, also meson #553.
|
||||
pc_cdata.set('PTHREAD_LIBS', '-pthread')
|
||||
pc_files = [
|
||||
'libpulse.pc',
|
||||
'libpulse-simple.pc',
|
||||
]
|
||||
|
||||
pc_files = [
|
||||
'libpulse.pc',
|
||||
'libpulse-simple.pc',
|
||||
]
|
||||
|
||||
if glib_dep.found()
|
||||
pc_files += 'libpulse-mainloop-glib.pc'
|
||||
endif
|
||||
|
||||
foreach file : pc_files
|
||||
configure_file(
|
||||
input : file + '.in',
|
||||
output : file,
|
||||
configuration : pc_cdata,
|
||||
install_dir : pkgconfigdir)
|
||||
endforeach
|
||||
|
||||
# CMake files
|
||||
|
||||
m4 = find_program('m4', required: true)
|
||||
|
||||
cmakedir = join_paths(libdir, 'cmake', 'PulseAudio')
|
||||
|
||||
cmake_template_file = configure_file(
|
||||
input : 'PulseAudioConfig.cmake.in',
|
||||
output : 'PulseAudioConfig.cmake.tmp',
|
||||
configuration: cdata,
|
||||
)
|
||||
|
||||
custom_target('PulseAudioConfig.cmake',
|
||||
input : cmake_template_file,
|
||||
output : 'PulseAudioConfig.cmake',
|
||||
capture : true,
|
||||
command : [m4, '@INPUT@'],
|
||||
build_by_default : true,
|
||||
install : true,
|
||||
install_dir : cmakedir,
|
||||
)
|
||||
if glib_dep.found()
|
||||
pc_files += 'libpulse-mainloop-glib.pc'
|
||||
endif
|
||||
|
||||
foreach file : pc_files
|
||||
configure_file(
|
||||
input : 'PulseAudioConfigVersion.cmake.in',
|
||||
output : 'PulseAudioConfigVersion.cmake',
|
||||
configuration: cdata,
|
||||
install : true,
|
||||
install_dir : cmakedir,
|
||||
)
|
||||
input : file + '.in',
|
||||
output : file,
|
||||
configuration : pc_cdata,
|
||||
install_dir : pkgconfigdir)
|
||||
endforeach
|
||||
|
||||
endif # client
|
||||
# CMake files
|
||||
|
||||
m4 = find_program('m4', required: true)
|
||||
|
||||
cmakedir = join_paths(libdir, 'cmake', 'PulseAudio')
|
||||
|
||||
cmake_template_file = configure_file(
|
||||
input : 'PulseAudioConfig.cmake.in',
|
||||
output : 'PulseAudioConfig.cmake.tmp',
|
||||
configuration: cdata,
|
||||
)
|
||||
|
||||
custom_target('PulseAudioConfig.cmake',
|
||||
input : cmake_template_file,
|
||||
output : 'PulseAudioConfig.cmake',
|
||||
capture : true,
|
||||
command : [m4, '@INPUT@'],
|
||||
build_by_default : true,
|
||||
install : true,
|
||||
install_dir : cmakedir,
|
||||
)
|
||||
|
||||
configure_file(
|
||||
input : 'PulseAudioConfigVersion.cmake.in',
|
||||
output : 'PulseAudioConfigVersion.cmake',
|
||||
configuration: cdata,
|
||||
install : true,
|
||||
install_dir : cmakedir,
|
||||
)
|
||||
|
||||
############################################################
|
||||
|
||||
|
|
@ -954,67 +893,49 @@ summary = [
|
|||
# 'LIBS: @0@'.format(${LIBS}),
|
||||
'',
|
||||
'Enable pulseaudio daemon: @0@'.format(get_option('daemon')),
|
||||
'Enable pulseaudio client: @0@'.format(get_option('client')),
|
||||
'',
|
||||
'Enable memfd shared memory: @0@'.format(cdata.has('HAVE_MEMFD')),
|
||||
'Enable X11: @0@'.format(x11_dep.found()),
|
||||
'Enable D-Bus: @0@'.format(dbus_dep.found()),
|
||||
'Enable GLib 2: @0@'.format(glib_dep.found()),
|
||||
'Enable systemd integration: @0@'.format(libsystemd_dep.found()),
|
||||
'Enable FFTW: @0@'.format(fftw_dep.found()),
|
||||
'Enable IPv6: @0@'.format(get_option('ipv6')),
|
||||
'Enable Gcov coverage: @0@'.format(get_option('gcov')),
|
||||
'Enable Valgrind: @0@'.format(cdata.has('HAVE_VALGRIND_MEMCHECK_H')),
|
||||
'Enable man pages: @0@'.format(get_option('man')),
|
||||
'Enable unit tests: @0@'.format(get_option('tests')),
|
||||
]
|
||||
|
||||
if get_option('client')
|
||||
summary += [
|
||||
'',
|
||||
'--- Pulseaudio client features ---',
|
||||
'',
|
||||
'Enable Gtk+ 3: @0@'.format(gtk_dep.found()),
|
||||
'Enable Async DNS: @0@'.format(asyncns_dep.found()),
|
||||
'Enable OSS Wrapper: @0@'.format(cdata.has('HAVE_OSS_WRAPPER')),
|
||||
]
|
||||
endif
|
||||
|
||||
if get_option('daemon')
|
||||
summary += [
|
||||
'',
|
||||
'--- Pulseaudio daemon features ---',
|
||||
'',
|
||||
'Safe X11 I/O errors: @0@'.format(cdata.has('HAVE_XSETIOERROREXITHANDLER')),
|
||||
'Enable Avahi: @0@'.format(avahi_dep.found()),
|
||||
' Safe X11 I/O errors: @0@'.format(cdata.has('HAVE_XSETIOERROREXITHANDLER')),
|
||||
'Enable OSS Output: @0@'.format(cdata.has('HAVE_OSS_OUTPUT')),
|
||||
'Enable OSS Wrapper: @0@'.format(cdata.has('HAVE_OSS_WRAPPER')),
|
||||
# 'Enable EsounD: @0@'.format(${ENABLE_ESOUND}),
|
||||
'Enable Alsa: @0@'.format(alsa_dep.found()),
|
||||
'Enable Jack: @0@'.format(jack_dep.found()),
|
||||
'Enable LIRC: @0@'.format(lirc_dep.found()),
|
||||
# 'Enable CoreAudio: @0@'.format(${ENABLE_COREAUDIO}),
|
||||
# 'Enable Solaris: @0@'.format(${ENABLE_SOLARIS}),
|
||||
# 'Enable WaveOut: @0@'.format(${ENABLE_WAVEOUT}),
|
||||
'Enable GLib 2: @0@'.format(glib_dep.found()),
|
||||
'Enable GSettings: @0@'.format(gio_dep.found()),
|
||||
'Enable BlueZ 5: @0@'.format(cdata.has('HAVE_BLUEZ_5')),
|
||||
' Enable native headsets: @0@'.format(cdata.has('HAVE_BLUEZ_5_NATIVE_HEADSET')),
|
||||
' Enable ofono headsets: @0@'.format(cdata.has('HAVE_BLUEZ_5_OFONO_HEADSET')),
|
||||
' Enable GStreamer based codecs: @0@'.format(have_bluez5_gstreamer),
|
||||
'Enable GStreamer: @0@'.format(have_gstreamer),
|
||||
'Enable Gtk+ 3: @0@'.format(gtk_dep.found()),
|
||||
'Enable Avahi: @0@'.format(avahi_dep.found()),
|
||||
'Enable Jack: @0@'.format(jack_dep.found()),
|
||||
'Enable Async DNS: @0@'.format(asyncns_dep.found()),
|
||||
'Enable LIRC: @0@'.format(lirc_dep.found()),
|
||||
'Enable D-Bus: @0@'.format(dbus_dep.found()),
|
||||
' Enable BlueZ 5: @0@'.format(get_option('bluez5')),
|
||||
' Enable native headsets: @0@'.format(get_option('bluez5-native-headset')),
|
||||
' Enable ofono headsets: @0@'.format(get_option('bluez5-ofono-headset')),
|
||||
' Enable GStreamer based codecs: @0@'.format(have_bluez5_gstreamer),
|
||||
'Enable udev: @0@'.format(udev_dep.found()),
|
||||
' Enable HAL->udev compat: @0@'.format(get_option('hal-compat')),
|
||||
'Enable systemd: @0@'.format(libsystemd_dep.found()),
|
||||
'Enable elogind: @0@'.format(libelogind_dep.found()),
|
||||
'Enable TCP Wrappers: @0@'.format(tcpwrap_dep.found()),
|
||||
'Enable libsamplerate: @0@'.format(samplerate_dep.found()),
|
||||
'Enable IPv6: @0@'.format(get_option('ipv6')),
|
||||
'Enable OpenSSL (for Airtunes): @0@'.format(openssl_dep.found()),
|
||||
'Enable FFTW: @0@'.format(fftw_dep.found()),
|
||||
'Enable ORC: @0@'.format(have_orcc),
|
||||
'Enable GStreamer: @0@'.format(have_gstreamer),
|
||||
'Enable Adrian echo canceller: @0@'.format(get_option('adrian-aec')),
|
||||
'Enable Speex (resampler, AEC): @0@'.format(speex_dep.found()),
|
||||
'Enable SoXR (resampler): @0@'.format(soxr_dep.found()),
|
||||
'Enable WebRTC echo canceller: @0@'.format(webrtc_dep.found()),
|
||||
'Enable Gcov coverage: @0@'.format(get_option('gcov')),
|
||||
'Enable Valgrind: @0@'.format(cdata.has('HAVE_VALGRIND_MEMCHECK_H')),
|
||||
'Enable man pages: @0@'.format(get_option('man')),
|
||||
'Enable unit tests: @0@'.format(get_option('tests')),
|
||||
'',
|
||||
'Enable udev: @0@'.format(udev_dep.found()),
|
||||
' Enable HAL->udev compat: @0@'.format(get_option('hal-compat')),
|
||||
'Enable systemd units: @0@'.format(systemd_dep.found()),
|
||||
'Enable elogind: @0@'.format(libelogind_dep.found()),
|
||||
'Enable ConsoleKit: @0@'.format(not get_option('consolekit').disabled() and dbus_dep.found()),
|
||||
'Enable TCP Wrappers: @0@'.format(tcpwrap_dep.found()),
|
||||
'Enable OpenSSL (for Airtunes): @0@'.format(openssl_dep.found()),
|
||||
'Database: @0@'.format(get_option('database')),
|
||||
'Legacy Database Entry Support: @0@'.format(get_option('legacy-database-entry-format')),
|
||||
'module-stream-restore:',
|
||||
|
|
@ -1027,48 +948,47 @@ summary += [
|
|||
# 'Force preopen: @0@'.format(${FORCE_PREOPEN}),
|
||||
# 'Preopened modules: @0@'.format(${PREOPEN_MODS}),
|
||||
]
|
||||
endif
|
||||
|
||||
message('\n '.join(summary))
|
||||
|
||||
# Sanity checks
|
||||
|
||||
if get_option('daemon') and not speex_dep.found() and not webrtc_dep.found() and not get_option('adrian-aec')
|
||||
if not speex_dep.found() and not webrtc_dep.found() and not get_option('adrian-aec')
|
||||
error('At least one echo canceller implementation must be available!')
|
||||
endif
|
||||
|
||||
if get_option('daemon') and samplerate_dep.found()
|
||||
if samplerate_dep.found()
|
||||
warning('Support for libsamplerate is DEPRECATED')
|
||||
endif
|
||||
|
||||
if host_machine.system() != 'windows' and not dbus_dep.found()
|
||||
message = [
|
||||
'You do not have D-Bus support enabled. It is strongly recommended',
|
||||
'that you enable D-Bus support if your platform supports it.',
|
||||
'Many parts of PulseAudio use D-Bus, from ConsoleKit interaction',
|
||||
'to the Device Reservation Protocol to speak to JACK, Bluetooth',
|
||||
'support and even a native control protocol for communicating and',
|
||||
'controlling the PulseAudio daemon itself.',
|
||||
]
|
||||
warning('\n' + '\n'.join(message))
|
||||
endif
|
||||
|
||||
if get_option('daemon') and host_machine.system() == 'linux' and not udev_dep.found()
|
||||
message = [
|
||||
'You do not have udev support enabled. It is strongly recommended',
|
||||
'that you enable udev support if your platform supports it as it is',
|
||||
'the primary method used to detect hardware audio devices (on Linux)',
|
||||
'and is thus a critical part of PulseAudio on that platform.',
|
||||
]
|
||||
warning('\n' + '\n'.join(message))
|
||||
endif
|
||||
|
||||
if get_option('daemon') and host_machine.system() != 'windows' and not speex_dep.found()
|
||||
message = [
|
||||
'You do not have speex support enabled. It is strongly recommended',
|
||||
'that you enable speex support if your platform supports it as it is',
|
||||
'the primary method used for audio resampling and is thus a critical',
|
||||
'part of PulseAudio on that platform.',
|
||||
]
|
||||
warning('\n' + '\n'.join(message))
|
||||
if host_machine.system() != 'windows'
|
||||
if not dbus_dep.found()
|
||||
message = [
|
||||
'You do not have D-Bus support enabled. It is strongly recommended',
|
||||
'that you enable D-Bus support if your platform supports it.',
|
||||
'Many parts of PulseAudio use D-Bus, from ConsoleKit interaction',
|
||||
'to the Device Reservation Protocol to speak to JACK, Bluetooth',
|
||||
'support and even a native control protocol for communicating and',
|
||||
'controlling the PulseAudio daemon itself.',
|
||||
]
|
||||
warning('\n' + '\n'.join(message))
|
||||
endif
|
||||
if host_machine.system() == 'linux' and not udev_dep.found()
|
||||
message = [
|
||||
'You do not have udev support enabled. It is strongly recommended',
|
||||
'that you enable udev support if your platform supports it as it is',
|
||||
'the primary method used to detect hardware audio devices (on Linux)',
|
||||
'and is thus a critical part of PulseAudio on that platform.',
|
||||
]
|
||||
warning('\n' + '\n'.join(message))
|
||||
endif
|
||||
if not speex_dep.found()
|
||||
message = [
|
||||
'You do not have speex support enabled. It is strongly recommended',
|
||||
'that you enable speex support if your platform supports it as it is',
|
||||
'the primary method used for audio resampling and is thus a critical',
|
||||
'part of PulseAudio on that platform.',
|
||||
]
|
||||
warning('\n' + '\n'.join(message))
|
||||
endif
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -1,11 +1,8 @@
|
|||
option('daemon',
|
||||
type : 'boolean', value : true,
|
||||
description : 'Enable building and installation of pulseaudio daemon and supporting configuration files')
|
||||
option('client',
|
||||
type : 'boolean', value : true,
|
||||
description : 'Build and install pulseaudio client libraries and utilities')
|
||||
option('doxygen',
|
||||
type : 'feature',
|
||||
type : 'boolean', value : true,
|
||||
description : 'Enable building and installation of documentation generated with doxygen')
|
||||
option('gcov',
|
||||
type : 'boolean', value : false,
|
||||
|
|
@ -14,7 +11,7 @@ option('man',
|
|||
type : 'boolean',
|
||||
description : 'Enable building and installation of man pages')
|
||||
option('tests',
|
||||
type : 'feature',
|
||||
type : 'boolean',
|
||||
description : 'Enable unit tests')
|
||||
|
||||
option('system_user',
|
||||
|
|
@ -88,7 +85,7 @@ option('avahi',
|
|||
type : 'feature', value : 'auto',
|
||||
description : 'Optional Avahi support')
|
||||
option('bluez5',
|
||||
type : 'feature', value : 'auto',
|
||||
type : 'boolean', value : 'true',
|
||||
description : 'Optional BlueZ 5 support')
|
||||
option('bluez5-gstreamer',
|
||||
type : 'feature', value: 'auto',
|
||||
|
|
@ -99,9 +96,6 @@ option('bluez5-native-headset',
|
|||
option('bluez5-ofono-headset',
|
||||
type : 'boolean',
|
||||
description : 'Optional oFono headset backend support (BlueZ 5)')
|
||||
option('consolekit',
|
||||
type : 'feature', value : 'auto',
|
||||
description : 'Optional ConsoleKit support')
|
||||
option('dbus',
|
||||
type : 'feature', value : 'auto',
|
||||
description : 'Optional D-Bus support')
|
||||
|
|
@ -118,7 +112,7 @@ option('gsettings',
|
|||
type : 'feature', value : 'auto',
|
||||
description : 'Optional GSettings support')
|
||||
option('gstreamer',
|
||||
type : 'feature', value : 'auto',
|
||||
type : 'feature', value : 'disabled',
|
||||
description : 'Optional GStreamer dependency for media-related functionality')
|
||||
option('gtk',
|
||||
type : 'feature', value : 'auto',
|
||||
|
|
@ -168,9 +162,6 @@ option('valgrind',
|
|||
option('x11',
|
||||
type : 'feature', value : 'auto',
|
||||
description : 'Optional X11 support')
|
||||
option('enable-smoother-2',
|
||||
type : 'boolean', value : true,
|
||||
description : 'Use alternative time smoother implementation')
|
||||
|
||||
# Echo cancellation
|
||||
|
||||
|
|
|
|||
|
|
@ -48,8 +48,3 @@ zh_CN
|
|||
zh_TW
|
||||
eo
|
||||
si
|
||||
ka
|
||||
eu
|
||||
ar
|
||||
sl
|
||||
ro
|
||||
|
|
|
|||
|
|
@ -170,7 +170,6 @@ src/pulsecore/thread-mq.c
|
|||
src/pulsecore/thread-posix.c
|
||||
src/pulsecore/thread-win32.c
|
||||
src/pulsecore/time-smoother.c
|
||||
src/pulsecore/time-smoother_2.c
|
||||
src/pulsecore/tokenizer.c
|
||||
src/pulsecore/x11prop.c
|
||||
src/pulsecore/x11wrap.c
|
||||
|
|
|
|||
619
po/bn_IN.po
619
po/bn_IN.po
File diff suppressed because it is too large
Load diff
619
po/de_CH.po
619
po/de_CH.po
File diff suppressed because it is too large
Load diff
|
|
@ -1,3 +1,4 @@
|
|||
i18n = import('i18n')
|
||||
i18n.gettext(
|
||||
meson.project_name(),
|
||||
preset: 'glib',
|
||||
|
|
@ -6,3 +7,5 @@ i18n.gettext(
|
|||
args: ['--msgid-bugs-address=https://gitlab.freedesktop.org/pulseaudio/pulseaudio/issues/new',
|
||||
'--width=90'],
|
||||
)
|
||||
|
||||
po_dir = meson.current_source_dir()
|
||||
|
|
|
|||
782
po/pt_BR.po
782
po/pt_BR.po
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
619
po/sr@latin.po
619
po/sr@latin.po
File diff suppressed because it is too large
Load diff
845
po/zh_CN.po
845
po/zh_CN.po
File diff suppressed because it is too large
Load diff
629
po/zh_TW.po
629
po/zh_TW.po
File diff suppressed because it is too large
Load diff
|
|
@ -17,14 +17,7 @@ print_map_file() {
|
|||
echo "};"
|
||||
}
|
||||
|
||||
print_def_file() {
|
||||
echo "EXPORTS"
|
||||
ctags -I ${CTAGS_IDENTIFIER_LIST} -f - --c-kinds=p "$@" | awk '/^pa_/ && !/(^pa_glib_|^pa_simple_)/ { print $1 }' | sort
|
||||
}
|
||||
TARGET_FILE=$1
|
||||
shift
|
||||
|
||||
MAP_FILE=$1
|
||||
DEF_FILE=$2
|
||||
shift 2
|
||||
|
||||
cd "${MESON_SOURCE_ROOT}/${MESON_SUBDIR}" && print_map_file "$@" > ${MAP_FILE}
|
||||
cd "${MESON_SOURCE_ROOT}/${MESON_SUBDIR}" && print_def_file "$@" > ${DEF_FILE}
|
||||
cd "${MESON_SOURCE_ROOT}/${MESON_SUBDIR}" && print_map_file "$@" > ${TARGET_FILE}
|
||||
|
|
|
|||
|
|
@ -3,33 +3,25 @@ if bashcompletiondir != 'no'
|
|||
|
||||
if get_option('daemon')
|
||||
aliases += [
|
||||
'pulseaudio',
|
||||
'pacmd',
|
||||
'pasuspender',
|
||||
]
|
||||
|
||||
# Create target directory for symlinks
|
||||
if meson.version().version_compare('>= 0.60.0')
|
||||
install_emptydir(bashcompletiondir)
|
||||
else
|
||||
meson.add_install_script('sh', '-c', 'mkdir -p $DESTDIR@0@'.format(bashcompletiondir))
|
||||
endif
|
||||
endif
|
||||
|
||||
if get_option('client')
|
||||
aliases += [
|
||||
'pacat',
|
||||
'padsp',
|
||||
'paplay',
|
||||
'parec',
|
||||
'parecord',
|
||||
]
|
||||
install_data('pactl', install_dir : bashcompletiondir)
|
||||
endif
|
||||
aliases += [
|
||||
'pacat',
|
||||
'pactl',
|
||||
'padsp',
|
||||
'paplay',
|
||||
'parec',
|
||||
'parecord',
|
||||
]
|
||||
|
||||
install_data('pulseaudio', install_dir : bashcompletiondir)
|
||||
|
||||
foreach alias : aliases
|
||||
dst = join_paths(bashcompletiondir, alias)
|
||||
cmd = 'ln -fs @0@ $DESTDIR@1@'.format('pactl', dst)
|
||||
cmd = 'ln -fs @0@ $DESTDIR@1@'.format('pulseaudio', dst)
|
||||
meson.add_install_script('sh', '-c', cmd)
|
||||
endforeach
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -109,20 +109,19 @@ in_array() {
|
|||
}
|
||||
|
||||
_pactl() {
|
||||
local cur prev words cword preprev word command
|
||||
local cur prev words cword preprev command
|
||||
local comps
|
||||
local flags='-h --help --version -s --server= --client-name='
|
||||
local list_types='short sinks sources sink-inputs source-outputs cards
|
||||
modules samples clients message-handlers'
|
||||
local commands=(stat info list exit upload-sample play-sample remove-sample
|
||||
load-module unload-module move-sink-input move-source-output
|
||||
suspend-sink suspend-source set-card-profile get-default-sink
|
||||
set-default-sink set-sink-port get-default-source set-default-source
|
||||
set-source-port get-sink-volume set-sink-volume get-source-volume
|
||||
suspend-sink suspend-source set-card-profile set-default-sink
|
||||
set-sink-port set-default-source set-source-port set-sink-volume
|
||||
set-source-volume set-sink-input-volume set-source-output-volume
|
||||
get-sink-mute set-sink-mute get-source-mute set-source-mute
|
||||
set-sink-input-mute set-source-output-mute set-sink-formats
|
||||
set-port-latency-offset subscribe send-message help)
|
||||
set-sink-mute set-source-mute set-sink-input-mute
|
||||
set-source-output-mute set-sink-formats set-port-latency-offset
|
||||
subscribe send-message help)
|
||||
|
||||
_init_completion -n = || return
|
||||
preprev=${words[$cword-2]}
|
||||
|
|
@ -187,8 +186,6 @@ _pactl() {
|
|||
|
||||
remove-sample) ;; # TODO
|
||||
|
||||
get-default*) ;;
|
||||
|
||||
load-module)
|
||||
comps=$(__all_modules)
|
||||
COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
|
||||
|
|
@ -258,7 +255,7 @@ _pactl() {
|
|||
complete -F _pactl pactl
|
||||
|
||||
_pacmd() {
|
||||
local cur prev words cword preprev word command
|
||||
local cur prev words cword preprev command
|
||||
local comps
|
||||
local flags='-h --help --version'
|
||||
local commands=(exit help list-modules list-cards list-sinks list-sources list-clients
|
||||
|
|
@ -503,7 +500,7 @@ _pulseaudio()
|
|||
--start -k --kill --check --system= -D --daemonize= --fail= --high-priority=
|
||||
--realtime= --disallow-module-loading= --disallow-exit= --exit-idle-time=
|
||||
--scache-idle-time= --log-level= -v --log-target= --log-meta= --log-time=
|
||||
--log-backtrace= -p --dl-search-path= --resample-method= --use-pid-file=
|
||||
--log-backtrace= -p --dl-search-path= --resample-method= --use-pit-file=
|
||||
--no-cpu-limit= --disable-shm= --enable-memfd= -L --load= -F --file= -C -n'
|
||||
_init_completion -n = || return
|
||||
|
||||
|
|
@ -18,12 +18,10 @@ _devices() {
|
|||
if [[ $service == pactl || $service == pacmd ]]; then
|
||||
case $words[$((CURRENT - 1))] in
|
||||
set-sink-input-*) cmd=('sink-inputs');;
|
||||
get-sink-*) cmd=('sinks');;
|
||||
set-sink-*) cmd=('sinks');;
|
||||
set-default-sink) cmd=('sinks');;
|
||||
set-default-source) cmd=('sources');;
|
||||
set-source-output-*) cmd=('source-outputs');;
|
||||
get-source-*) cmd=('sources');;
|
||||
set-source-*) cmd=('sources');;
|
||||
suspend-sink) cmd=('sinks');;
|
||||
suspend-source) cmd=('sources');;
|
||||
|
|
@ -259,22 +257,16 @@ _pactl_completion() {
|
|||
'suspend-sink: suspend or resume a sink'
|
||||
'suspend-source: suspend or resume a source'
|
||||
'set-card-profile: set a card profile'
|
||||
'get-default-sink: get the default sink'
|
||||
'set-default-sink: set the default sink'
|
||||
'get-default-source: get the default source'
|
||||
'set-default-source: set the default source'
|
||||
'set-sink-port: set the sink port of a sink'
|
||||
'set-source-port: set the source port of a source'
|
||||
'set-port-latency-offset: set a latency offset on a port'
|
||||
'get-sink-volume: get the volume of a sink'
|
||||
'set-sink-volume: set the volume of a sink'
|
||||
'get-source-volume: get the volume of a source'
|
||||
'set-source-volume: set the volume of a source'
|
||||
'set-sink-input-volume: set the volume of a stream'
|
||||
'set-source-output-volume: set the volume of a recording stream'
|
||||
'get-sink-mute: get the mute status of a sink'
|
||||
'set-sink-mute: mute a sink'
|
||||
'get-source-mute: get the mute status of a source'
|
||||
'set-source-mute: mute a source'
|
||||
'set-sink-input-mute: mute a stream'
|
||||
'set-source-output-mute: mute a recording stream'
|
||||
|
|
@ -500,15 +492,11 @@ _pactl_completion() {
|
|||
set-default-source) if ((CURRENT == 2)); then _devices; fi;;
|
||||
set-sink-port) _set_sink_port_parameter;;
|
||||
set-source-port) _set_source_port_parameter;;
|
||||
get-sink-volume) if ((CURRENT == 2)); then _devices; fi;;
|
||||
set-sink-volume) if ((CURRENT == 2)); then _devices; fi;;
|
||||
get-source-volume) if ((CURRENT == 2)); then _devices; fi;;
|
||||
set-source-volume) if ((CURRENT == 2)); then _devices; fi;;
|
||||
set-sink-input-volume) if ((CURRENT == 2)); then _devices; fi;;
|
||||
set-source-output-volume) if ((CURRENT == 2)); then _devices; fi;;
|
||||
get-sink-mute) if ((CURRENT == 2)); then _devices; fi;;
|
||||
set-sink-mute) _set_sink_mute_parameter;;
|
||||
get-source-mute) if ((CURRENT == 2)); then _devices; fi;;
|
||||
set-source-mute) _set_source_mute_parameter;;
|
||||
set-sink-input-mute) _set_sink_input_mute_parameter;;
|
||||
set-source-output-mute) _set_source_output_mute_parameter;;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
if get_option('client')
|
||||
if zshcompletiondir != 'no'
|
||||
install_data('_pulseaudio', install_dir : zshcompletiondir)
|
||||
endif
|
||||
if zshcompletiondir != 'no'
|
||||
install_data('_pulseaudio', install_dir : zshcompletiondir)
|
||||
endif
|
||||
|
|
|
|||
1
src/.gitignore
vendored
1
src/.gitignore
vendored
|
|
@ -71,7 +71,6 @@ proplist-test
|
|||
queue-test
|
||||
remix-test
|
||||
resampler-test
|
||||
resampler-rewind-test
|
||||
rtpoll-test
|
||||
rtstutter
|
||||
sig2str-test
|
||||
|
|
|
|||
|
|
@ -262,7 +262,7 @@ int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d
|
|||
|
||||
if (optarg) {
|
||||
if (pa_daemon_conf_set_log_level(conf, optarg) < 0) {
|
||||
pa_log(_("--log-level expects log level argument (either numeric in range 0..4 or one of error, warn, notice, info, debug)."));
|
||||
pa_log(_("--log-level expects log level argument (either numeric in range 0..4 or one of debug, info, notice, warn, error)."));
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -171,6 +171,5 @@ load-module module-filter-apply
|
|||
|
||||
### Allow including a default.pa.d directory, which if present, can be used
|
||||
### for additional configuration snippets.
|
||||
### Note that those snippet files must have a .pa file extension, not .conf
|
||||
.nofail
|
||||
.include @PA_DEFAULT_CONFIG_DIR_UNQUOTED@/default.pa.d
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@ executable('pulseaudio',
|
|||
install_rpath : privlibdir,
|
||||
include_directories : [configinc, topinc],
|
||||
link_args : ['-ffast-math'],
|
||||
link_with : [libpulsecore],
|
||||
dependencies : [ltdl_dep, cap_dep, dbus_dep, libsystemd_dep, dl_dep, libintl_dep, platform_dep, platform_socket_dep, libpulsecommon_dep, libpulse_dep],
|
||||
link_with : [libpulsecore, libpulsecommon, libpulse],
|
||||
dependencies : [ltdl_dep, cap_dep, dbus_dep, libsystemd_dep, dl_dep, libintl_dep, platform_dep, platform_socket_dep],
|
||||
c_args : pa_c_args,
|
||||
)
|
||||
|
||||
|
|
@ -141,7 +141,7 @@ custom_target('system.pa',
|
|||
|
||||
if dbus_dep.found()
|
||||
install_data('pulseaudio-system.conf',
|
||||
install_dir : join_paths(datadir, 'dbus-1', 'system.d')
|
||||
install_dir : join_paths(sysconfdir, 'dbus-1', 'system.d')
|
||||
)
|
||||
endif
|
||||
|
||||
|
|
|
|||
|
|
@ -69,6 +69,5 @@ load-module module-position-event-sounds
|
|||
|
||||
### Allow including a system.pa.d directory, which if present, can be used
|
||||
### for additional configuration snippets.
|
||||
### Note that those snippet files must have a .pa file extension, not .conf
|
||||
.nofail
|
||||
.include @PA_DEFAULT_CONFIG_DIR_UNQUOTED@/system.pa.d
|
||||
|
|
|
|||
|
|
@ -57,12 +57,12 @@ libpulsecommon_sources = [
|
|||
'pulsecore/shm.c',
|
||||
'pulsecore/bitset.c',
|
||||
'pulsecore/socket-client.c',
|
||||
'pulsecore/socket-server.c',
|
||||
'pulsecore/socket-util.c',
|
||||
'pulsecore/strbuf.c',
|
||||
'pulsecore/strlist.c',
|
||||
'pulsecore/tagstruct.c',
|
||||
'pulsecore/time-smoother.c',
|
||||
'pulsecore/time-smoother_2.c',
|
||||
'pulsecore/tokenizer.c',
|
||||
'pulsecore/usergroup.c',
|
||||
'pulsecore/sndfile-util.c',
|
||||
|
|
@ -136,13 +136,13 @@ libpulsecommon_headers = [
|
|||
'pulsecore/shm.h',
|
||||
'pulsecore/bitset.h',
|
||||
'pulsecore/socket-client.h',
|
||||
'pulsecore/socket-server.h',
|
||||
'pulsecore/socket-util.h',
|
||||
'pulsecore/strbuf.h',
|
||||
'pulsecore/strlist.h',
|
||||
'pulsecore/tagstruct.h',
|
||||
'pulsecore/thread.h',
|
||||
'pulsecore/time-smoother.h',
|
||||
'pulsecore/time-smoother_2.h',
|
||||
'pulsecore/tokenizer.h',
|
||||
'pulsecore/usergroup.h',
|
||||
'pulsecore/sndfile-util.h',
|
||||
|
|
@ -182,47 +182,37 @@ if host_machine.system() == 'windows'
|
|||
else
|
||||
libpulsecommon_sources += [
|
||||
'pulsecore/mutex-posix.c',
|
||||
'pulsecore/poll-posix.c',
|
||||
'pulsecore/thread-posix.c',
|
||||
'pulsecore/semaphore-posix.c',
|
||||
'pulsecore/thread-posix.c'
|
||||
]
|
||||
if host_machine.system() == 'darwin'
|
||||
libpulsecommon_sources += ['pulsecore/semaphore-osx.c']
|
||||
else
|
||||
libpulsecommon_sources += ['pulsecore/semaphore-posix.c']
|
||||
endif
|
||||
endif
|
||||
# FIXME: Do SIMD things
|
||||
|
||||
if not get_option('client')
|
||||
libpulsecommon_dep = cc.find_library('pulsecommon-' + pa_version_major_minor, dirs : privlibdir, required : true)
|
||||
libpulse_dep = dependency('libpulse', required : true)
|
||||
libpulse_simple_dep = dependency('libpulse-simple', required : true)
|
||||
else
|
||||
libpulsecommon = shared_library('pulsecommon-' + pa_version_major_minor,
|
||||
libpulsecommon_sources,
|
||||
libpulsecommon_headers,
|
||||
include_directories : [configinc, topinc],
|
||||
c_args : [pa_c_args],
|
||||
link_args : [nodelete_link_args],
|
||||
install : true,
|
||||
install_dir : privlibdir,
|
||||
dependencies : [
|
||||
libm_dep, thread_dep, dl_dep, shm_dep, iconv_dep, sndfile_dep, dbus_dep,
|
||||
x11_dep, libsystemd_dep, glib_dep.partial_dependency(compile_args: true),
|
||||
gtk_dep.partial_dependency(compile_args: true), asyncns_dep, libintl_dep,
|
||||
platform_dep, platform_socket_dep, execinfo_dep, libatomic_ops_dep,
|
||||
],
|
||||
implicit_include_directories : false)
|
||||
libpulsecommon = shared_library('pulsecommon-' + pa_version_major_minor,
|
||||
libpulsecommon_sources,
|
||||
libpulsecommon_headers,
|
||||
include_directories : [configinc, topinc],
|
||||
c_args : [pa_c_args],
|
||||
link_args : [nodelete_link_args],
|
||||
install : true,
|
||||
install_dir : privlibdir,
|
||||
dependencies : [
|
||||
libm_dep, thread_dep, dl_dep, shm_dep, iconv_dep, sndfile_dep, dbus_dep,
|
||||
x11_dep, libsystemd_dep, glib_dep.partial_dependency(compile_args: true),
|
||||
gtk_dep.partial_dependency(compile_args: true), asyncns_dep, libintl_dep,
|
||||
platform_dep, tcpwrap_dep, platform_socket_dep, execinfo_dep,
|
||||
],
|
||||
implicit_include_directories : false)
|
||||
|
||||
libpulsecommon_dep = declare_dependency(link_with: libpulsecommon)
|
||||
|
||||
subdir('pulse')
|
||||
endif
|
||||
libpulsecommon_dep = declare_dependency(link_with: libpulsecommon)
|
||||
|
||||
subdir('pulse')
|
||||
if get_option('daemon')
|
||||
subdir('pulsecore')
|
||||
subdir('daemon')
|
||||
subdir('modules')
|
||||
endif
|
||||
subdir('tests')
|
||||
if get_option('tests')
|
||||
subdir('tests')
|
||||
endif
|
||||
subdir('utils')
|
||||
|
|
|
|||
|
|
@ -107,15 +107,13 @@ ATTRS{idVendor}=="17cc", ATTRS{idProduct}=="1011", ENV{PULSE_PROFILE_SET}="nativ
|
|||
|
||||
|
||||
ATTRS{idVendor}=="17cc", ATTRS{idProduct}=="1001", ENV{PULSE_PROFILE_SET}="native-instruments-komplete-audio6.conf"
|
||||
# This entry is for the Komplete Audio 6 MK2, which has a different ID, but is functionally identical to the Komplete Audio 6.
|
||||
ATTRS{idVendor}=="17cc", ATTRS{idProduct}=="1870", ENV{PULSE_PROFILE_SET}="native-instruments-komplete-audio6.conf"
|
||||
ATTRS{idVendor}=="17cc", ATTRS{idProduct}=="1021", ENV{PULSE_PROFILE_SET}="native-instruments-traktor-audio10.conf"
|
||||
ATTRS{idVendor}=="0763", ATTRS{idProduct}=="2012", ENV{PULSE_PROFILE_SET}="maudio-fasttrack-pro.conf"
|
||||
ATTRS{idVendor}=="045e", ATTRS{idProduct}=="02bb", ENV{PULSE_PROFILE_SET}="kinect-audio.conf"
|
||||
ATTRS{idVendor}=="041e", ATTRS{idProduct}=="322c", ENV{PULSE_PROFILE_SET}="sb-omni-surround-5.1.conf"
|
||||
ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="4014", ENV{PULSE_PROFILE_SET}="dell-dock-tb16-usb-audio.conf"
|
||||
ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="402e", ENV{PULSE_PROFILE_SET}="dell-dock-tb16-usb-audio.conf"
|
||||
ATTRS{idVendor}=="08bb", ATTRS{idProduct}=="2902", ENV{PULSE_PROFILE_SET}="texas-instruments-pcm2902.conf"
|
||||
ATTRS{idVendor}=="08bb", ATTRS{idProduct}=="2902", ENV{PULSE_PROFILE_SET}="behringer-umc22.conf"
|
||||
ATTRS{idVendor}=="03f0", ATTRS{idProduct}=="0269", ENV{PULSE_PROFILE_SET}="hp-tbt-dock-120w-g2.conf"
|
||||
ATTRS{idVendor}=="03f0", ATTRS{idProduct}=="0567", ENV{PULSE_PROFILE_SET}="hp-tbt-dock-audio-module.conf"
|
||||
|
||||
|
|
@ -125,8 +123,6 @@ ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1260", ENV{PULSE_PROFILE_SET}="usb-g
|
|||
ATTRS{idVendor}=="1038", ATTRS{idProduct}=="12ad", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf"
|
||||
ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1294", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf"
|
||||
ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1730", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf"
|
||||
# ID 1038:1282 is for SteelSeries GameDAC
|
||||
ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1282", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf"
|
||||
# ID 1038:12c4 is for Arctis 9
|
||||
ATTRS{idVendor}=="1038", ATTRS{idProduct}=="12c4", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf"
|
||||
# Lucidsound LS31
|
||||
|
|
@ -168,16 +164,6 @@ ATTRS{idVendor}=="1395", ATTRS{idProduct}=="00a0", ENV{PULSE_PROFILE_SET}="sennh
|
|||
ATTRS{idVendor}=="1395", ATTRS{idProduct}=="005f", ENV{PULSE_PROFILE_SET}="sennheiser-gsx.conf"
|
||||
ATTRS{idVendor}=="1395", ATTRS{idProduct}=="00a1", ENV{PULSE_PROFILE_SET}="sennheiser-gsx.conf"
|
||||
|
||||
# Sennheiser GSA 70 wireless USB dongle for GSP 670
|
||||
ATTRS{idVendor}=="1395", ATTRS{idProduct}=="0089", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf"
|
||||
# EPOS GSA 70 wireless USB dongle for GSP 670 (Sennheiser GSA 70 with updated firmware)
|
||||
ATTRS{idVendor}=="1395", ATTRS{idProduct}=="0300", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf"
|
||||
# Sennheiser GSP 670 USB headset
|
||||
ATTRS{idVendor}=="1395", ATTRS{idProduct}=="008a", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf"
|
||||
|
||||
# Asus Xonar SE
|
||||
ATTRS{idVendor}=="0b05", ATTRS{idProduct}=="189d", ENV{PULSE_PROFILE_SET}="asus-xonar-se.conf"
|
||||
|
||||
GOTO="pulseaudio_end"
|
||||
|
||||
LABEL="pulseaudio_check_pci"
|
||||
|
|
|
|||
|
|
@ -2838,7 +2838,7 @@ static int path_verify(pa_alsa_path *p) {
|
|||
if (p->device_port_type == PA_DEVICE_PORT_TYPE_UNKNOWN)
|
||||
p->device_port_type = map->type;
|
||||
if (!p->description)
|
||||
p->description = pa_xstrdup(_(map->description));
|
||||
p->description = pa_xstrdup(map->description);
|
||||
}
|
||||
|
||||
if (!p->description) {
|
||||
|
|
@ -2851,44 +2851,41 @@ static int path_verify(pa_alsa_path *p) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static char *get_data_path(const char *data_dir, const char *data_type, const char *fname) {
|
||||
char *result;
|
||||
static char *get_path_config_path(const char *paths_dir, const char *fname) {
|
||||
char *path_config_path;
|
||||
char *dir;
|
||||
char *data_home;
|
||||
pa_dynarray *data_dirs;
|
||||
|
||||
if (data_dir) {
|
||||
result = pa_maybe_prefix_path(fname, data_dir);
|
||||
if (access(result, R_OK) == 0)
|
||||
return result;
|
||||
if (paths_dir) {
|
||||
path_config_path = pa_maybe_prefix_path(fname, paths_dir);
|
||||
if (access(path_config_path, R_OK) == 0)
|
||||
return path_config_path;
|
||||
else
|
||||
pa_xfree(result);
|
||||
pa_xfree(path_config_path);
|
||||
}
|
||||
|
||||
#ifdef HAVE_RUNNING_FROM_BUILD_TREE
|
||||
if (pa_run_from_build_tree()) {
|
||||
dir = pa_sprintf_malloc(PA_SRCDIR "/modules/alsa/mixer/%s/", data_type);
|
||||
result = pa_maybe_prefix_path(fname, dir);
|
||||
pa_xfree(dir);
|
||||
|
||||
if (access(result, R_OK) == 0)
|
||||
return result;
|
||||
path_config_path = pa_maybe_prefix_path(fname, PA_SRCDIR "/modules/alsa/mixer/paths/");
|
||||
if (access(path_config_path, R_OK) == 0)
|
||||
return path_config_path;
|
||||
else
|
||||
pa_xfree(result);
|
||||
pa_xfree(path_config_path);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pa_get_data_home_dir(&data_home) == 0) {
|
||||
dir = pa_sprintf_malloc("%s" PA_PATH_SEP "alsa-mixer" PA_PATH_SEP "%s", data_home, data_type);
|
||||
dir = pa_sprintf_malloc("%s" PA_PATH_SEP "alsa-mixer" PA_PATH_SEP "paths", data_home);
|
||||
pa_xfree(data_home);
|
||||
|
||||
result = pa_maybe_prefix_path(fname, dir);
|
||||
path_config_path = pa_maybe_prefix_path(fname, dir);
|
||||
pa_xfree(dir);
|
||||
|
||||
if (access(result, R_OK) == 0)
|
||||
return result;
|
||||
if (access(path_config_path, R_OK) == 0)
|
||||
return path_config_path;
|
||||
else
|
||||
pa_xfree(result);
|
||||
pa_xfree(path_config_path);
|
||||
}
|
||||
|
||||
if (pa_get_data_dirs(&data_dirs) == 0) {
|
||||
|
|
@ -2896,27 +2893,24 @@ static char *get_data_path(const char *data_dir, const char *data_type, const ch
|
|||
const char *n;
|
||||
|
||||
PA_DYNARRAY_FOREACH(n, data_dirs, idx) {
|
||||
dir = pa_sprintf_malloc("%s" PA_PATH_SEP "alsa-mixer" PA_PATH_SEP "%s", n, data_type);
|
||||
result = pa_maybe_prefix_path(fname, dir);
|
||||
dir = pa_sprintf_malloc("%s" PA_PATH_SEP "alsa-mixer" PA_PATH_SEP "paths", n);
|
||||
path_config_path = pa_maybe_prefix_path(fname, dir);
|
||||
pa_xfree(dir);
|
||||
|
||||
if (access(result, R_OK) == 0) {
|
||||
if (access(path_config_path, R_OK) == 0) {
|
||||
pa_dynarray_free(data_dirs);
|
||||
return result;
|
||||
return path_config_path;
|
||||
}
|
||||
else {
|
||||
pa_xfree(result);
|
||||
pa_xfree(path_config_path);
|
||||
}
|
||||
}
|
||||
|
||||
pa_dynarray_free(data_dirs);
|
||||
}
|
||||
|
||||
dir = pa_sprintf_malloc(PA_ALSA_DATA_DIR PA_PATH_SEP "%s", data_type);
|
||||
result = pa_maybe_prefix_path(fname, dir);
|
||||
pa_xfree(dir);
|
||||
|
||||
return result;
|
||||
path_config_path = pa_maybe_prefix_path(fname, PA_ALSA_PATHS_DIR);
|
||||
return path_config_path;
|
||||
}
|
||||
|
||||
pa_alsa_path* pa_alsa_path_new(const char *paths_dir, const char *fname, pa_alsa_direction_t direction) {
|
||||
|
|
@ -2983,7 +2977,7 @@ pa_alsa_path* pa_alsa_path_new(const char *paths_dir, const char *fname, pa_alsa
|
|||
items[2].data = &p->description;
|
||||
items[3].data = &mute_during_activation;
|
||||
|
||||
fn = get_data_path(paths_dir, "paths", fname);
|
||||
fn = get_path_config_path(paths_dir, fname);
|
||||
|
||||
pa_log_info("Loading path config: %s", fn);
|
||||
|
||||
|
|
@ -4977,9 +4971,11 @@ pa_alsa_profile_set* pa_alsa_profile_set_new(const char *fname, const pa_channel
|
|||
if (!fname)
|
||||
fname = "default.conf";
|
||||
|
||||
fn = get_data_path(NULL, "profile-sets", fname);
|
||||
|
||||
pa_log_info("Loading profile set: %s", fn);
|
||||
fn = pa_maybe_prefix_path(fname,
|
||||
#ifdef HAVE_RUNNING_FROM_BUILD_TREE
|
||||
pa_run_from_build_tree() ? PA_SRCDIR "/modules/alsa/mixer/profile-sets/" :
|
||||
#endif
|
||||
PA_ALSA_PROFILE_SETS_DIR);
|
||||
|
||||
r = pa_config_parse(fn, NULL, items, NULL, false, ps);
|
||||
pa_xfree(fn);
|
||||
|
|
@ -5078,7 +5074,7 @@ static snd_pcm_t* mapping_open_pcm(pa_alsa_mapping *m,
|
|||
handle = pa_alsa_open_by_template(
|
||||
m->device_strings, dev_id, NULL, &try_ss,
|
||||
&try_map, mode, &try_period_size,
|
||||
&try_buffer_size, 0, NULL, NULL, NULL, NULL, exact_channels);
|
||||
&try_buffer_size, 0, NULL, NULL, exact_channels);
|
||||
if (handle && !exact_channels && m->channel_map.channels != try_map.channels) {
|
||||
char buf[PA_CHANNEL_MAP_SNPRINT_MAX];
|
||||
pa_log_debug("Channel map for mapping '%s' permanently changed to '%s'", m->name,
|
||||
|
|
|
|||
|
|
@ -103,8 +103,8 @@ struct pa_alsa_setting {
|
|||
|
||||
/* An entry for one ALSA mixer */
|
||||
struct pa_alsa_mixer {
|
||||
struct pa_alsa_mixer *alias;
|
||||
snd_mixer_t *mixer_handle;
|
||||
int card_index;
|
||||
pa_alsa_fdlist *fdl;
|
||||
bool used_for_probe_only:1;
|
||||
};
|
||||
|
|
@ -318,7 +318,7 @@ struct pa_alsa_mapping {
|
|||
pa_sink *sink;
|
||||
pa_source *source;
|
||||
|
||||
/* ucm device context */
|
||||
/* ucm device context*/
|
||||
pa_alsa_ucm_mapping_context ucm_context;
|
||||
};
|
||||
|
||||
|
|
@ -342,9 +342,6 @@ struct pa_alsa_profile {
|
|||
|
||||
pa_idxset *input_mappings;
|
||||
pa_idxset *output_mappings;
|
||||
|
||||
/* ucm device context */
|
||||
pa_alsa_ucm_profile_context ucm_context;
|
||||
};
|
||||
|
||||
struct pa_alsa_decibel_fix {
|
||||
|
|
|
|||
|
|
@ -52,12 +52,7 @@
|
|||
#include <pulsecore/thread.h>
|
||||
#include <pulsecore/thread-mq.h>
|
||||
#include <pulsecore/rtpoll.h>
|
||||
|
||||
#ifdef USE_SMOOTHER_2
|
||||
#include <pulsecore/time-smoother_2.h>
|
||||
#else
|
||||
#include <pulsecore/time-smoother.h>
|
||||
#endif
|
||||
|
||||
#include <modules/reserve-wrap.h>
|
||||
|
||||
|
|
@ -83,15 +78,11 @@
|
|||
#define TSCHED_MIN_SLEEP_USEC (10*PA_USEC_PER_MSEC) /* 10ms -- Sleep at least 10ms on each iteration */
|
||||
#define TSCHED_MIN_WAKEUP_USEC (4*PA_USEC_PER_MSEC) /* 4ms -- Wakeup at least this long before the buffer runs empty*/
|
||||
|
||||
#ifdef USE_SMOOTHER_2
|
||||
#define SMOOTHER_WINDOW_USEC (15*PA_USEC_PER_SEC) /* 15s -- smoother windows size */
|
||||
#else
|
||||
#define SMOOTHER_WINDOW_USEC (10*PA_USEC_PER_SEC) /* 10s -- smoother windows size */
|
||||
#define SMOOTHER_ADJUST_USEC (1*PA_USEC_PER_SEC) /* 1s -- smoother adjust time */
|
||||
|
||||
#define SMOOTHER_MIN_INTERVAL (2*PA_USEC_PER_MSEC) /* 2ms -- min smoother update interval */
|
||||
#define SMOOTHER_MAX_INTERVAL (200*PA_USEC_PER_MSEC) /* 200ms -- max smoother update interval */
|
||||
#endif
|
||||
|
||||
#define VOLUME_ACCURACY (PA_VOLUME_NORM/100) /* don't require volume adjustments to be perfectly correct. don't necessarily extend granularity in software unless the differences get greater than this level */
|
||||
|
||||
|
|
@ -165,18 +156,11 @@ struct userdata {
|
|||
|
||||
pa_rtpoll_item *alsa_rtpoll_item;
|
||||
|
||||
#ifdef USE_SMOOTHER_2
|
||||
pa_smoother_2 *smoother;
|
||||
#else
|
||||
pa_smoother *smoother;
|
||||
#endif
|
||||
uint64_t write_count;
|
||||
uint64_t since_start;
|
||||
|
||||
#ifndef USE_SMOOTHER_2
|
||||
pa_usec_t smoother_interval;
|
||||
pa_usec_t last_smoother_update;
|
||||
#endif
|
||||
|
||||
pa_idxset *formats;
|
||||
|
||||
|
|
@ -496,13 +480,9 @@ static void hw_sleep_time(struct userdata *u, pa_usec_t *sleep_usec, pa_usec_t*p
|
|||
/* Reset smoother and counters */
|
||||
static void reset_vars(struct userdata *u) {
|
||||
|
||||
#ifdef USE_SMOOTHER_2
|
||||
pa_smoother_2_reset(u->smoother, pa_rtclock_now());
|
||||
#else
|
||||
pa_smoother_reset(u->smoother, pa_rtclock_now(), true);
|
||||
u->smoother_interval = SMOOTHER_MIN_INTERVAL;
|
||||
u->last_smoother_update = 0;
|
||||
#endif
|
||||
|
||||
u->first = true;
|
||||
u->since_start = 0;
|
||||
|
|
@ -975,10 +955,7 @@ static void update_smoother(struct userdata *u) {
|
|||
snd_pcm_sframes_t delay = 0;
|
||||
int64_t position;
|
||||
int err;
|
||||
pa_usec_t now1 = 0;
|
||||
#ifndef USE_SMOOTHER_2
|
||||
pa_usec_t now2;
|
||||
#endif
|
||||
pa_usec_t now1 = 0, now2;
|
||||
snd_pcm_status_t *status;
|
||||
snd_htimestamp_t htstamp = { 0, 0 };
|
||||
|
||||
|
|
@ -1001,16 +978,13 @@ static void update_smoother(struct userdata *u) {
|
|||
if (now1 <= 0)
|
||||
now1 = pa_rtclock_now();
|
||||
|
||||
position = (int64_t) u->write_count - ((int64_t) delay * (int64_t) u->frame_size);
|
||||
|
||||
#ifdef USE_SMOOTHER_2
|
||||
pa_smoother_2_put(u->smoother, now1, position);
|
||||
#else
|
||||
/* check if the time since the last update is bigger than the interval */
|
||||
if (u->last_smoother_update > 0)
|
||||
if (u->last_smoother_update + u->smoother_interval > now1)
|
||||
return;
|
||||
|
||||
position = (int64_t) u->write_count - ((int64_t) delay * (int64_t) u->frame_size);
|
||||
|
||||
if (PA_UNLIKELY(position < 0))
|
||||
position = 0;
|
||||
|
||||
|
|
@ -1021,26 +995,18 @@ static void update_smoother(struct userdata *u) {
|
|||
u->last_smoother_update = now1;
|
||||
/* exponentially increase the update interval up to the MAX limit */
|
||||
u->smoother_interval = PA_MIN (u->smoother_interval * 2, SMOOTHER_MAX_INTERVAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int64_t sink_get_latency(struct userdata *u) {
|
||||
int64_t delay;
|
||||
pa_usec_t now1;
|
||||
#ifndef USE_SMOOTHER_2
|
||||
pa_usec_t now2;
|
||||
#endif
|
||||
pa_usec_t now1, now2;
|
||||
|
||||
pa_assert(u);
|
||||
|
||||
now1 = pa_rtclock_now();
|
||||
#ifdef USE_SMOOTHER_2
|
||||
delay = pa_smoother_2_get_delay(u->smoother, now1, u->write_count);
|
||||
#else
|
||||
now2 = pa_smoother_get(u->smoother, now1);
|
||||
|
||||
delay = (int64_t) pa_bytes_to_usec(u->write_count, &u->sink->sample_spec) - (int64_t) now2;
|
||||
#endif
|
||||
|
||||
if (u->memchunk.memblock)
|
||||
delay += pa_bytes_to_usec(u->memchunk.length, &u->sink->sample_spec);
|
||||
|
|
@ -1070,11 +1036,7 @@ static void suspend(struct userdata *u) {
|
|||
if (!u->pcm_handle)
|
||||
return;
|
||||
|
||||
#ifdef USE_SMOOTHER_2
|
||||
pa_smoother_2_pause(u->smoother, pa_rtclock_now());
|
||||
#else
|
||||
pa_smoother_pause(u->smoother, pa_rtclock_now());
|
||||
#endif
|
||||
|
||||
/* Close PCM device */
|
||||
close_pcm(u);
|
||||
|
|
@ -1532,7 +1494,6 @@ static void sink_set_volume_cb(pa_sink *s) {
|
|||
pa_cvolume r;
|
||||
char volume_buf[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
|
||||
bool deferred_volume = !!(s->flags & PA_SINK_DEFERRED_VOLUME);
|
||||
bool write_to_hw = !deferred_volume;
|
||||
|
||||
pa_assert(u);
|
||||
pa_assert(u->mixer_path);
|
||||
|
|
@ -1541,14 +1502,7 @@ static void sink_set_volume_cb(pa_sink *s) {
|
|||
/* Shift up by the base volume */
|
||||
pa_sw_cvolume_divide_scalar(&r, &s->real_volume, s->base_volume);
|
||||
|
||||
/* If the set_volume() is called because of ucm active_port changing, the
|
||||
* volume should be written to hw immediately, otherwise this volume will be
|
||||
* overridden by calling get_volume_cb() which is called by
|
||||
* _disdev/_enadev() -> io_mixer_callback() */
|
||||
if (u->ucm_context && s->port_changing)
|
||||
write_to_hw = true;
|
||||
|
||||
if (pa_alsa_path_set_volume(u->mixer_path, u->mixer_handle, &s->channel_map, &r, deferred_volume, write_to_hw) < 0)
|
||||
if (pa_alsa_path_set_volume(u->mixer_path, u->mixer_handle, &s->channel_map, &r, deferred_volume, !deferred_volume) < 0)
|
||||
return;
|
||||
|
||||
/* Shift down by the base volume, so that 0dB becomes maximum volume */
|
||||
|
|
@ -1721,7 +1675,7 @@ static int sink_set_port_ucm_cb(pa_sink *s, pa_device_port *p) {
|
|||
else
|
||||
sync_mixer(u, p);
|
||||
|
||||
return pa_alsa_ucm_set_port(u->ucm_context, p);
|
||||
return pa_alsa_ucm_set_port(u->ucm_context, p, true);
|
||||
}
|
||||
|
||||
static int sink_set_port_cb(pa_sink *s, pa_device_port *p) {
|
||||
|
|
@ -1822,22 +1776,12 @@ static void sink_reconfigure_cb(pa_sink *s, pa_sample_spec *spec, bool passthrou
|
|||
int i;
|
||||
bool format_supported = false;
|
||||
bool rate_supported = false;
|
||||
#ifdef USE_SMOOTHER_2
|
||||
pa_sample_spec effective_spec;
|
||||
#endif
|
||||
|
||||
pa_assert(u);
|
||||
|
||||
#ifdef USE_SMOOTHER_2
|
||||
effective_spec.channels = s->sample_spec.channels;
|
||||
#endif
|
||||
|
||||
for (i = 0; u->supported_formats[i] != PA_SAMPLE_MAX; i++) {
|
||||
if (u->supported_formats[i] == spec->format) {
|
||||
pa_sink_set_sample_format(u->sink, spec->format);
|
||||
#ifdef USE_SMOOTHER_2
|
||||
effective_spec.format = spec->format;
|
||||
#endif
|
||||
format_supported = true;
|
||||
break;
|
||||
}
|
||||
|
|
@ -1847,17 +1791,11 @@ static void sink_reconfigure_cb(pa_sink *s, pa_sample_spec *spec, bool passthrou
|
|||
pa_log_info("Sink does not support sample format of %s, set it to a verified value",
|
||||
pa_sample_format_to_string(spec->format));
|
||||
pa_sink_set_sample_format(u->sink, u->verified_sample_spec.format);
|
||||
#ifdef USE_SMOOTHER_2
|
||||
effective_spec.format = u->verified_sample_spec.format;
|
||||
#endif
|
||||
}
|
||||
|
||||
for (i = 0; u->supported_rates[i]; i++) {
|
||||
if (u->supported_rates[i] == spec->rate) {
|
||||
pa_sink_set_sample_rate(u->sink, spec->rate);
|
||||
#ifdef USE_SMOOTHER_2
|
||||
effective_spec.rate = spec->rate;
|
||||
#endif
|
||||
rate_supported = true;
|
||||
break;
|
||||
}
|
||||
|
|
@ -1866,15 +1804,8 @@ static void sink_reconfigure_cb(pa_sink *s, pa_sample_spec *spec, bool passthrou
|
|||
if (!rate_supported) {
|
||||
pa_log_info("Sink does not support sample rate of %u, set it to a verified value", spec->rate);
|
||||
pa_sink_set_sample_rate(u->sink, u->verified_sample_spec.rate);
|
||||
#ifdef USE_SMOOTHER_2
|
||||
effective_spec.rate = u->verified_sample_spec.rate;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef USE_SMOOTHER_2
|
||||
pa_smoother_2_set_sample_spec(u->smoother, pa_rtclock_now(), &effective_spec);
|
||||
#endif
|
||||
|
||||
/* Passthrough status change is handled during unsuspend */
|
||||
}
|
||||
|
||||
|
|
@ -2008,11 +1939,7 @@ static void thread_func(void *userdata) {
|
|||
pa_log_info("Starting playback.");
|
||||
snd_pcm_start(u->pcm_handle);
|
||||
|
||||
#ifdef USE_SMOOTHER_2
|
||||
pa_smoother_2_resume(u->smoother, pa_rtclock_now());
|
||||
#else
|
||||
pa_smoother_resume(u->smoother, pa_rtclock_now(), true);
|
||||
#endif
|
||||
|
||||
u->first = false;
|
||||
}
|
||||
|
|
@ -2046,11 +1973,7 @@ static void thread_func(void *userdata) {
|
|||
|
||||
/* Convert from the sound card time domain to the
|
||||
* system time domain */
|
||||
#ifdef USE_SMOOTHER_2
|
||||
cusec = pa_smoother_2_translate(u->smoother, sleep_usec);
|
||||
#else
|
||||
cusec = pa_smoother_translate(u->smoother, pa_rtclock_now(), sleep_usec);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_TIMING
|
||||
pa_log_debug("Waking up in %0.2fms (system clock).", (double) cusec / PA_USEC_PER_MSEC);
|
||||
|
|
@ -2190,7 +2113,8 @@ static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char
|
|||
u->mixers = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func,
|
||||
NULL, (pa_free_cb_t) pa_alsa_mixer_free);
|
||||
|
||||
mdev = mapping ? pa_proplist_gets(mapping->proplist, "alsa.mixer_device") : NULL;
|
||||
if (mapping)
|
||||
mdev = pa_proplist_gets(mapping->proplist, "alsa.mixer_device");
|
||||
if (mdev) {
|
||||
u->mixer_handle = pa_alsa_open_mixer_by_name(u->mixers, mdev, true);
|
||||
} else {
|
||||
|
|
@ -2239,7 +2163,7 @@ static int setup_mixer(struct userdata *u, bool ignore_dB) {
|
|||
* will be NULL, but the UCM device enable sequence will still need to be
|
||||
* executed. */
|
||||
if (u->sink->active_port && u->ucm_context) {
|
||||
if (pa_alsa_ucm_set_port(u->ucm_context, u->sink->active_port) < 0)
|
||||
if (pa_alsa_ucm_set_port(u->ucm_context, u->sink->active_port, true) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -2350,11 +2274,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
|
|||
bool volume_is_set;
|
||||
bool mute_is_set;
|
||||
pa_alsa_profile_set *profile_set = NULL;
|
||||
void *state = NULL;
|
||||
#ifdef USE_SMOOTHER_2
|
||||
snd_pcm_info_t* pcm_info;
|
||||
const char *id;
|
||||
#endif
|
||||
void *state;
|
||||
|
||||
pa_assert(m);
|
||||
pa_assert(ma);
|
||||
|
|
@ -2467,7 +2387,6 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
|
|||
goto fail;
|
||||
}
|
||||
|
||||
#ifndef USE_SMOOTHER_2
|
||||
u->smoother = pa_smoother_new(
|
||||
SMOOTHER_ADJUST_USEC,
|
||||
SMOOTHER_WINDOW_USEC,
|
||||
|
|
@ -2477,7 +2396,6 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
|
|||
pa_rtclock_now(),
|
||||
true);
|
||||
u->smoother_interval = SMOOTHER_MIN_INTERVAL;
|
||||
#endif
|
||||
|
||||
/* use ucm */
|
||||
if (mapping && mapping->ucm_context.ucm)
|
||||
|
|
@ -2527,9 +2445,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
|
|||
&ss, &map,
|
||||
SND_PCM_STREAM_PLAYBACK,
|
||||
&period_frames, &buffer_frames, tsched_frames,
|
||||
&b, &d,
|
||||
&u->supported_formats, &u->supported_rates,
|
||||
mapping)))
|
||||
&b, &d, mapping)))
|
||||
goto fail;
|
||||
|
||||
} else if ((dev_id = pa_modargs_get_value(ma, "device_id", NULL))) {
|
||||
|
|
@ -2543,9 +2459,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
|
|||
&ss, &map,
|
||||
SND_PCM_STREAM_PLAYBACK,
|
||||
&period_frames, &buffer_frames, tsched_frames,
|
||||
&b, &d,
|
||||
&u->supported_formats, &u->supported_rates,
|
||||
profile_set, &mapping)))
|
||||
&b, &d, profile_set, &mapping)))
|
||||
goto fail;
|
||||
|
||||
} else {
|
||||
|
|
@ -2556,9 +2470,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
|
|||
&ss, &map,
|
||||
SND_PCM_STREAM_PLAYBACK,
|
||||
&period_frames, &buffer_frames, tsched_frames,
|
||||
&b, &d,
|
||||
&u->supported_formats, &u->supported_rates,
|
||||
false)))
|
||||
&b, &d, false)))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
|
@ -2604,11 +2516,13 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
|
|||
|
||||
u->verified_sample_spec = ss;
|
||||
|
||||
u->supported_formats = pa_alsa_get_supported_formats(u->pcm_handle, ss.format);
|
||||
if (!u->supported_formats) {
|
||||
pa_log_error("Failed to find any supported sample formats.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
u->supported_rates = pa_alsa_get_supported_rates(u->pcm_handle, ss.rate);
|
||||
if (!u->supported_rates) {
|
||||
pa_log_error("Failed to find any supported sample rates.");
|
||||
goto fail;
|
||||
|
|
@ -2692,25 +2606,6 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
|
|||
goto fail;
|
||||
}
|
||||
|
||||
#ifdef USE_SMOOTHER_2
|
||||
u->smoother = pa_smoother_2_new(SMOOTHER_WINDOW_USEC, pa_rtclock_now(), frame_size, u->sink->sample_spec.rate);
|
||||
|
||||
/* Check if this is an USB device, see alsa-util.c
|
||||
* USB devices unfortunately need some special handling */
|
||||
snd_pcm_info_alloca(&pcm_info);
|
||||
if (snd_pcm_info(u->pcm_handle, pcm_info) == 0 &&
|
||||
(id = snd_pcm_info_get_id(pcm_info))) {
|
||||
if (pa_streq(id, "USB Audio")) {
|
||||
uint32_t hack_threshold;
|
||||
/* USB device, set hack parameter */
|
||||
hack_threshold = 2000;
|
||||
if (!u->use_tsched)
|
||||
hack_threshold = 1000;
|
||||
pa_smoother_2_usb_hack_enable(u->smoother, true, hack_threshold);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (u->ucm_context) {
|
||||
pa_device_port *port;
|
||||
unsigned h_prio = 0;
|
||||
|
|
@ -2914,11 +2809,7 @@ static void userdata_free(struct userdata *u) {
|
|||
pa_hashmap_free(u->mixers);
|
||||
|
||||
if (u->smoother)
|
||||
#ifdef USE_SMOOTHER_2
|
||||
pa_smoother_2_free(u->smoother);
|
||||
#else
|
||||
pa_smoother_free(u->smoother);
|
||||
#endif
|
||||
|
||||
if (u->formats)
|
||||
pa_idxset_free(u->formats, (pa_free_cb_t) pa_format_info_free);
|
||||
|
|
|
|||
|
|
@ -47,12 +47,7 @@
|
|||
#include <pulsecore/thread.h>
|
||||
#include <pulsecore/thread-mq.h>
|
||||
#include <pulsecore/rtpoll.h>
|
||||
|
||||
#ifdef USE_SMOOTHER_2
|
||||
#include <pulsecore/time-smoother_2.h>
|
||||
#else
|
||||
#include <pulsecore/time-smoother.h>
|
||||
#endif
|
||||
|
||||
#include <modules/reserve-wrap.h>
|
||||
|
||||
|
|
@ -76,15 +71,11 @@
|
|||
#define TSCHED_MIN_SLEEP_USEC (10*PA_USEC_PER_MSEC) /* 10ms */
|
||||
#define TSCHED_MIN_WAKEUP_USEC (4*PA_USEC_PER_MSEC) /* 4ms */
|
||||
|
||||
#ifdef USE_SMOOTHER_2
|
||||
#define SMOOTHER_WINDOW_USEC (15*PA_USEC_PER_SEC) /* 15s */
|
||||
#else
|
||||
#define SMOOTHER_WINDOW_USEC (10*PA_USEC_PER_SEC) /* 10s */
|
||||
#define SMOOTHER_ADJUST_USEC (1*PA_USEC_PER_SEC) /* 1s */
|
||||
|
||||
#define SMOOTHER_MIN_INTERVAL (2*PA_USEC_PER_MSEC) /* 2ms */
|
||||
#define SMOOTHER_MAX_INTERVAL (200*PA_USEC_PER_MSEC) /* 200ms */
|
||||
#endif
|
||||
|
||||
#define VOLUME_ACCURACY (PA_VOLUME_NORM/100)
|
||||
|
||||
|
|
@ -149,17 +140,10 @@ struct userdata {
|
|||
|
||||
pa_rtpoll_item *alsa_rtpoll_item;
|
||||
|
||||
#ifdef USE_SMOOTHER_2
|
||||
pa_smoother_2 *smoother;
|
||||
#else
|
||||
pa_smoother *smoother;
|
||||
#endif
|
||||
uint64_t read_count;
|
||||
|
||||
#ifndef USE_SMOOTHER_2
|
||||
pa_usec_t smoother_interval;
|
||||
pa_usec_t last_smoother_update;
|
||||
#endif
|
||||
|
||||
pa_reserve_wrapper *reserve;
|
||||
pa_hook_slot *reserve_slot;
|
||||
|
|
@ -468,13 +452,9 @@ static void hw_sleep_time(struct userdata *u, pa_usec_t *sleep_usec, pa_usec_t*p
|
|||
/* Reset smoother and counters */
|
||||
static void reset_vars(struct userdata *u) {
|
||||
|
||||
#ifdef USE_SMOOTHER_2
|
||||
pa_smoother_2_reset(u->smoother, pa_rtclock_now());
|
||||
#else
|
||||
pa_smoother_reset(u->smoother, pa_rtclock_now(), true);
|
||||
u->smoother_interval = SMOOTHER_MIN_INTERVAL;
|
||||
u->last_smoother_update = 0;
|
||||
#endif
|
||||
|
||||
u->read_count = 0;
|
||||
u->first = true;
|
||||
|
|
@ -482,12 +462,7 @@ static void reset_vars(struct userdata *u) {
|
|||
|
||||
/* Called from IO context */
|
||||
static void close_pcm(struct userdata *u) {
|
||||
|
||||
#ifdef USE_SMOOTHER_2
|
||||
pa_smoother_2_pause(u->smoother, pa_rtclock_now());
|
||||
#else
|
||||
pa_smoother_pause(u->smoother, pa_rtclock_now());
|
||||
#endif
|
||||
|
||||
/* Let's suspend */
|
||||
snd_pcm_close(u->pcm_handle);
|
||||
|
|
@ -902,10 +877,7 @@ static void update_smoother(struct userdata *u) {
|
|||
snd_pcm_sframes_t delay = 0;
|
||||
uint64_t position;
|
||||
int err;
|
||||
pa_usec_t now1 = 0;
|
||||
#ifndef USE_SMOOTHER_2
|
||||
pa_usec_t now2;
|
||||
#endif
|
||||
pa_usec_t now1 = 0, now2;
|
||||
snd_pcm_status_t *status;
|
||||
snd_htimestamp_t htstamp = { 0, 0 };
|
||||
|
||||
|
|
@ -928,16 +900,12 @@ static void update_smoother(struct userdata *u) {
|
|||
if (now1 <= 0)
|
||||
now1 = pa_rtclock_now();
|
||||
|
||||
position = u->read_count + ((uint64_t) delay * (uint64_t) u->frame_size);
|
||||
|
||||
#ifdef USE_SMOOTHER_2
|
||||
pa_smoother_2_put(u->smoother, now1, position);
|
||||
#else
|
||||
/* check if the time since the last update is bigger than the interval */
|
||||
if (u->last_smoother_update > 0)
|
||||
if (u->last_smoother_update + u->smoother_interval > now1)
|
||||
return;
|
||||
|
||||
position = u->read_count + ((uint64_t) delay * (uint64_t) u->frame_size);
|
||||
now2 = pa_bytes_to_usec(position, &u->source->sample_spec);
|
||||
|
||||
pa_smoother_put(u->smoother, now1, now2);
|
||||
|
|
@ -945,27 +913,18 @@ static void update_smoother(struct userdata *u) {
|
|||
u->last_smoother_update = now1;
|
||||
/* exponentially increase the update interval up to the MAX limit */
|
||||
u->smoother_interval = PA_MIN (u->smoother_interval * 2, SMOOTHER_MAX_INTERVAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int64_t source_get_latency(struct userdata *u) {
|
||||
int64_t delay;
|
||||
pa_usec_t now1;
|
||||
#ifndef USE_SMOOTHER_2
|
||||
pa_usec_t now2;
|
||||
#endif
|
||||
pa_usec_t now1, now2;
|
||||
|
||||
pa_assert(u);
|
||||
|
||||
now1 = pa_rtclock_now();
|
||||
|
||||
#ifdef USE_SMOOTHER_2
|
||||
delay = - pa_smoother_2_get_delay(u->smoother, now1, u->read_count);
|
||||
#else
|
||||
now2 = pa_smoother_get(u->smoother, now1);
|
||||
|
||||
delay = (int64_t) now2 - (int64_t) pa_bytes_to_usec(u->read_count, &u->source->sample_spec);
|
||||
#endif
|
||||
|
||||
return delay;
|
||||
}
|
||||
|
|
@ -1406,7 +1365,6 @@ static void source_set_volume_cb(pa_source *s) {
|
|||
pa_cvolume r;
|
||||
char volume_buf[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
|
||||
bool deferred_volume = !!(s->flags & PA_SOURCE_DEFERRED_VOLUME);
|
||||
bool write_to_hw = !deferred_volume;
|
||||
|
||||
pa_assert(u);
|
||||
pa_assert(u->mixer_path);
|
||||
|
|
@ -1415,14 +1373,7 @@ static void source_set_volume_cb(pa_source *s) {
|
|||
/* Shift up by the base volume */
|
||||
pa_sw_cvolume_divide_scalar(&r, &s->real_volume, s->base_volume);
|
||||
|
||||
/* If the set_volume() is called because of ucm active_port changing, the
|
||||
* volume should be written to hw immediately, otherwise this volume will be
|
||||
* overridden by calling get_volume_cb() which is called by
|
||||
* _disdev/_enadev() -> io_mixer_callback() */
|
||||
if (u->ucm_context && s->port_changing)
|
||||
write_to_hw = true;
|
||||
|
||||
if (pa_alsa_path_set_volume(u->mixer_path, u->mixer_handle, &s->channel_map, &r, deferred_volume, write_to_hw) < 0)
|
||||
if (pa_alsa_path_set_volume(u->mixer_path, u->mixer_handle, &s->channel_map, &r, deferred_volume, !deferred_volume) < 0)
|
||||
return;
|
||||
|
||||
/* Shift down by the base volume, so that 0dB becomes maximum volume */
|
||||
|
|
@ -1595,7 +1546,7 @@ static int source_set_port_ucm_cb(pa_source *s, pa_device_port *p) {
|
|||
else
|
||||
sync_mixer(u, p);
|
||||
|
||||
return pa_alsa_ucm_set_port(u->ucm_context, p);
|
||||
return pa_alsa_ucm_set_port(u->ucm_context, p, false);
|
||||
}
|
||||
|
||||
static int source_set_port_cb(pa_source *s, pa_device_port *p) {
|
||||
|
|
@ -1637,22 +1588,12 @@ static void source_reconfigure_cb(pa_source *s, pa_sample_spec *spec, bool passt
|
|||
int i;
|
||||
bool format_supported = false;
|
||||
bool rate_supported = false;
|
||||
#ifdef USE_SMOOTHER_2
|
||||
pa_sample_spec effective_spec;
|
||||
#endif
|
||||
|
||||
pa_assert(u);
|
||||
|
||||
#ifdef USE_SMOOTHER_2
|
||||
effective_spec.channels = s->sample_spec.channels;
|
||||
#endif
|
||||
|
||||
for (i = 0; u->supported_formats[i] != PA_SAMPLE_MAX; i++) {
|
||||
if (u->supported_formats[i] == spec->format) {
|
||||
pa_source_set_sample_format(u->source, spec->format);
|
||||
#ifdef USE_SMOOTHER_2
|
||||
effective_spec.format = spec->format;
|
||||
#endif
|
||||
format_supported = true;
|
||||
break;
|
||||
}
|
||||
|
|
@ -1662,17 +1603,11 @@ static void source_reconfigure_cb(pa_source *s, pa_sample_spec *spec, bool passt
|
|||
pa_log_info("Source does not support sample format of %s, set it to a verified value",
|
||||
pa_sample_format_to_string(spec->format));
|
||||
pa_source_set_sample_format(u->source, u->verified_sample_spec.format);
|
||||
#ifdef USE_SMOOTHER_2
|
||||
effective_spec.format = u->verified_sample_spec.format;
|
||||
#endif
|
||||
}
|
||||
|
||||
for (i = 0; u->supported_rates[i]; i++) {
|
||||
if (u->supported_rates[i] == spec->rate) {
|
||||
pa_source_set_sample_rate(u->source, spec->rate);
|
||||
#ifdef USE_SMOOTHER_2
|
||||
effective_spec.rate = spec->rate;
|
||||
#endif
|
||||
rate_supported = true;
|
||||
break;
|
||||
}
|
||||
|
|
@ -1681,15 +1616,7 @@ static void source_reconfigure_cb(pa_source *s, pa_sample_spec *spec, bool passt
|
|||
if (!rate_supported) {
|
||||
pa_log_info("Source does not support sample rate of %u, set it to a verfied value", spec->rate);
|
||||
pa_source_set_sample_rate(u->source, u->verified_sample_spec.rate);
|
||||
#ifdef USE_SMOOTHER_2
|
||||
effective_spec.rate = u->verified_sample_spec.rate;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef USE_SMOOTHER_2
|
||||
pa_smoother_2_set_sample_spec(u->smoother, pa_rtclock_now(), &effective_spec);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static void thread_func(void *userdata) {
|
||||
|
|
@ -1723,11 +1650,7 @@ static void thread_func(void *userdata) {
|
|||
pa_log_info("Starting capture.");
|
||||
snd_pcm_start(u->pcm_handle);
|
||||
|
||||
#ifdef USE_SMOOTHER_2
|
||||
pa_smoother_2_resume(u->smoother, pa_rtclock_now());
|
||||
#else
|
||||
pa_smoother_resume(u->smoother, pa_rtclock_now(), true);
|
||||
#endif
|
||||
|
||||
u->first = false;
|
||||
}
|
||||
|
|
@ -1755,11 +1678,7 @@ static void thread_func(void *userdata) {
|
|||
|
||||
/* Convert from the sound card time domain to the
|
||||
* system time domain */
|
||||
#ifdef USE_SMOOTHER_2
|
||||
cusec = pa_smoother_2_translate(u->smoother, sleep_usec);
|
||||
#else
|
||||
cusec = pa_smoother_translate(u->smoother, pa_rtclock_now(), sleep_usec);
|
||||
#endif
|
||||
|
||||
/* pa_log_debug("Waking up in %0.2fms (system clock).", (double) cusec / PA_USEC_PER_MSEC); */
|
||||
|
||||
|
|
@ -1894,7 +1813,8 @@ static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char
|
|||
u->mixers = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func,
|
||||
NULL, (pa_free_cb_t) pa_alsa_mixer_free);
|
||||
|
||||
mdev = mapping ? pa_proplist_gets(mapping->proplist, "alsa.mixer_device") : NULL;
|
||||
if (mapping)
|
||||
mdev = pa_proplist_gets(mapping->proplist, "alsa.mixer_device");
|
||||
if (mdev) {
|
||||
u->mixer_handle = pa_alsa_open_mixer_by_name(u->mixers, mdev, false);
|
||||
} else {
|
||||
|
|
@ -1943,7 +1863,7 @@ static int setup_mixer(struct userdata *u, bool ignore_dB) {
|
|||
* will be NULL, but the UCM device enable sequence will still need to be
|
||||
* executed. */
|
||||
if (u->source->active_port && u->ucm_context) {
|
||||
if (pa_alsa_ucm_set_port(u->ucm_context, u->source->active_port) < 0)
|
||||
if (pa_alsa_ucm_set_port(u->ucm_context, u->source->active_port, false) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -2158,7 +2078,6 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
|
|||
goto fail;
|
||||
}
|
||||
|
||||
#ifndef USE_SMOOTHER_2
|
||||
u->smoother = pa_smoother_new(
|
||||
SMOOTHER_ADJUST_USEC,
|
||||
SMOOTHER_WINDOW_USEC,
|
||||
|
|
@ -2168,7 +2087,6 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
|
|||
pa_rtclock_now(),
|
||||
true);
|
||||
u->smoother_interval = SMOOTHER_MIN_INTERVAL;
|
||||
#endif
|
||||
|
||||
/* use ucm */
|
||||
if (mapping && mapping->ucm_context.ucm)
|
||||
|
|
@ -2218,7 +2136,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
|
|||
&ss, &map,
|
||||
SND_PCM_STREAM_CAPTURE,
|
||||
&period_frames, &buffer_frames, tsched_frames,
|
||||
&b, &d, &u->supported_formats, &u->supported_rates, mapping)))
|
||||
&b, &d, mapping)))
|
||||
goto fail;
|
||||
|
||||
} else if ((dev_id = pa_modargs_get_value(ma, "device_id", NULL))) {
|
||||
|
|
@ -2232,7 +2150,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
|
|||
&ss, &map,
|
||||
SND_PCM_STREAM_CAPTURE,
|
||||
&period_frames, &buffer_frames, tsched_frames,
|
||||
&b, &d, &u->supported_formats, &u->supported_rates, profile_set, &mapping)))
|
||||
&b, &d, profile_set, &mapping)))
|
||||
goto fail;
|
||||
|
||||
} else {
|
||||
|
|
@ -2243,7 +2161,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
|
|||
&ss, &map,
|
||||
SND_PCM_STREAM_CAPTURE,
|
||||
&period_frames, &buffer_frames, tsched_frames,
|
||||
&b, &d, &u->supported_formats, &u->supported_rates, false)))
|
||||
&b, &d, false)))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
|
@ -2279,11 +2197,13 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
|
|||
|
||||
u->verified_sample_spec = ss;
|
||||
|
||||
u->supported_formats = pa_alsa_get_supported_formats(u->pcm_handle, ss.format);
|
||||
if (!u->supported_formats) {
|
||||
pa_log_error("Failed to find any supported sample formats.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
u->supported_rates = pa_alsa_get_supported_rates(u->pcm_handle, ss.rate);
|
||||
if (!u->supported_rates) {
|
||||
pa_log_error("Failed to find any supported sample rates.");
|
||||
goto fail;
|
||||
|
|
@ -2366,10 +2286,6 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
|
|||
goto fail;
|
||||
}
|
||||
|
||||
#ifdef USE_SMOOTHER_2
|
||||
u->smoother = pa_smoother_2_new(SMOOTHER_WINDOW_USEC, pa_rtclock_now(), frame_size, u->source->sample_spec.rate);
|
||||
#endif
|
||||
|
||||
if (u->ucm_context) {
|
||||
pa_device_port *port;
|
||||
unsigned h_prio = 0;
|
||||
|
|
@ -2531,11 +2447,7 @@ static void userdata_free(struct userdata *u) {
|
|||
pa_hashmap_free(u->mixers);
|
||||
|
||||
if (u->smoother)
|
||||
#ifdef USE_SMOOTHER_2
|
||||
pa_smoother_2_free(u->smoother);
|
||||
#else
|
||||
pa_smoother_free(u->smoother);
|
||||
#endif
|
||||
|
||||
if (u->supported_formats)
|
||||
pa_xfree(u->supported_formats);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -140,13 +140,12 @@ typedef struct pa_alsa_ucm_modifier pa_alsa_ucm_modifier;
|
|||
typedef struct pa_alsa_ucm_device pa_alsa_ucm_device;
|
||||
typedef struct pa_alsa_ucm_config pa_alsa_ucm_config;
|
||||
typedef struct pa_alsa_ucm_mapping_context pa_alsa_ucm_mapping_context;
|
||||
typedef struct pa_alsa_ucm_profile_context pa_alsa_ucm_profile_context;
|
||||
typedef struct pa_alsa_ucm_port_data pa_alsa_ucm_port_data;
|
||||
typedef struct pa_alsa_ucm_volume pa_alsa_ucm_volume;
|
||||
|
||||
int pa_alsa_ucm_query_profiles(pa_alsa_ucm_config *ucm, int card_index);
|
||||
pa_alsa_profile_set* pa_alsa_ucm_add_profile_set(pa_alsa_ucm_config *ucm, pa_channel_map *default_channel_map);
|
||||
int pa_alsa_ucm_set_profile(pa_alsa_ucm_config *ucm, pa_card *card, pa_alsa_profile *new_profile, pa_alsa_profile *old_profile);
|
||||
int pa_alsa_ucm_set_profile(pa_alsa_ucm_config *ucm, pa_card *card, const char *new_profile, const char *old_profile);
|
||||
|
||||
int pa_alsa_ucm_get_verb(snd_use_case_mgr_t *uc_mgr, const char *verb_name, const char *verb_desc, pa_alsa_ucm_verb **p_verb);
|
||||
|
||||
|
|
@ -158,14 +157,14 @@ void pa_alsa_ucm_add_ports(
|
|||
pa_card *card,
|
||||
snd_pcm_t *pcm_handle,
|
||||
bool ignore_dB);
|
||||
void pa_alsa_ucm_add_port(
|
||||
void pa_alsa_ucm_add_ports_combination(
|
||||
pa_hashmap *hash,
|
||||
pa_alsa_ucm_mapping_context *context,
|
||||
bool is_sink,
|
||||
pa_hashmap *ports,
|
||||
pa_card_profile *cp,
|
||||
pa_core *core);
|
||||
int pa_alsa_ucm_set_port(pa_alsa_ucm_mapping_context *context, pa_device_port *port);
|
||||
int pa_alsa_ucm_set_port(pa_alsa_ucm_mapping_context *context, pa_device_port *port, bool is_sink);
|
||||
|
||||
void pa_alsa_ucm_free(pa_alsa_ucm_config *ucm);
|
||||
void pa_alsa_ucm_mapping_context_free(pa_alsa_ucm_mapping_context *context);
|
||||
|
|
@ -222,8 +221,11 @@ struct pa_alsa_ucm_modifier {
|
|||
|
||||
pa_proplist *proplist;
|
||||
|
||||
pa_idxset *conflicting_devices;
|
||||
pa_idxset *supported_devices;
|
||||
int n_confdev;
|
||||
int n_suppdev;
|
||||
|
||||
const char **conflicting_devices;
|
||||
const char **supported_devices;
|
||||
|
||||
pa_direction_t action_direction;
|
||||
|
||||
|
|
@ -251,7 +253,6 @@ struct pa_alsa_ucm_config {
|
|||
pa_core *core;
|
||||
snd_use_case_mgr_t *ucm_mgr;
|
||||
pa_alsa_ucm_verb *active_verb;
|
||||
char *alib_prefix;
|
||||
|
||||
pa_hashmap *mixers;
|
||||
PA_LLIST_HEAD(pa_alsa_ucm_verb, verbs);
|
||||
|
|
@ -262,23 +263,21 @@ struct pa_alsa_ucm_mapping_context {
|
|||
pa_alsa_ucm_config *ucm;
|
||||
pa_direction_t direction;
|
||||
|
||||
pa_alsa_ucm_device *ucm_device;
|
||||
pa_alsa_ucm_modifier *ucm_modifier;
|
||||
};
|
||||
|
||||
struct pa_alsa_ucm_profile_context {
|
||||
pa_alsa_ucm_verb *verb;
|
||||
pa_idxset *ucm_devices;
|
||||
pa_idxset *ucm_modifiers;
|
||||
};
|
||||
|
||||
struct pa_alsa_ucm_port_data {
|
||||
pa_alsa_ucm_config *ucm;
|
||||
pa_device_port *core_port;
|
||||
|
||||
pa_alsa_ucm_device *device;
|
||||
/* A single port will be associated with multiple devices if it represents
|
||||
* a combination of devices. */
|
||||
pa_dynarray *devices; /* pa_alsa_ucm_device */
|
||||
|
||||
/* verb name -> pa_alsa_path for volume control */
|
||||
/* profile name -> pa_alsa_path for volume control */
|
||||
pa_hashmap *paths;
|
||||
/* Current path, set when activating verb */
|
||||
/* Current path, set when activating profile */
|
||||
pa_alsa_path *path;
|
||||
|
||||
/* ELD info */
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@
|
|||
#include <pulsecore/thread.h>
|
||||
#include <pulsecore/conf-parser.h>
|
||||
#include <pulsecore/core-rtclock.h>
|
||||
#include <pulsecore/strbuf.h>
|
||||
|
||||
#include "alsa-util.h"
|
||||
#include "alsa-mixer.h"
|
||||
|
|
@ -523,8 +522,6 @@ snd_pcm_t *pa_alsa_open_by_device_id_auto(
|
|||
snd_pcm_uframes_t tsched_size,
|
||||
bool *use_mmap,
|
||||
bool *use_tsched,
|
||||
pa_sample_format_t **query_supported_formats,
|
||||
unsigned int **query_supported_rates,
|
||||
pa_alsa_profile_set *ps,
|
||||
pa_alsa_mapping **mapping) {
|
||||
|
||||
|
|
@ -563,8 +560,6 @@ snd_pcm_t *pa_alsa_open_by_device_id_auto(
|
|||
tsched_size,
|
||||
use_mmap,
|
||||
use_tsched,
|
||||
query_supported_formats,
|
||||
query_supported_rates,
|
||||
m);
|
||||
|
||||
if (pcm_handle) {
|
||||
|
|
@ -592,8 +587,6 @@ snd_pcm_t *pa_alsa_open_by_device_id_auto(
|
|||
tsched_size,
|
||||
use_mmap,
|
||||
use_tsched,
|
||||
query_supported_formats,
|
||||
query_supported_rates,
|
||||
m);
|
||||
|
||||
if (pcm_handle) {
|
||||
|
|
@ -618,8 +611,6 @@ snd_pcm_t *pa_alsa_open_by_device_id_auto(
|
|||
tsched_size,
|
||||
use_mmap,
|
||||
use_tsched,
|
||||
query_supported_formats,
|
||||
query_supported_rates,
|
||||
false);
|
||||
pa_xfree(d);
|
||||
|
||||
|
|
@ -640,8 +631,6 @@ snd_pcm_t *pa_alsa_open_by_device_id_mapping(
|
|||
snd_pcm_uframes_t tsched_size,
|
||||
bool *use_mmap,
|
||||
bool *use_tsched,
|
||||
pa_sample_format_t **query_supported_formats,
|
||||
unsigned int **query_supported_rates,
|
||||
pa_alsa_mapping *m) {
|
||||
|
||||
snd_pcm_t *pcm_handle;
|
||||
|
|
@ -671,8 +660,6 @@ snd_pcm_t *pa_alsa_open_by_device_id_mapping(
|
|||
tsched_size,
|
||||
use_mmap,
|
||||
use_tsched,
|
||||
query_supported_formats,
|
||||
query_supported_rates,
|
||||
pa_channel_map_valid(&m->channel_map) /* Query the channel count if we don't know what we want */);
|
||||
|
||||
if (!pcm_handle)
|
||||
|
|
@ -696,8 +683,6 @@ snd_pcm_t *pa_alsa_open_by_device_string(
|
|||
snd_pcm_uframes_t tsched_size,
|
||||
bool *use_mmap,
|
||||
bool *use_tsched,
|
||||
pa_sample_format_t **query_supported_formats,
|
||||
unsigned int **query_supported_rates,
|
||||
bool require_exact_channel_number) {
|
||||
|
||||
int err;
|
||||
|
|
@ -725,12 +710,6 @@ snd_pcm_t *pa_alsa_open_by_device_string(
|
|||
|
||||
pa_log_debug("Managed to open %s", d);
|
||||
|
||||
if (query_supported_formats)
|
||||
*query_supported_formats = pa_alsa_get_supported_formats(pcm_handle, ss->format);
|
||||
|
||||
if (query_supported_rates)
|
||||
*query_supported_rates = pa_alsa_get_supported_rates(pcm_handle, ss->rate);
|
||||
|
||||
if ((err = pa_alsa_set_hw_params(
|
||||
pcm_handle,
|
||||
ss,
|
||||
|
|
@ -804,8 +783,6 @@ snd_pcm_t *pa_alsa_open_by_template(
|
|||
snd_pcm_uframes_t tsched_size,
|
||||
bool *use_mmap,
|
||||
bool *use_tsched,
|
||||
pa_sample_format_t **query_supported_formats,
|
||||
unsigned int **query_supported_rates,
|
||||
bool require_exact_channel_number) {
|
||||
|
||||
snd_pcm_t *pcm_handle;
|
||||
|
|
@ -827,8 +804,6 @@ snd_pcm_t *pa_alsa_open_by_template(
|
|||
tsched_size,
|
||||
use_mmap,
|
||||
use_tsched,
|
||||
query_supported_formats,
|
||||
query_supported_rates,
|
||||
require_exact_channel_number);
|
||||
|
||||
pa_xfree(d);
|
||||
|
|
@ -1431,31 +1406,13 @@ char *pa_alsa_get_reserve_name(const char *device) {
|
|||
return pa_sprintf_malloc("Audio%i", i);
|
||||
}
|
||||
|
||||
static void dump_supported_rates(unsigned int* values)
|
||||
{
|
||||
pa_strbuf *buf;
|
||||
char *str;
|
||||
int i;
|
||||
|
||||
buf = pa_strbuf_new();
|
||||
|
||||
for (i = 0; values[i]; i++) {
|
||||
pa_strbuf_printf(buf, " %u", values[i]);
|
||||
}
|
||||
|
||||
str = pa_strbuf_to_string_free(buf);
|
||||
pa_log_debug("Supported rates:%s", str);
|
||||
pa_xfree(str);
|
||||
}
|
||||
|
||||
unsigned int *pa_alsa_get_supported_rates(snd_pcm_t *pcm, unsigned int fallback_rate) {
|
||||
static unsigned int all_rates[] = { 8000, 11025, 12000,
|
||||
16000, 22050, 24000,
|
||||
32000, 44100, 48000,
|
||||
64000, 88200, 96000,
|
||||
128000, 176400, 192000,
|
||||
352800, 384000,
|
||||
705600, 768000 };
|
||||
384000 };
|
||||
bool supported[PA_ELEMENTSOF(all_rates)] = { false, };
|
||||
snd_pcm_hw_params_t *hwparams;
|
||||
unsigned int i, j, n, *rates = NULL;
|
||||
|
|
@ -1497,40 +1454,39 @@ unsigned int *pa_alsa_get_supported_rates(snd_pcm_t *pcm, unsigned int fallback_
|
|||
rates[1] = 0;
|
||||
}
|
||||
|
||||
dump_supported_rates(rates);
|
||||
return rates;
|
||||
}
|
||||
|
||||
pa_sample_format_t *pa_alsa_get_supported_formats(snd_pcm_t *pcm, pa_sample_format_t fallback_format) {
|
||||
static const snd_pcm_format_t format_trans_to_pcm[] = {
|
||||
[PA_SAMPLE_U8] = SND_PCM_FORMAT_U8,
|
||||
[PA_SAMPLE_ALAW] = SND_PCM_FORMAT_A_LAW,
|
||||
[PA_SAMPLE_ULAW] = SND_PCM_FORMAT_MU_LAW,
|
||||
[PA_SAMPLE_S16LE] = SND_PCM_FORMAT_S16_LE,
|
||||
[PA_SAMPLE_S16BE] = SND_PCM_FORMAT_S16_BE,
|
||||
[PA_SAMPLE_FLOAT32LE] = SND_PCM_FORMAT_FLOAT_LE,
|
||||
[PA_SAMPLE_FLOAT32BE] = SND_PCM_FORMAT_FLOAT_BE,
|
||||
[PA_SAMPLE_S32LE] = SND_PCM_FORMAT_S32_LE,
|
||||
[PA_SAMPLE_S32BE] = SND_PCM_FORMAT_S32_BE,
|
||||
[PA_SAMPLE_S24LE] = SND_PCM_FORMAT_S24_3LE,
|
||||
[PA_SAMPLE_S24BE] = SND_PCM_FORMAT_S24_3BE,
|
||||
[PA_SAMPLE_S24_32LE] = SND_PCM_FORMAT_S24_LE,
|
||||
[PA_SAMPLE_S24_32BE] = SND_PCM_FORMAT_S24_BE,
|
||||
static const snd_pcm_format_t format_trans_to_pa[] = {
|
||||
[SND_PCM_FORMAT_U8] = PA_SAMPLE_U8,
|
||||
[SND_PCM_FORMAT_A_LAW] = PA_SAMPLE_ALAW,
|
||||
[SND_PCM_FORMAT_MU_LAW] = PA_SAMPLE_ULAW,
|
||||
[SND_PCM_FORMAT_S16_LE] = PA_SAMPLE_S16LE,
|
||||
[SND_PCM_FORMAT_S16_BE] = PA_SAMPLE_S16BE,
|
||||
[SND_PCM_FORMAT_FLOAT_LE] = PA_SAMPLE_FLOAT32LE,
|
||||
[SND_PCM_FORMAT_FLOAT_BE] = PA_SAMPLE_FLOAT32BE,
|
||||
[SND_PCM_FORMAT_S32_LE] = PA_SAMPLE_S32LE,
|
||||
[SND_PCM_FORMAT_S32_BE] = PA_SAMPLE_S32BE,
|
||||
[SND_PCM_FORMAT_S24_3LE] = PA_SAMPLE_S24LE,
|
||||
[SND_PCM_FORMAT_S24_3BE] = PA_SAMPLE_S24BE,
|
||||
[SND_PCM_FORMAT_S24_LE] = PA_SAMPLE_S24_32LE,
|
||||
[SND_PCM_FORMAT_S24_BE] = PA_SAMPLE_S24_32BE,
|
||||
};
|
||||
static const pa_sample_format_t all_formats[] = {
|
||||
PA_SAMPLE_U8,
|
||||
PA_SAMPLE_ALAW,
|
||||
PA_SAMPLE_ULAW,
|
||||
PA_SAMPLE_S16LE,
|
||||
PA_SAMPLE_S16BE,
|
||||
PA_SAMPLE_FLOAT32LE,
|
||||
PA_SAMPLE_FLOAT32BE,
|
||||
PA_SAMPLE_S32LE,
|
||||
PA_SAMPLE_S32BE,
|
||||
PA_SAMPLE_S24LE,
|
||||
PA_SAMPLE_S24BE,
|
||||
PA_SAMPLE_S24_32LE,
|
||||
PA_SAMPLE_S24_32BE,
|
||||
static const snd_pcm_format_t all_formats[] = {
|
||||
SND_PCM_FORMAT_U8,
|
||||
SND_PCM_FORMAT_A_LAW,
|
||||
SND_PCM_FORMAT_MU_LAW,
|
||||
SND_PCM_FORMAT_S16_LE,
|
||||
SND_PCM_FORMAT_S16_BE,
|
||||
SND_PCM_FORMAT_FLOAT_LE,
|
||||
SND_PCM_FORMAT_FLOAT_BE,
|
||||
SND_PCM_FORMAT_S32_LE,
|
||||
SND_PCM_FORMAT_S32_BE,
|
||||
SND_PCM_FORMAT_S24_3LE,
|
||||
SND_PCM_FORMAT_S24_3BE,
|
||||
SND_PCM_FORMAT_S24_LE,
|
||||
SND_PCM_FORMAT_S24_BE,
|
||||
};
|
||||
bool supported[PA_ELEMENTSOF(all_formats)] = {
|
||||
false,
|
||||
|
|
@ -1548,7 +1504,7 @@ pa_sample_format_t *pa_alsa_get_supported_formats(snd_pcm_t *pcm, pa_sample_form
|
|||
}
|
||||
|
||||
for (i = 0, n = 0; i < PA_ELEMENTSOF(all_formats); i++) {
|
||||
if (snd_pcm_hw_params_test_format(pcm, hwparams, format_trans_to_pcm[all_formats[i]]) == 0) {
|
||||
if (snd_pcm_hw_params_test_format(pcm, hwparams, all_formats[i]) == 0) {
|
||||
supported[i] = true;
|
||||
n++;
|
||||
}
|
||||
|
|
@ -1559,7 +1515,7 @@ pa_sample_format_t *pa_alsa_get_supported_formats(snd_pcm_t *pcm, pa_sample_form
|
|||
|
||||
for (i = 0, j = 0; i < PA_ELEMENTSOF(all_formats); i++) {
|
||||
if (supported[i])
|
||||
formats[j++] = all_formats[i];
|
||||
formats[j++] = format_trans_to_pa[all_formats[i]];
|
||||
}
|
||||
|
||||
formats[j] = PA_SAMPLE_MAX;
|
||||
|
|
@ -1567,7 +1523,7 @@ pa_sample_format_t *pa_alsa_get_supported_formats(snd_pcm_t *pcm, pa_sample_form
|
|||
formats = pa_xnew(pa_sample_format_t, 2);
|
||||
|
||||
formats[0] = fallback_format;
|
||||
if ((ret = snd_pcm_hw_params_set_format(pcm, hwparams, format_trans_to_pcm[formats[0]])) < 0) {
|
||||
if ((ret = snd_pcm_hw_params_set_format(pcm, hwparams, format_trans_to_pa[formats[0]])) < 0) {
|
||||
pa_log_debug("snd_pcm_hw_params_set_format() failed: %s", pa_alsa_strerror(ret));
|
||||
pa_xfree(formats);
|
||||
return NULL;
|
||||
|
|
@ -1658,16 +1614,14 @@ static snd_mixer_elem_t *pa_alsa_mixer_find(snd_mixer_t *mixer,
|
|||
snd_ctl_elem_iface_t iface,
|
||||
const char *name,
|
||||
unsigned int index,
|
||||
unsigned int device,
|
||||
unsigned int subdevice) {
|
||||
unsigned int device) {
|
||||
snd_mixer_elem_t *elem;
|
||||
|
||||
for (elem = snd_mixer_first_elem(mixer); elem; elem = snd_mixer_elem_next(elem)) {
|
||||
snd_hctl_elem_t **_helem, *helem;
|
||||
snd_hctl_elem_t *helem;
|
||||
if (snd_mixer_elem_get_type(elem) != SND_MIXER_ELEM_PULSEAUDIO)
|
||||
continue;
|
||||
_helem = snd_mixer_elem_get_private(elem);
|
||||
helem = *_helem;
|
||||
helem = snd_mixer_elem_get_private(elem);
|
||||
if (snd_hctl_elem_get_interface(helem) != iface)
|
||||
continue;
|
||||
if (!pa_streq(snd_hctl_elem_get_name(helem), name))
|
||||
|
|
@ -1676,19 +1630,17 @@ static snd_mixer_elem_t *pa_alsa_mixer_find(snd_mixer_t *mixer,
|
|||
continue;
|
||||
if (snd_hctl_elem_get_device(helem) != device)
|
||||
continue;
|
||||
if (snd_hctl_elem_get_subdevice(helem) != subdevice)
|
||||
continue;
|
||||
return elem;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
snd_mixer_elem_t *pa_alsa_mixer_find_card(snd_mixer_t *mixer, struct pa_alsa_mixer_id *alsa_id, unsigned int device) {
|
||||
return pa_alsa_mixer_find(mixer, SND_CTL_ELEM_IFACE_CARD, alsa_id->name, alsa_id->index, device, 0);
|
||||
return pa_alsa_mixer_find(mixer, SND_CTL_ELEM_IFACE_CARD, alsa_id->name, alsa_id->index, device);
|
||||
}
|
||||
|
||||
snd_mixer_elem_t *pa_alsa_mixer_find_pcm(snd_mixer_t *mixer, const char *name, unsigned int device) {
|
||||
return pa_alsa_mixer_find(mixer, SND_CTL_ELEM_IFACE_PCM, name, 0, device, 0);
|
||||
return pa_alsa_mixer_find(mixer, SND_CTL_ELEM_IFACE_PCM, name, 0, device);
|
||||
}
|
||||
|
||||
static int mixer_class_compare(const snd_mixer_elem_t *c1, const snd_mixer_elem_t *c2)
|
||||
|
|
@ -1697,79 +1649,31 @@ static int mixer_class_compare(const snd_mixer_elem_t *c1, const snd_mixer_elem_
|
|||
return c1 == c2 ? 0 : (c1 > c2 ? 1 : -1);
|
||||
}
|
||||
|
||||
static void mixer_melem_free(snd_mixer_elem_t *elem)
|
||||
{
|
||||
snd_hctl_elem_t **_helem;
|
||||
_helem = snd_mixer_elem_get_private(elem);
|
||||
pa_xfree(_helem);
|
||||
}
|
||||
|
||||
static int mixer_class_event(snd_mixer_class_t *class, unsigned int mask,
|
||||
snd_hctl_elem_t *helem, snd_mixer_elem_t *melem)
|
||||
{
|
||||
int err;
|
||||
const char *name = snd_hctl_elem_get_name(helem);
|
||||
snd_hctl_elem_t **_helem;
|
||||
/* NOTE: The remove event is defined as '~0U`. */
|
||||
if (mask == SND_CTL_EVENT_MASK_REMOVE) {
|
||||
/* NOTE: Unless we remove the pointer to melem from the linked-list at
|
||||
* private_data of helem, an assertion will be hit in alsa-lib since
|
||||
* the list is not empty. */
|
||||
_helem = snd_mixer_elem_get_private(melem);
|
||||
*_helem = NULL;
|
||||
snd_mixer_elem_detach(melem, helem);
|
||||
} else if (mask & SND_CTL_EVENT_MASK_ADD) {
|
||||
if (mask & SND_CTL_EVENT_MASK_ADD) {
|
||||
snd_ctl_elem_iface_t iface = snd_hctl_elem_get_interface(helem);
|
||||
if (iface == SND_CTL_ELEM_IFACE_CARD || iface == SND_CTL_ELEM_IFACE_PCM) {
|
||||
snd_mixer_t *mixer = snd_mixer_class_get_mixer(class);
|
||||
snd_ctl_elem_iface_t iface = snd_hctl_elem_get_interface(helem);
|
||||
const char *name = snd_hctl_elem_get_name(helem);
|
||||
const int index = snd_hctl_elem_get_index(helem);
|
||||
const int device = snd_hctl_elem_get_device(helem);
|
||||
const int subdevice = snd_hctl_elem_get_subdevice(helem);
|
||||
snd_mixer_elem_t *new_melem;
|
||||
bool found = true;
|
||||
|
||||
new_melem = pa_alsa_mixer_find(mixer, iface, name, index, device, subdevice);
|
||||
if (!new_melem) {
|
||||
_helem = pa_xmalloc(sizeof(snd_hctl_elem_t *));
|
||||
*_helem = helem;
|
||||
/* Put the hctl pointer as our private data - it will be useful for callbacks */
|
||||
if ((err = snd_mixer_elem_new(&new_melem, SND_MIXER_ELEM_PULSEAUDIO, 0, _helem, mixer_melem_free)) < 0) {
|
||||
pa_log_warn("snd_mixer_elem_new failed: %s", pa_alsa_strerror(err));
|
||||
return 0;
|
||||
}
|
||||
found = false;
|
||||
} else {
|
||||
_helem = snd_mixer_elem_get_private(new_melem);
|
||||
if (_helem) {
|
||||
char *s1, *s2;
|
||||
snd_ctl_elem_id_t *id1, *id2;
|
||||
snd_ctl_elem_id_alloca(&id1);
|
||||
snd_ctl_elem_id_alloca(&id2);
|
||||
snd_hctl_elem_get_id(helem, id1);
|
||||
snd_hctl_elem_get_id(*_helem, id2);
|
||||
s1 = snd_ctl_ascii_elem_id_get(id1);
|
||||
s2 = snd_ctl_ascii_elem_id_get(id2);
|
||||
pa_log_warn("mixer_class_event - duplicate mixer controls: %s | %s", s1, s2);
|
||||
free(s2);
|
||||
free(s1);
|
||||
return 0;
|
||||
}
|
||||
*_helem = helem;
|
||||
/* Put the hctl pointer as our private data - it will be useful for callbacks */
|
||||
if ((err = snd_mixer_elem_new(&new_melem, SND_MIXER_ELEM_PULSEAUDIO, 0, helem, NULL)) < 0) {
|
||||
pa_log_warn("snd_mixer_elem_new failed: %s", pa_alsa_strerror(err));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((err = snd_mixer_elem_attach(new_melem, helem)) < 0) {
|
||||
pa_log_warn("snd_mixer_elem_attach failed: %s", pa_alsa_strerror(err));
|
||||
snd_mixer_elem_free(melem);
|
||||
snd_mixer_elem_free(melem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
if ((err = snd_mixer_elem_add(new_melem, class)) < 0) {
|
||||
pa_log_warn("snd_mixer_elem_add failed: %s", pa_alsa_strerror(err));
|
||||
return 0;
|
||||
}
|
||||
if ((err = snd_mixer_elem_add(new_melem, class)) < 0) {
|
||||
pa_log_warn("snd_mixer_elem_add failed: %s", pa_alsa_strerror(err));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1783,14 +1687,14 @@ static int mixer_class_event(snd_mixer_class_t *class, unsigned int mask,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int prepare_mixer(snd_mixer_t *mixer, const char *dev, snd_hctl_t *hctl) {
|
||||
static int prepare_mixer(snd_mixer_t *mixer, const char *dev) {
|
||||
int err;
|
||||
snd_mixer_class_t *class;
|
||||
|
||||
pa_assert(mixer);
|
||||
pa_assert(dev);
|
||||
|
||||
if ((err = snd_mixer_attach_hctl(mixer, hctl)) < 0) {
|
||||
if ((err = snd_mixer_attach(mixer, dev)) < 0) {
|
||||
pa_log_info("Unable to attach to mixer %s: %s", dev, pa_alsa_strerror(err));
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -1829,29 +1733,37 @@ snd_mixer_t *pa_alsa_open_mixer(pa_hashmap *mixers, int alsa_card_index, bool pr
|
|||
return m;
|
||||
}
|
||||
|
||||
pa_alsa_mixer *pa_alsa_create_mixer(pa_hashmap *mixers, const char *dev, snd_mixer_t *m, bool probe) {
|
||||
pa_alsa_mixer *pm;
|
||||
|
||||
pm = pa_xnew0(pa_alsa_mixer, 1);
|
||||
if (pm == NULL)
|
||||
return NULL;
|
||||
|
||||
pm->used_for_probe_only = probe;
|
||||
pm->mixer_handle = m;
|
||||
pa_hashmap_put(mixers, pa_xstrdup(dev), pm);
|
||||
return pm;
|
||||
}
|
||||
|
||||
snd_mixer_t *pa_alsa_open_mixer_by_name(pa_hashmap *mixers, const char *dev, bool probe) {
|
||||
int err;
|
||||
snd_mixer_t *m;
|
||||
snd_hctl_t *hctl;
|
||||
pa_alsa_mixer *pm;
|
||||
char *dev2;
|
||||
void *state;
|
||||
|
||||
pa_assert(mixers);
|
||||
pa_assert(dev);
|
||||
|
||||
pm = pa_hashmap_get(mixers, dev);
|
||||
|
||||
/* The quick card number/index lookup (hw:#)
|
||||
* We already know the card number/index, thus use the mixer
|
||||
* from the cache at first.
|
||||
*/
|
||||
if (!pm && pa_strneq(dev, "hw:", 3)) {
|
||||
const char *s = dev + 3;
|
||||
int card_index;
|
||||
while (*s && *s >= '0' && *s <= '9') s++;
|
||||
if (*s == '\0' && pa_atoi(dev + 3, &card_index) >= 0) {
|
||||
PA_HASHMAP_FOREACH_KV(dev2, pm, mixers, state) {
|
||||
if (pm->card_index == card_index) {
|
||||
dev = dev2;
|
||||
pm = pa_hashmap_get(mixers, dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pm) {
|
||||
if (!probe)
|
||||
pm->used_for_probe_only = false;
|
||||
|
|
@ -1863,55 +1775,27 @@ snd_mixer_t *pa_alsa_open_mixer_by_name(pa_hashmap *mixers, const char *dev, boo
|
|||
return NULL;
|
||||
}
|
||||
|
||||
err = snd_hctl_open(&hctl, dev, 0);
|
||||
if (err < 0) {
|
||||
pa_log("Error opening hctl device: %s", pa_alsa_strerror(err));
|
||||
goto __close;
|
||||
}
|
||||
|
||||
if (prepare_mixer(m, dev, hctl) >= 0) {
|
||||
/* get the ALSA card number (index) and ID (alias) and create two identical mixers */
|
||||
char *p, *dev2, *dev_idx, *dev_id;
|
||||
snd_ctl_card_info_t *info;
|
||||
snd_ctl_card_info_alloca(&info);
|
||||
err = snd_ctl_card_info(snd_hctl_ctl(hctl), info);
|
||||
if (err < 0)
|
||||
goto __std;
|
||||
dev2 = pa_xstrdup(dev);
|
||||
if (dev2 == NULL)
|
||||
goto __close;
|
||||
p = strchr(dev2, ':');
|
||||
/* sanity check - only hw: devices */
|
||||
if (p == NULL || (p - dev2) < 2 || !pa_strneq(p - 2, "hw:", 3)) {
|
||||
pa_xfree(dev2);
|
||||
goto __std;
|
||||
}
|
||||
*p = '\0';
|
||||
dev_idx = pa_sprintf_malloc("%s:%u", dev2, snd_ctl_card_info_get_card(info));
|
||||
dev_id = pa_sprintf_malloc("%s:%s", dev2, snd_ctl_card_info_get_id(info));
|
||||
pa_log_debug("ALSA alias mixers: %s = %s", dev_idx, dev_id);
|
||||
if (dev_idx && dev_id && (strcmp(dev, dev_idx) == 0 || strcmp(dev, dev_id) == 0)) {
|
||||
pm = pa_alsa_create_mixer(mixers, dev_idx, m, probe);
|
||||
if (pm) {
|
||||
pa_alsa_mixer *pm2;
|
||||
pm2 = pa_alsa_create_mixer(mixers, dev_id, m, probe);
|
||||
if (pm2) {
|
||||
pm->alias = pm2;
|
||||
pm2->alias = pm;
|
||||
}
|
||||
if (prepare_mixer(m, dev) >= 0) {
|
||||
pm = pa_xnew0(pa_alsa_mixer, 1);
|
||||
if (pm) {
|
||||
snd_hctl_t *hctl;
|
||||
pm->card_index = -1;
|
||||
/* determine the ALSA card number (index) and store it to card_index */
|
||||
err = snd_mixer_get_hctl(m, dev, &hctl);
|
||||
if (err >= 0) {
|
||||
snd_ctl_card_info_t *info;
|
||||
snd_ctl_card_info_alloca(&info);
|
||||
err = snd_ctl_card_info(snd_hctl_ctl(hctl), info);
|
||||
if (err >= 0)
|
||||
pm->card_index = snd_ctl_card_info_get_card(info);
|
||||
}
|
||||
}
|
||||
pa_xfree(dev_id);
|
||||
pa_xfree(dev_idx);
|
||||
pa_xfree(dev2);
|
||||
__std:
|
||||
if (pm == NULL)
|
||||
pm = pa_alsa_create_mixer(mixers, dev, m, probe);
|
||||
if (pm)
|
||||
pm->used_for_probe_only = probe;
|
||||
pm->mixer_handle = m;
|
||||
pa_hashmap_put(mixers, pa_xstrdup(dev), pm);
|
||||
return m;
|
||||
}
|
||||
}
|
||||
|
||||
__close:
|
||||
snd_mixer_close(m);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -1952,10 +1836,8 @@ void pa_alsa_mixer_free(pa_alsa_mixer *mixer)
|
|||
{
|
||||
if (mixer->fdl)
|
||||
pa_alsa_fdlist_free(mixer->fdl);
|
||||
if (mixer->mixer_handle && mixer->alias == NULL)
|
||||
if (mixer->mixer_handle)
|
||||
snd_mixer_close(mixer->mixer_handle);
|
||||
if (mixer->alias)
|
||||
mixer->alias->alias = NULL;
|
||||
pa_xfree(mixer);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,8 +67,6 @@ snd_pcm_t *pa_alsa_open_by_device_id_auto(
|
|||
snd_pcm_uframes_t tsched_size,
|
||||
bool *use_mmap, /* modified at return */
|
||||
bool *use_tsched, /* modified at return */
|
||||
pa_sample_format_t **query_supported_formats, /* modified at return */
|
||||
unsigned int **query_supported_rates, /* modified at return */
|
||||
pa_alsa_profile_set *ps,
|
||||
pa_alsa_mapping **mapping); /* modified at return */
|
||||
|
||||
|
|
@ -84,8 +82,6 @@ snd_pcm_t *pa_alsa_open_by_device_id_mapping(
|
|||
snd_pcm_uframes_t tsched_size,
|
||||
bool *use_mmap, /* modified at return */
|
||||
bool *use_tsched, /* modified at return */
|
||||
pa_sample_format_t **query_supported_formats, /* modified at return */
|
||||
unsigned int **query_supported_rates, /* modified at return */
|
||||
pa_alsa_mapping *mapping);
|
||||
|
||||
/* Opens the explicit ALSA device */
|
||||
|
|
@ -100,8 +96,6 @@ snd_pcm_t *pa_alsa_open_by_device_string(
|
|||
snd_pcm_uframes_t tsched_size,
|
||||
bool *use_mmap, /* modified at return */
|
||||
bool *use_tsched, /* modified at return */
|
||||
pa_sample_format_t **query_supported_formats, /* modified at return */
|
||||
unsigned int **query_supported_rates, /* modified at return */
|
||||
bool require_exact_channel_number);
|
||||
|
||||
/* Opens the explicit ALSA device with a fallback list */
|
||||
|
|
@ -117,8 +111,6 @@ snd_pcm_t *pa_alsa_open_by_template(
|
|||
snd_pcm_uframes_t tsched_size,
|
||||
bool *use_mmap, /* modified at return */
|
||||
bool *use_tsched, /* modified at return */
|
||||
pa_sample_format_t **query_supported_formats, /* modified at return */
|
||||
unsigned int **query_supported_rates, /* modified at return */
|
||||
bool require_exact_channel_number);
|
||||
|
||||
void pa_alsa_dump(pa_log_level_t level, snd_pcm_t *pcm);
|
||||
|
|
|
|||
|
|
@ -24,9 +24,6 @@ description-key = analog-input-microphone-rear
|
|||
[Jack Rear Mic]
|
||||
required-any = any
|
||||
|
||||
[Jack Rear Mic - Input]
|
||||
required-any = any
|
||||
|
||||
[Jack Rear Mic Phantom]
|
||||
required-any = any
|
||||
state.plugged = unknown
|
||||
|
|
|
|||
|
|
@ -1,91 +0,0 @@
|
|||
# This file is part of PulseAudio.
|
||||
#
|
||||
# PulseAudio is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation; either version 2.1 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# PulseAudio is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
; ASUS Xonar SE card.
|
||||
; This card has two devices for each rear and front panel jacks.
|
||||
;
|
||||
; See default.conf for an explanation on the directives used here.
|
||||
|
||||
[General]
|
||||
auto-profiles = yes
|
||||
|
||||
[Mapping analog-stereo-headset]
|
||||
device-strings = hw:%f,1
|
||||
channel-map = left,right
|
||||
paths-output = analog-output analog-output-headphones
|
||||
paths-input = analog-input-mic analog-input-headphone-mic analog-input-headset-mic
|
||||
priority = 15
|
||||
|
||||
[Mapping analog-stereo]
|
||||
device-strings = hw:%f,0
|
||||
channel-map = left,right
|
||||
paths-output = analog-output analog-output-speaker
|
||||
paths-input = analog-input analog-input-mic analog-input-linein
|
||||
priority = 14
|
||||
|
||||
[Mapping analog-surround-21]
|
||||
device-strings = surround21:%f
|
||||
channel-map = front-left,front-right,lfe
|
||||
paths-output = analog-output-speaker
|
||||
priority = 13
|
||||
direction = output
|
||||
|
||||
[Mapping analog-surround-40]
|
||||
device-strings = surround40:%f
|
||||
channel-map = front-left,front-right,rear-left,rear-right
|
||||
paths-output = analog-output-speaker
|
||||
priority = 12
|
||||
direction = output
|
||||
|
||||
[Mapping analog-surround-41]
|
||||
device-strings = surround41:%f
|
||||
channel-map = front-left,front-right,rear-left,rear-right,lfe
|
||||
paths-output = analog-output-speaker
|
||||
priority = 13
|
||||
direction = output
|
||||
|
||||
[Mapping analog-surround-50]
|
||||
device-strings = surround50:%f
|
||||
channel-map = front-left,front-right,rear-left,rear-right,front-center
|
||||
paths-output = analog-output-speaker
|
||||
priority = 12
|
||||
direction = output
|
||||
|
||||
[Mapping analog-surround-51]
|
||||
device-strings = surround51:%f
|
||||
channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
|
||||
paths-output = analog-output-speaker
|
||||
priority = 13
|
||||
direction = output
|
||||
|
||||
[Mapping iec958-stereo]
|
||||
device-strings = iec958:%f
|
||||
channel-map = left,right
|
||||
paths-output = iec958-stereo-output
|
||||
priority = 5
|
||||
|
||||
[Mapping iec958-ac3-surround-40]
|
||||
device-strings = a52:%f
|
||||
channel-map = front-left,front-right,rear-left,rear-right
|
||||
paths-output = iec958-stereo-output
|
||||
priority = 2
|
||||
direction = output
|
||||
|
||||
[Mapping iec958-ac3-surround-51]
|
||||
device-strings = a52:%f
|
||||
channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
|
||||
paths-output = iec958-stereo-output
|
||||
priority = 3
|
||||
direction = output
|
||||
|
|
@ -13,29 +13,22 @@
|
|||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
; Texas Instruments PCM2902
|
||||
; Behringer U-Phoria UMC22
|
||||
;
|
||||
; This is a generic chip used in multiple products, including at least
|
||||
; Behringer U-Phoria UMC22, Behringer Xenyx 302USB, Intopic Jazz-UB700 and
|
||||
; some unbranded "usb mini microphone".
|
||||
; Default mapping only allows to use stereo input and sound card has two
|
||||
; physical input channels.
|
||||
;
|
||||
; Behringer UMC22 has stereo input (representing two physical mono inputs),
|
||||
; others have mono input.
|
||||
; However in case of only using a single input channel (like condenser
|
||||
; microphone) only one channel will have any sound, which is often
|
||||
; inconvenient for casual use.
|
||||
;
|
||||
; Some devices have a mic input path, but at least Behringer Xenyx 302USB
|
||||
; doesn't have any input mixer controls.
|
||||
;
|
||||
; Since the UMC22 card has only stereo input PCM device but is commonly used
|
||||
; with mono mics, we define special mono mappings using "mono,aux1" and
|
||||
; "aux1,mono" channel maps. If we had only had the standard stereo input
|
||||
; mapping, the user would have to record stereo tracks with one channel silent,
|
||||
; which would be inconvenient.
|
||||
; This config includes mono input options which makes it much more
|
||||
; friendly in single input configuration.
|
||||
;
|
||||
; This config also removes default digital input/output mappings that do
|
||||
; not physically exist on cards that we've seen so far.
|
||||
; not physically exist on this card.
|
||||
;
|
||||
; Originally added by Nazar Mokrynskyi <nazar@mokrynskyi.com> for Behringer
|
||||
; UMC22.
|
||||
; Added by Nazar Mokrynskyi <nazar@mokrynskyi.com>
|
||||
|
||||
[General]
|
||||
auto-profiles = yes
|
||||
|
|
@ -43,28 +36,28 @@ auto-profiles = yes
|
|||
[Mapping analog-stereo-input]
|
||||
device-strings = hw:%f
|
||||
channel-map = left,right
|
||||
paths-input = analog-input-mic analog-input
|
||||
paths-input = analog-input-mic
|
||||
direction = input
|
||||
priority = 4
|
||||
|
||||
[Mapping analog-mono]
|
||||
device-strings = hw:%f
|
||||
channel-map = mono
|
||||
paths-input = analog-input-mic analog-input
|
||||
channel-map = mono,mono
|
||||
paths-input = analog-input-mic
|
||||
direction = input
|
||||
priority = 3
|
||||
|
||||
[Mapping analog-mono-left]
|
||||
device-strings = hw:%f
|
||||
channel-map = mono,aux1
|
||||
paths-input = analog-input-mic analog-input
|
||||
paths-input = analog-input-mic
|
||||
direction = input
|
||||
priority = 2
|
||||
|
||||
[Mapping analog-mono-right]
|
||||
device-strings = hw:%f
|
||||
channel-map = aux1,mono
|
||||
paths-input = analog-input-mic analog-input
|
||||
paths-input = analog-input-mic
|
||||
direction = input
|
||||
priority = 1
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ channel-map = aux0,aux1,left,right,aux2,aux3
|
|||
direction = output
|
||||
|
||||
[Mapping stereo-out-ef]
|
||||
description = Stereo 5/6 (S/PDIF)
|
||||
description = Analog Stereo 5/6
|
||||
device-strings = hw:%f,0,0
|
||||
channel-map = aux0,aux1,aux2,aux3,left,right
|
||||
direction = output
|
||||
|
|
@ -51,7 +51,7 @@ channel-map = mono,aux0,aux1,aux2,aux3,aux4
|
|||
direction = input
|
||||
|
||||
[Mapping analog-mono-in-b]
|
||||
description = Analog Mono Input 2
|
||||
description = Anlog Mono Input 2
|
||||
device-strings = hw:%f,0,0
|
||||
channel-map = aux0,mono,aux1,aux2,aux3,aux4
|
||||
direction = input
|
||||
|
|
@ -69,7 +69,7 @@ channel-map = aux0,aux1,left,right,aux2,aux3
|
|||
direction = input
|
||||
|
||||
[Mapping stereo-in-ef]
|
||||
description = Stereo Input 5/6 (S/PDIF)
|
||||
description = Stereo Input 5/6
|
||||
device-strings = hw:%f,0,0
|
||||
channel-map = aux0,aux1,aux2,aux3,left,right
|
||||
direction = input
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ static void add_profiles(struct userdata *u, pa_hashmap *h, pa_hashmap *ports) {
|
|||
|
||||
PA_IDXSET_FOREACH(m, ap->output_mappings, idx) {
|
||||
if (u->use_ucm)
|
||||
pa_alsa_ucm_add_port(NULL, &m->ucm_context, true, ports, cp, u->core);
|
||||
pa_alsa_ucm_add_ports_combination(NULL, &m->ucm_context, true, ports, cp, u->core);
|
||||
else
|
||||
pa_alsa_path_set_add_ports(m->output_path_set, cp, ports, NULL, u->core);
|
||||
if (m->channel_map.channels > cp->max_sink_channels)
|
||||
|
|
@ -175,7 +175,7 @@ static void add_profiles(struct userdata *u, pa_hashmap *h, pa_hashmap *ports) {
|
|||
|
||||
PA_IDXSET_FOREACH(m, ap->input_mappings, idx) {
|
||||
if (u->use_ucm)
|
||||
pa_alsa_ucm_add_port(NULL, &m->ucm_context, false, ports, cp, u->core);
|
||||
pa_alsa_ucm_add_ports_combination(NULL, &m->ucm_context, false, ports, cp, u->core);
|
||||
else
|
||||
pa_alsa_path_set_add_ports(m->input_path_set, cp, ports, NULL, u->core);
|
||||
if (m->channel_map.channels > cp->max_source_channels)
|
||||
|
|
@ -249,7 +249,8 @@ static int card_set_profile(pa_card *c, pa_card_profile *new_profile) {
|
|||
|
||||
/* if UCM is available for this card then update the verb */
|
||||
if (u->use_ucm) {
|
||||
if (pa_alsa_ucm_set_profile(&u->ucm, c, nd->profile, od->profile) < 0) {
|
||||
if (pa_alsa_ucm_set_profile(&u->ucm, c, nd->profile ? nd->profile->name : NULL,
|
||||
od->profile ? od->profile->name : NULL) < 0) {
|
||||
ret = -1;
|
||||
goto finish;
|
||||
}
|
||||
|
|
@ -301,7 +302,7 @@ static void init_profile(struct userdata *u) {
|
|||
|
||||
if (d->profile && u->use_ucm) {
|
||||
/* Set initial verb */
|
||||
if (pa_alsa_ucm_set_profile(ucm, u->card, d->profile, NULL) < 0) {
|
||||
if (pa_alsa_ucm_set_profile(ucm, u->card, d->profile->name, NULL) < 0) {
|
||||
pa_log("Failed to set ucm profile %s", d->profile->name);
|
||||
return;
|
||||
}
|
||||
|
|
@ -370,7 +371,7 @@ struct temp_port_avail {
|
|||
|
||||
static int report_jack_state(snd_mixer_elem_t *melem, unsigned int mask) {
|
||||
struct userdata *u = snd_mixer_elem_get_callback_private(melem);
|
||||
snd_hctl_elem_t **_elem = snd_mixer_elem_get_private(melem), *elem;
|
||||
snd_hctl_elem_t *elem = snd_mixer_elem_get_private(melem);
|
||||
snd_ctl_elem_value_t *elem_value;
|
||||
bool plugged_in;
|
||||
void *state;
|
||||
|
|
@ -380,8 +381,6 @@ static int report_jack_state(snd_mixer_elem_t *melem, unsigned int mask) {
|
|||
pa_available_t active_available = PA_AVAILABLE_UNKNOWN;
|
||||
|
||||
pa_assert(u);
|
||||
pa_assert(_elem);
|
||||
elem = *_elem;
|
||||
|
||||
/* Changing the jack state may cause a port change, and a port change will
|
||||
* make the sink or source change the mixer settings. If there are multiple
|
||||
|
|
@ -564,18 +563,13 @@ static pa_device_port* find_port_with_eld_device(struct userdata *u, int device)
|
|||
|
||||
static int hdmi_eld_changed(snd_mixer_elem_t *melem, unsigned int mask) {
|
||||
struct userdata *u = snd_mixer_elem_get_callback_private(melem);
|
||||
snd_hctl_elem_t **_elem = snd_mixer_elem_get_private(melem), *elem;
|
||||
int device;
|
||||
snd_hctl_elem_t *elem = snd_mixer_elem_get_private(melem);
|
||||
int device = snd_hctl_elem_get_device(elem);
|
||||
const char *old_monitor_name;
|
||||
pa_device_port *p;
|
||||
pa_hdmi_eld eld;
|
||||
bool changed = false;
|
||||
|
||||
pa_assert(u);
|
||||
pa_assert(_elem);
|
||||
elem = *_elem;
|
||||
device = snd_hctl_elem_get_device(elem);
|
||||
|
||||
if (mask == SND_CTL_EVENT_MASK_REMOVE)
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,9 @@ typedef struct pa_a2dp_endpoint_conf {
|
|||
/* A2DP codec id */
|
||||
pa_a2dp_codec_id id;
|
||||
|
||||
/* True if codec is bi-directional and supports backchannel */
|
||||
bool support_backchannel;
|
||||
|
||||
/* Returns true if the codec can be supported on the system */
|
||||
bool (*can_be_supported)(bool for_encoding);
|
||||
|
||||
|
|
|
|||
|
|
@ -490,7 +490,7 @@ static size_t reduce_encoder_bitrate(void *codec_info, size_t write_link_mtu) {
|
|||
static size_t encode_buffer(void *codec_info, uint32_t timestamp, const uint8_t *input_buffer, size_t input_size, uint8_t *output_buffer, size_t output_size, size_t *processed) {
|
||||
size_t written;
|
||||
|
||||
written = gst_transcode_buffer(codec_info, timestamp, input_buffer, input_size, output_buffer, output_size, processed);
|
||||
written = gst_transcode_buffer(codec_info, input_buffer, input_size, output_buffer, output_size, processed);
|
||||
if (PA_UNLIKELY(*processed == 0 || *processed != input_size))
|
||||
pa_log_error("aptX encoding error");
|
||||
|
||||
|
|
@ -526,7 +526,7 @@ static size_t encode_buffer_hd(void *codec_info, uint32_t timestamp, const uint8
|
|||
static size_t decode_buffer(void *codec_info, const uint8_t *input_buffer, size_t input_size, uint8_t *output_buffer, size_t output_size, size_t *processed) {
|
||||
size_t written;
|
||||
|
||||
written = gst_transcode_buffer(codec_info, -1, input_buffer, input_size, output_buffer, output_size, processed);
|
||||
written = gst_transcode_buffer(codec_info, input_buffer, input_size, output_buffer, output_size, processed);
|
||||
|
||||
/* Due to aptX latency, aptx_decode starts filling output buffer after 90 input samples.
|
||||
* If input buffer contains less than 90 samples, aptx_decode returns zero (=no output)
|
||||
|
|
@ -556,6 +556,7 @@ static size_t decode_buffer_hd(void *codec_info, const uint8_t *input_buffer, si
|
|||
|
||||
const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_aptx = {
|
||||
.id = { A2DP_CODEC_VENDOR, APTX_VENDOR_ID, APTX_CODEC_ID },
|
||||
.support_backchannel = false,
|
||||
.can_be_supported = can_be_supported,
|
||||
.can_accept_capabilities = can_accept_capabilities,
|
||||
.choose_remote_endpoint = choose_remote_endpoint,
|
||||
|
|
@ -579,6 +580,7 @@ const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_aptx = {
|
|||
|
||||
const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_aptx_hd = {
|
||||
.id = { A2DP_CODEC_VENDOR, APTX_HD_VENDOR_ID, APTX_HD_CODEC_ID },
|
||||
.support_backchannel = false,
|
||||
.can_be_supported = can_be_supported,
|
||||
.can_accept_capabilities = can_accept_capabilities_hd,
|
||||
.choose_remote_endpoint = choose_remote_endpoint_hd,
|
||||
|
|
|
|||
|
|
@ -22,14 +22,12 @@
|
|||
#endif
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <pulsecore/log.h>
|
||||
#include <pulsecore/macro.h>
|
||||
#include <pulsecore/once.h>
|
||||
#include <pulsecore/core-util.h>
|
||||
#include <pulse/sample.h>
|
||||
#include <pulse/timeval.h>
|
||||
#include <pulse/util.h>
|
||||
|
||||
#include "a2dp-codecs.h"
|
||||
|
|
@ -41,19 +39,83 @@ static void app_sink_eos(GstAppSink *appsink, gpointer userdata) {
|
|||
pa_log_debug("Sink got EOS");
|
||||
}
|
||||
|
||||
/* Called from the GStreamer streaming thread */
|
||||
static GstFlowReturn app_sink_new_sample(GstAppSink *appsink, gpointer userdata) {
|
||||
struct gst_info *info = (struct gst_info *) userdata;
|
||||
GstSample *sample = NULL;
|
||||
GstBuffer *buf;
|
||||
|
||||
sample = gst_app_sink_pull_sample(GST_APP_SINK(info->app_sink));
|
||||
if (!sample)
|
||||
return GST_FLOW_OK;
|
||||
|
||||
buf = gst_sample_get_buffer(sample);
|
||||
gst_buffer_ref(buf);
|
||||
gst_adapter_push(info->sink_adapter, buf);
|
||||
gst_sample_unref(sample);
|
||||
pa_fdsem_post(info->sample_ready_fdsem);
|
||||
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
static void gst_deinit_common(struct gst_info *info) {
|
||||
if (!info)
|
||||
return;
|
||||
if (info->sample_ready_fdsem)
|
||||
pa_fdsem_free(info->sample_ready_fdsem);
|
||||
if (info->app_src)
|
||||
gst_object_unref(info->app_src);
|
||||
if (info->app_sink)
|
||||
gst_object_unref(info->app_sink);
|
||||
if (info->bin)
|
||||
gst_object_unref(info->bin);
|
||||
if (info->sink_adapter)
|
||||
g_object_unref(info->sink_adapter);
|
||||
if (info->pipeline)
|
||||
gst_object_unref(info->pipeline);
|
||||
}
|
||||
|
||||
static GstBusSyncReply sync_bus_handler (GstBus *bus, GstMessage *message, struct gst_info *info) {
|
||||
GstStreamStatusType type;
|
||||
GstElement *owner;
|
||||
|
||||
switch (GST_MESSAGE_TYPE (message)) {
|
||||
case GST_MESSAGE_STREAM_STATUS:
|
||||
|
||||
gst_message_parse_stream_status (message, &type, &owner);
|
||||
|
||||
switch (type) {
|
||||
case GST_STREAM_STATUS_TYPE_ENTER:
|
||||
pa_log_debug("GStreamer pipeline thread starting up");
|
||||
if (info->core->realtime_scheduling)
|
||||
pa_thread_make_realtime(info->core->realtime_priority);
|
||||
break;
|
||||
case GST_STREAM_STATUS_TYPE_LEAVE:
|
||||
pa_log_debug("GStreamer pipeline thread shutting down");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* pass all messages on the async queue */
|
||||
return GST_BUS_PASS;
|
||||
}
|
||||
|
||||
bool gst_init_common(struct gst_info *info) {
|
||||
GstElement *bin = NULL;
|
||||
GstElement *appsink = NULL;
|
||||
GstElement *pipeline = NULL;
|
||||
GstElement *appsrc = NULL, *appsink = NULL;
|
||||
GstAdapter *adapter;
|
||||
GstAppSinkCallbacks callbacks = { 0, };
|
||||
GstBus *bus;
|
||||
|
||||
appsrc = gst_element_factory_make("appsrc", "app_source");
|
||||
if (!appsrc) {
|
||||
pa_log_error("Could not create appsrc element");
|
||||
goto fail;
|
||||
}
|
||||
g_object_set(appsrc, "is-live", FALSE, "format", GST_FORMAT_TIME, "stream-type", 0, "max-bytes", 0, NULL);
|
||||
|
||||
appsink = gst_element_factory_make("appsink", "app_sink");
|
||||
if (!appsink) {
|
||||
|
|
@ -63,27 +125,75 @@ bool gst_init_common(struct gst_info *info) {
|
|||
g_object_set(appsink, "sync", FALSE, "async", FALSE, "enable-last-sample", FALSE, NULL);
|
||||
|
||||
callbacks.eos = app_sink_eos;
|
||||
callbacks.new_sample = app_sink_new_sample;
|
||||
gst_app_sink_set_callbacks(GST_APP_SINK(appsink), &callbacks, info, NULL);
|
||||
|
||||
bin = gst_bin_new(NULL);
|
||||
pa_assert(bin);
|
||||
adapter = gst_adapter_new();
|
||||
pa_assert(adapter);
|
||||
|
||||
pipeline = gst_pipeline_new(NULL);
|
||||
pa_assert(pipeline);
|
||||
|
||||
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
|
||||
gst_bus_set_sync_handler (bus, (GstBusSyncHandler) sync_bus_handler, info, NULL);
|
||||
gst_object_unref (bus);
|
||||
|
||||
info->app_src = appsrc;
|
||||
info->app_sink = appsink;
|
||||
info->bin = bin;
|
||||
info->sink_adapter = adapter;
|
||||
info->pipeline = pipeline;
|
||||
info->sample_ready_fdsem = pa_fdsem_new();
|
||||
|
||||
return true;
|
||||
|
||||
fail:
|
||||
if (appsrc)
|
||||
gst_object_unref(appsrc);
|
||||
if (appsink)
|
||||
gst_object_unref(appsink);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* The idea of using buffer probes is as follows. We set a buffer probe on the
|
||||
* encoder sink pad. In the buffer probe, we set an idle probe on the upstream
|
||||
* source pad. In encode_buffer, we wait on the fdsem. The fdsem gets posted
|
||||
* when either new_sample or idle probe gets called. We do this, to make the
|
||||
* appsink behave synchronously.
|
||||
*
|
||||
* For buffer probes, see
|
||||
* https://gstreamer.freedesktop.org/documentation/additional/design/probes.html?gi-language=c
|
||||
*/
|
||||
static GstPadProbeReturn gst_sink_buffer_idle_probe(GstPad *pad, GstPadProbeInfo *probe_info, gpointer userdata)
|
||||
{
|
||||
struct gst_info *info = (struct gst_info *)userdata;
|
||||
|
||||
pa_assert(probe_info->type & GST_PAD_PROBE_TYPE_IDLE);
|
||||
|
||||
pa_fdsem_post(info->sample_ready_fdsem);
|
||||
|
||||
return GST_PAD_PROBE_REMOVE;
|
||||
}
|
||||
|
||||
static GstPadProbeReturn gst_sink_buffer_probe(GstPad *pad, GstPadProbeInfo *probe_info, gpointer userdata)
|
||||
{
|
||||
struct gst_info *info = (struct gst_info *)userdata;
|
||||
GstPad *peer_pad;
|
||||
|
||||
pa_assert(probe_info->type & GST_PAD_PROBE_TYPE_BUFFER);
|
||||
|
||||
peer_pad = gst_pad_get_peer(pad);
|
||||
gst_pad_add_probe(peer_pad, GST_PAD_PROBE_TYPE_IDLE, gst_sink_buffer_idle_probe, info, NULL);
|
||||
gst_object_unref(peer_pad);
|
||||
|
||||
return GST_PAD_PROBE_OK;
|
||||
}
|
||||
|
||||
static GstCaps *gst_create_caps_from_sample_spec(const pa_sample_spec *ss) {
|
||||
gchar *sample_format;
|
||||
GstCaps *caps;
|
||||
uint64_t channel_mask;
|
||||
int channel_mask;
|
||||
|
||||
switch (ss->format) {
|
||||
case PA_SAMPLE_S16LE:
|
||||
|
|
@ -130,10 +240,6 @@ static GstCaps *gst_create_caps_from_sample_spec(const pa_sample_spec *ss) {
|
|||
bool gst_codec_init(struct gst_info *info, bool for_encoding, GstElement *transcoder) {
|
||||
GstPad *pad;
|
||||
GstCaps *caps;
|
||||
GstEvent *event;
|
||||
GstSegment segment;
|
||||
GstEvent *stream_start;
|
||||
guint group_id;
|
||||
|
||||
pa_assert(transcoder);
|
||||
|
||||
|
|
@ -142,49 +248,30 @@ bool gst_codec_init(struct gst_info *info, bool for_encoding, GstElement *transc
|
|||
if (!gst_init_common(info))
|
||||
goto common_fail;
|
||||
|
||||
gst_bin_add_many(GST_BIN(info->bin), transcoder, info->app_sink, NULL);
|
||||
caps = gst_create_caps_from_sample_spec(info->ss);
|
||||
if (for_encoding)
|
||||
g_object_set(info->app_src, "caps", caps, NULL);
|
||||
else
|
||||
g_object_set(info->app_sink, "caps", caps, NULL);
|
||||
gst_caps_unref(caps);
|
||||
|
||||
if (!gst_element_link_many(transcoder, info->app_sink, NULL)) {
|
||||
|
||||
gst_bin_add_many(GST_BIN(info->pipeline), info->app_src, transcoder, info->app_sink, NULL);
|
||||
|
||||
if (!gst_element_link_many(info->app_src, transcoder, info->app_sink, NULL)) {
|
||||
pa_log_error("Failed to link codec elements into pipeline");
|
||||
goto pipeline_fail;
|
||||
}
|
||||
|
||||
pad = gst_element_get_static_pad(transcoder, "sink");
|
||||
pa_assert_se(gst_element_add_pad(info->bin, gst_ghost_pad_new("sink", pad)));
|
||||
/**
|
||||
* Only the sink pad is needed to push buffers. Cache it since
|
||||
* gst_element_get_static_pad is relatively expensive and verbose
|
||||
* on higher log levels.
|
||||
*/
|
||||
info->pad_sink = pad;
|
||||
|
||||
if (gst_element_set_state(info->bin, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
|
||||
if (gst_element_set_state(info->pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
|
||||
pa_log_error("Could not start pipeline");
|
||||
goto pipeline_fail;
|
||||
}
|
||||
|
||||
/* First, send stream-start sticky event */
|
||||
group_id = gst_util_group_id_next();
|
||||
stream_start = gst_event_new_stream_start("gst-codec-pa");
|
||||
gst_event_set_group_id(stream_start, group_id);
|
||||
gst_pad_send_event(info->pad_sink, stream_start);
|
||||
|
||||
/* Retrieve the pad that handles the PCM format between PA and GStreamer */
|
||||
if (for_encoding)
|
||||
pad = gst_element_get_static_pad(transcoder, "sink");
|
||||
else
|
||||
pad = gst_element_get_static_pad(transcoder, "src");
|
||||
|
||||
/* Second, send caps sticky event */
|
||||
caps = gst_create_caps_from_sample_spec(info->ss);
|
||||
pa_assert_se(gst_pad_set_caps(pad, caps));
|
||||
gst_caps_unref(caps);
|
||||
gst_object_unref(GST_OBJECT(pad));
|
||||
|
||||
/* Third, send segment sticky event */
|
||||
gst_segment_init(&segment, GST_FORMAT_TIME);
|
||||
event = gst_event_new_segment(&segment);
|
||||
gst_pad_send_event(info->pad_sink, event);
|
||||
/* See the comment on buffer probe functions */
|
||||
pad = gst_element_get_static_pad(transcoder, "sink");
|
||||
gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER, gst_sink_buffer_probe, info, NULL);
|
||||
gst_object_unref(pad);
|
||||
|
||||
pa_log_info("GStreamer pipeline initialisation succeeded");
|
||||
|
||||
|
|
@ -208,58 +295,40 @@ common_fail:
|
|||
return false;
|
||||
}
|
||||
|
||||
size_t gst_transcode_buffer(void *codec_info, uint32_t timestamp, const uint8_t *input_buffer, size_t input_size, uint8_t *output_buffer, size_t output_size, size_t *processed) {
|
||||
size_t gst_transcode_buffer(void *codec_info, const uint8_t *input_buffer, size_t input_size, uint8_t *output_buffer, size_t output_size, size_t *processed) {
|
||||
struct gst_info *info = (struct gst_info *) codec_info;
|
||||
gsize transcoded;
|
||||
gsize available, transcoded;
|
||||
GstBuffer *in_buf;
|
||||
GstMapInfo map_info;
|
||||
GstFlowReturn ret;
|
||||
size_t written = 0;
|
||||
GstSample *sample;
|
||||
|
||||
pa_assert(info->pad_sink);
|
||||
|
||||
in_buf = gst_buffer_new_wrapped_full(GST_MEMORY_FLAG_READONLY,
|
||||
(gpointer)input_buffer, input_size, 0, input_size, NULL, NULL);
|
||||
in_buf = gst_buffer_new_allocate(NULL, input_size, NULL);
|
||||
pa_assert(in_buf);
|
||||
/* Acquire an extra reference to validate refcount afterwards */
|
||||
gst_mini_object_ref(GST_MINI_OBJECT_CAST(in_buf));
|
||||
pa_assert(GST_MINI_OBJECT_REFCOUNT_VALUE(in_buf) == 2);
|
||||
|
||||
if (timestamp == -1)
|
||||
GST_BUFFER_TIMESTAMP(in_buf) = GST_CLOCK_TIME_NONE;
|
||||
else {
|
||||
// Timestamp is monotonically increasing with samplerate/packets-per-second;
|
||||
// convert it to a timestamp in nanoseconds:
|
||||
GST_BUFFER_TIMESTAMP(in_buf) = timestamp * PA_USEC_PER_SEC / info->ss->rate;
|
||||
}
|
||||
|
||||
ret = gst_pad_chain(info->pad_sink, in_buf);
|
||||
/**
|
||||
* Ensure we're the only one holding a reference to this buffer after gst_pad_chain,
|
||||
* which internally holds a pointer reference to input_buffer. The caller provides
|
||||
* no guarantee to the validity of this pointer after returning from this function.
|
||||
*/
|
||||
pa_assert(GST_MINI_OBJECT_REFCOUNT_VALUE(in_buf) == 1);
|
||||
gst_mini_object_unref(GST_MINI_OBJECT_CAST(in_buf));
|
||||
pa_assert_se(gst_buffer_map(in_buf, &map_info, GST_MAP_WRITE));
|
||||
memcpy(map_info.data, input_buffer, input_size);
|
||||
gst_buffer_unmap(in_buf, &map_info);
|
||||
|
||||
ret = gst_app_src_push_buffer(GST_APP_SRC(info->app_src), in_buf);
|
||||
if (ret != GST_FLOW_OK) {
|
||||
pa_log_error("failed to push buffer for transcoding %d", ret);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
while ((sample = gst_app_sink_try_pull_sample(GST_APP_SINK(info->app_sink), 0))) {
|
||||
in_buf = gst_sample_get_buffer(sample);
|
||||
pa_fdsem_wait(info->sample_ready_fdsem);
|
||||
|
||||
available = gst_adapter_available(info->sink_adapter);
|
||||
|
||||
if (available) {
|
||||
transcoded = PA_MIN(available, output_size);
|
||||
|
||||
gst_adapter_copy(info->sink_adapter, output_buffer, 0, transcoded);
|
||||
gst_adapter_flush(info->sink_adapter, transcoded);
|
||||
|
||||
transcoded = gst_buffer_get_size(in_buf);
|
||||
written += transcoded;
|
||||
pa_assert(written <= output_size);
|
||||
|
||||
GstMapInfo map_info;
|
||||
pa_assert_se(gst_buffer_map(in_buf, &map_info, GST_MAP_READ));
|
||||
memcpy(output_buffer, map_info.data, transcoded);
|
||||
gst_buffer_unmap(in_buf, &map_info);
|
||||
gst_sample_unref(sample);
|
||||
}
|
||||
} else
|
||||
pa_log_debug("No transcoded data available in adapter");
|
||||
|
||||
*processed = input_size;
|
||||
|
||||
|
|
@ -274,13 +343,17 @@ fail:
|
|||
void gst_codec_deinit(void *codec_info) {
|
||||
struct gst_info *info = (struct gst_info *) codec_info;
|
||||
|
||||
if (info->bin) {
|
||||
gst_element_set_state(info->bin, GST_STATE_NULL);
|
||||
gst_object_unref(info->bin);
|
||||
if (info->sample_ready_fdsem)
|
||||
pa_fdsem_free(info->sample_ready_fdsem);
|
||||
|
||||
|
||||
if (info->pipeline) {
|
||||
gst_element_set_state(info->pipeline, GST_STATE_NULL);
|
||||
gst_object_unref(info->pipeline);
|
||||
}
|
||||
|
||||
if (info->pad_sink)
|
||||
gst_object_unref(GST_OBJECT(info->pad_sink));
|
||||
if (info->sink_adapter)
|
||||
g_object_unref(info->sink_adapter);
|
||||
|
||||
pa_xfree(info);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,15 +43,15 @@ struct gst_info {
|
|||
const a2dp_ldac_t *ldac_config;
|
||||
} a2dp_codec_t;
|
||||
|
||||
/* The appsink element that accumulates encoded/decoded buffers */
|
||||
GstElement *app_sink;
|
||||
GstElement *bin;
|
||||
/* The sink pad to push to-be-encoded/decoded buffers into */
|
||||
GstPad *pad_sink;
|
||||
GstElement *app_src, *app_sink;
|
||||
GstElement *pipeline;
|
||||
GstAdapter *sink_adapter;
|
||||
|
||||
pa_fdsem *sample_ready_fdsem;
|
||||
|
||||
uint16_t seq_num;
|
||||
};
|
||||
|
||||
bool gst_codec_init(struct gst_info *info, bool for_encoding, GstElement *transcoder);
|
||||
size_t gst_transcode_buffer(void *codec_info, uint32_t timestamp, const uint8_t *input_buffer, size_t input_size, uint8_t *output_buffer, size_t output_size, size_t *processed);
|
||||
size_t gst_transcode_buffer(void *codec_info, const uint8_t *input_buffer, size_t input_size, uint8_t *output_buffer, size_t output_size, size_t *processed);
|
||||
void gst_codec_deinit(void *codec_info);
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue