mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-10-29 05:40:23 -04:00
update master
This commit is contained in:
commit
7138fa0272
227 changed files with 67492 additions and 3107 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -37,3 +37,4 @@ 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
|
||||
# wayland/ci-templates repository which is the recommended way to set up CI
|
||||
# freedesktop/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
|
||||
|
|
@ -19,22 +19,26 @@ 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.
|
||||
<<<<<<< HEAD
|
||||
FDO_DISTRIBUTION_TAG: '2021-03-01-02'
|
||||
FDO_DISTRIBUTION_VERSION: '18.04'
|
||||
=======
|
||||
FDO_DISTRIBUTION_TAG: '2023-08-13-00'
|
||||
FDO_DISTRIBUTION_VERSION: '20.04'
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
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: 'wayland/ci-templates'
|
||||
- project: 'freedesktop/ci-templates'
|
||||
ref: 'master'
|
||||
file: '/templates/ubuntu.yml'
|
||||
|
||||
build-container:
|
||||
extends: .fdo.container-ifnot-exists@ubuntu
|
||||
extends: .fdo.container-build@ubuntu
|
||||
stage: container
|
||||
variables:
|
||||
GIT_STRATEGY: none # no need to pull the whole tree for rebuilding the image
|
||||
|
|
@ -48,6 +52,7 @@ build-container:
|
|||
check
|
||||
curl
|
||||
dbus-x11
|
||||
doxygen
|
||||
g++
|
||||
gcc
|
||||
gettext
|
||||
|
|
@ -88,17 +93,17 @@ build-container:
|
|||
wget
|
||||
|
||||
build-meson:
|
||||
extends: .fdo.distribution-image@ubuntu
|
||||
stage: build
|
||||
image: $UBUNTU_IMAGE
|
||||
script:
|
||||
# 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
|
||||
# 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
|
||||
- python3 setup.py install
|
||||
- cd ..
|
||||
# Do the actual build
|
||||
- meson build
|
||||
- meson build -Dwebrtc-aec=enabled
|
||||
- cd build
|
||||
- ninja
|
||||
- ulimit -c 0 # don't dump core files on tests that are supposed to assert
|
||||
|
|
|
|||
189
NEWS
189
NEWS
|
|
@ -1,3 +1,192 @@
|
|||
<<<<<<< HEAD
|
||||
=======
|
||||
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
|
||||
김인수
|
||||
|
||||
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
PulseAudio 15.0
|
||||
|
||||
Changes at a glance:
|
||||
|
|
|
|||
|
|
@ -14,11 +14,33 @@ if get_option('daemon')
|
|||
]
|
||||
endif
|
||||
|
||||
<<<<<<< HEAD
|
||||
manpages += [
|
||||
['pacat', '1', ['paplay', 'parec', 'parecord', 'pamon']],
|
||||
['pactl', '1'],
|
||||
['pulse-client.conf', '5'],
|
||||
]
|
||||
=======
|
||||
if get_option('client')
|
||||
manpages += [
|
||||
['pacat', '1', ['paplay', 'parec', 'parecord', 'pamon']],
|
||||
['pactl', '1'],
|
||||
['pulse-client.conf', '5'],
|
||||
]
|
||||
|
||||
if cdata.has('HAVE_OSS_WRAPPER')
|
||||
manpages += [
|
||||
['padsp', '1'],
|
||||
]
|
||||
endif
|
||||
|
||||
if x11_dep.found()
|
||||
manpages += [
|
||||
['pax11publish', '1'],
|
||||
]
|
||||
endif
|
||||
endif
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
if cdata.has('HAVE_OSS_WRAPPER')
|
||||
manpages += [
|
||||
|
|
|
|||
|
|
@ -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.</p></optdesc>
|
||||
<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>
|
||||
</option>
|
||||
|
||||
<option>
|
||||
|
|
|
|||
|
|
@ -174,7 +174,13 @@ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<option>
|
||||
<p><opt>set-default-sink</opt> <arg>SINK</arg></p>
|
||||
<<<<<<< HEAD
|
||||
<optdesc><p>Make the specified sink (identified by its symbolic name or numerical index) the default sink.</p></optdesc>
|
||||
=======
|
||||
<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>
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
</option>
|
||||
|
||||
<option>
|
||||
|
|
@ -189,7 +195,13 @@ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<option>
|
||||
<p><opt>set-default-source</opt> <arg>SOURCE</arg></p>
|
||||
<<<<<<< HEAD
|
||||
<optdesc><p>Make the specified source (identified by its symbolic name or numerical index) the default source.</p></optdesc>
|
||||
=======
|
||||
<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>
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
</option>
|
||||
|
||||
<option>
|
||||
|
|
|
|||
|
|
@ -143,8 +143,10 @@ 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.</p><p>Note that defaults may be overridden by various policy modules
|
||||
or by specific stream configurations.</p></optdesc>
|
||||
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>
|
||||
</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 sever to connect
|
||||
<p><opt>default-server=</opt> The default server to connect
|
||||
to. The environment variable <opt>$PULSE_SERVER</opt> takes
|
||||
precedence.</p>
|
||||
</option>
|
||||
|
|
|
|||
578
meson.build
578
meson.build
|
|
@ -1,10 +1,16 @@
|
|||
project('pulseaudio', 'c', 'cpp',
|
||||
version : run_command(find_program('git-version-gen'), join_paths(meson.current_source_dir(), '.tarball-version')).stdout().strip(),
|
||||
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.50.0',
|
||||
default_options : [ 'c_std=gnu11', 'cpp_std=c++11' ]
|
||||
default_options : [ 'c_std=gnu11', 'cpp_std=c++17' ]
|
||||
)
|
||||
|
||||
<<<<<<< HEAD
|
||||
meson.add_dist_script('scripts/save-tarball-version.sh', meson.project_version())
|
||||
=======
|
||||
if not meson.is_subproject()
|
||||
meson.add_dist_script('scripts/save-tarball-version.sh', meson.project_version())
|
||||
endif
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
pa_version_str = meson.project_version()
|
||||
# For tarballs, the first split will do nothing, but for builds in git, we
|
||||
|
|
@ -25,7 +31,11 @@ pa_protocol_version = 35
|
|||
|
||||
# The stable ABI for client applications, for the version info x:y:z
|
||||
# always will hold x=z
|
||||
<<<<<<< HEAD
|
||||
libpulse_version_info = [24, 0, 24]
|
||||
=======
|
||||
libpulse_version_info = [24, 3, 24]
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
# A simplified, synchronous, ABI-stable interface for client
|
||||
# applications, for the version info x:y:z always will hold x=z
|
||||
|
|
@ -53,6 +63,8 @@ libpulse_mainloop_glib_version = '@0@.@1@.@2@'.format(
|
|||
libpulse_mainloop_glib_version_info[1],
|
||||
)
|
||||
|
||||
i18n = import('i18n')
|
||||
|
||||
# Paths
|
||||
|
||||
prefix = get_option('prefix')
|
||||
|
|
@ -68,6 +80,10 @@ 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')
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
po_dir = join_paths(meson.current_source_dir(), 'po')
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
if host_machine.system() == 'windows'
|
||||
# Windows only supports loading libraries from the same dir as the executable
|
||||
|
|
@ -85,7 +101,12 @@ pulsesysconfdir = join_paths(sysconfdir, 'pulse')
|
|||
|
||||
modlibexecdir = get_option('modlibexecdir')
|
||||
if modlibexecdir == ''
|
||||
modlibexecdir = join_paths(libdir, 'pulse-' + pa_version_major_minor, 'modules')
|
||||
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
|
||||
endif
|
||||
|
||||
padsplibdir = get_option('padsplibdir')
|
||||
|
|
@ -140,7 +161,11 @@ 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())
|
||||
cdata.set_quoted('PA_SOEXT', '.so')
|
||||
if host_machine.system() == 'windows'
|
||||
cdata.set_quoted('PA_SOEXT', '.dll')
|
||||
else
|
||||
cdata.set_quoted('PA_SOEXT', '.so')
|
||||
endif
|
||||
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'))
|
||||
|
|
@ -152,8 +177,7 @@ 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_PATHS_DIR', join_paths(alsadatadir, 'paths'))
|
||||
cdata.set_quoted('PA_ALSA_PROFILE_SETS_DIR', join_paths(alsadatadir, 'profile-sets'))
|
||||
cdata.set_quoted('PA_ALSA_DATA_DIR', alsadatadir)
|
||||
cdata.set_quoted('DESKTOPFILEDIR', join_paths(datadir, 'applications'))
|
||||
cdata.set_quoted('PULSE_LOCALEDIR', localedir)
|
||||
cdata.set_quoted('GETTEXT_PACKAGE', 'pulseaudio')
|
||||
|
|
@ -177,6 +201,7 @@ 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)
|
||||
|
|
@ -416,7 +441,11 @@ 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.
|
||||
<<<<<<< HEAD
|
||||
if host_machine.system() != 'windows'
|
||||
=======
|
||||
if host_machine.system() != 'windows' and host_machine.system() != 'darwin'
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
nodelete_link_args = ['-Wl,-z,nodelete']
|
||||
else
|
||||
nodelete_link_args = []
|
||||
|
|
@ -425,6 +454,7 @@ endif
|
|||
# Code coverage
|
||||
|
||||
if get_option('gcov')
|
||||
add_languages('cpp')
|
||||
add_project_arguments('--coverage', language: ['c', 'cpp'])
|
||||
add_project_link_arguments('--coverage', language: ['c', 'cpp'])
|
||||
endif
|
||||
|
|
@ -490,22 +520,24 @@ endif
|
|||
|
||||
need_libatomic_ops = false
|
||||
|
||||
atomictest = '''void func() {
|
||||
atomictest = '''int main() {
|
||||
volatile int atomic = 2;
|
||||
__sync_bool_compare_and_swap (&atomic, 2, 3);
|
||||
return 0;
|
||||
}
|
||||
'''
|
||||
|
||||
if cc.compiles(atomictest)
|
||||
if cc.links(atomictest)
|
||||
cdata.set('HAVE_ATOMIC_BUILTINS', 1)
|
||||
|
||||
newatomictest = '''void func() {
|
||||
newatomictest = '''int main() {
|
||||
int c = 0;
|
||||
__atomic_store_n(&c, 4, __ATOMIC_SEQ_CST);
|
||||
return 0;
|
||||
}
|
||||
'''
|
||||
|
||||
if(cc.compiles(newatomictest))
|
||||
if(cc.links(newatomictest))
|
||||
cdata.set('HAVE_ATOMIC_BUILTINS_MEMORY_MODEL', 1)
|
||||
endif
|
||||
|
||||
|
|
@ -577,6 +609,7 @@ if host_machine.cpu_family() == 'arm'
|
|||
endif
|
||||
# NEON checks are automatically done by the unstable-simd module
|
||||
|
||||
<<<<<<< HEAD
|
||||
if get_option('daemon')
|
||||
# FIXME: make sure it's >= 2.2
|
||||
ltdl_dep = cc.find_library('ltdl', required : true)
|
||||
|
|
@ -593,39 +626,20 @@ elif get_option('database') == 'gdbm'
|
|||
else
|
||||
database_dep = dependency('', required: false)
|
||||
endif
|
||||
=======
|
||||
# Dependencies common to client, daemon and modules
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
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
|
||||
|
||||
<<<<<<< HEAD
|
||||
gio_dep = dependency('gio-2.0', version : '>= 2.26.0')
|
||||
if get_option('gsettings').enabled()
|
||||
assert(gio_dep.found(), 'GSettings support needs glib I/O library (GIO)')
|
||||
|
|
@ -634,51 +648,22 @@ else
|
|||
cdata.set('HAVE_GSETTINGS', 0)
|
||||
endif
|
||||
|
||||
=======
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
glib_dep = dependency('glib-2.0', version : '>= 2.28.0', required: get_option('glib'))
|
||||
if glib_dep.found()
|
||||
cdata.set('HAVE_GLIB', 1)
|
||||
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)
|
||||
cdata.set('HAVE_GLIB20', 1) # to match the AM_CONDITIONAL for CMake file generation
|
||||
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()
|
||||
|
|
@ -691,6 +676,7 @@ if cc.has_header('tcpd.h') and cc.has_function('hosts_access', dependencies : tc
|
|||
endif
|
||||
|
||||
x11_dep = dependency('x11-xcb', required : get_option('x11'))
|
||||
<<<<<<< HEAD
|
||||
if x11_dep.found()
|
||||
xcb_dep = dependency('xcb', required : true, version : '>= 1.6')
|
||||
ice_dep = dependency('ice', required : get_option('daemon'))
|
||||
|
|
@ -704,15 +690,24 @@ endif
|
|||
|
||||
# Module dependencies
|
||||
if cc.has_header('sys/soundcard.h', required: get_option('oss-output'))
|
||||
=======
|
||||
|
||||
# OSS support
|
||||
if cc.has_header('sys/soundcard.h', required: get_option('oss-output'))
|
||||
# OSS output via daemon module-detect
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
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)
|
||||
fftw_dep = dependency('fftw3f', required : get_option('fftw'))
|
||||
if fftw_dep.found()
|
||||
cdata.set('HAVE_FFTW', 1)
|
||||
endif
|
||||
|
||||
<<<<<<< HEAD
|
||||
avahi_dep = dependency('avahi-client', version : '>= 0.6.0', required : get_option('avahi'), disabler : true)
|
||||
if avahi_dep.found()
|
||||
cdata.set('HAVE_AVAHI', 1)
|
||||
|
|
@ -732,47 +727,179 @@ if bluez_dep.found()
|
|||
cdata.set('HAVE_BLUEZ_5', 1)
|
||||
if get_option('bluez5-native-headset')
|
||||
cdata.set('HAVE_BLUEZ_5_NATIVE_HEADSET', 1)
|
||||
=======
|
||||
# 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)
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
endif
|
||||
if get_option('bluez5-ofono-headset')
|
||||
cdata.set('HAVE_BLUEZ_5_OFONO_HEADSET', 1)
|
||||
|
||||
gtk_dep = dependency('gtk+-3.0', required : get_option('gtk'))
|
||||
if gtk_dep.found()
|
||||
cdata.set('HAVE_GTK', 1)
|
||||
endif
|
||||
endif
|
||||
|
||||
fftw_dep = dependency('fftw3f', required : get_option('fftw'))
|
||||
if fftw_dep.found()
|
||||
cdata.set('HAVE_FFTW', 1)
|
||||
endif
|
||||
# Daemon and module dependencies
|
||||
|
||||
jack_dep = dependency('jack', version : '>= 0.117.0', required : get_option('jack'))
|
||||
if jack_dep.found()
|
||||
cdata.set('HAVE_JACK', 1)
|
||||
endif
|
||||
if get_option('daemon')
|
||||
# FIXME: make sure it's >= 2.2
|
||||
ltdl_dep = cc.find_library('ltdl', required : true)
|
||||
|
||||
lirc_dep = dependency('lirc', required : get_option('lirc'))
|
||||
if lirc_dep.found()
|
||||
cdata.set('HAVE_LIRC', 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)
|
||||
|
||||
openssl_dep = dependency('openssl', version : '>= 0.9', required : get_option('openssl'))
|
||||
if openssl_dep.found()
|
||||
cdata.set('HAVE_OPENSSL', 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
|
||||
|
||||
speex_dep = dependency('speexdsp', version : '>= 1.2', required : get_option('speex'))
|
||||
if speex_dep.found()
|
||||
cdata.set('HAVE_SPEEX', 1)
|
||||
endif
|
||||
if get_option('legacy-database-entry-format')
|
||||
cdata.set('ENABLE_LEGACY_DATABASE_ENTRY_FORMAT', 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('stream-restore-clear-old-devices')
|
||||
cdata.set('STREAM_RESTORE_CLEAR_OLD_DEVICES', 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('running-from-build-tree')
|
||||
cdata.set('HAVE_RUNNING_FROM_BUILD_TREE', 1)
|
||||
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_pkgconfig_variable('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
|
||||
|
||||
<<<<<<< HEAD
|
||||
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'))
|
||||
|
|
@ -781,6 +908,30 @@ 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
|
||||
=======
|
||||
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
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
endif
|
||||
|
||||
bluez5_gst_dep = dependency('gstreamer-1.0', version : '>= 1.14', required : get_option('bluez5-gstreamer'))
|
||||
|
|
@ -795,9 +946,6 @@ 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
|
||||
|
||||
|
|
@ -808,81 +956,93 @@ check_dep = dependency('check', version : '>= 0.9.10', required : get_option('te
|
|||
if get_option('doxygen')
|
||||
subdir('doxygen')
|
||||
endif
|
||||
<<<<<<< HEAD
|
||||
subdir('po')
|
||||
=======
|
||||
if get_option('client')
|
||||
subdir('po')
|
||||
endif
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
if get_option('man')
|
||||
subdir('man')
|
||||
endif
|
||||
subdir('shell-completion/bash')
|
||||
subdir('shell-completion/zsh')
|
||||
subdir('src')
|
||||
subdir('vala')
|
||||
if get_option('client')
|
||||
subdir('vala')
|
||||
endif
|
||||
|
||||
# Now generate config.h from everything above
|
||||
configure_file(output : 'config.h', configuration : cdata)
|
||||
|
||||
# pkg-config files
|
||||
if get_option('client')
|
||||
|
||||
pc_cdata = configuration_data()
|
||||
# pkg-config files
|
||||
|
||||
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 = configuration_data()
|
||||
|
||||
pc_files = [
|
||||
'libpulse.pc',
|
||||
'libpulse-simple.pc',
|
||||
]
|
||||
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')
|
||||
|
||||
if glib_dep.found()
|
||||
pc_files += 'libpulse-mainloop-glib.pc'
|
||||
endif
|
||||
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,
|
||||
)
|
||||
|
||||
foreach file : pc_files
|
||||
configure_file(
|
||||
input : file + '.in',
|
||||
output : file,
|
||||
configuration : pc_cdata,
|
||||
install_dir : pkgconfigdir)
|
||||
endforeach
|
||||
input : 'PulseAudioConfigVersion.cmake.in',
|
||||
output : 'PulseAudioConfigVersion.cmake',
|
||||
configuration: cdata,
|
||||
install : true,
|
||||
install_dir : cmakedir,
|
||||
)
|
||||
|
||||
# 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,
|
||||
)
|
||||
endif # client
|
||||
|
||||
############################################################
|
||||
|
||||
|
|
@ -913,17 +1073,57 @@ summary = [
|
|||
# 'LIBS: @0@'.format(${LIBS}),
|
||||
'',
|
||||
'Enable pulseaudio daemon: @0@'.format(get_option('daemon')),
|
||||
<<<<<<< HEAD
|
||||
'',
|
||||
'Enable memfd shared memory: @0@'.format(cdata.has('HAVE_MEMFD')),
|
||||
'Enable X11: @0@'.format(x11_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 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()),
|
||||
'Enable OSS Output: @0@'.format(cdata.has('HAVE_OSS_OUTPUT')),
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
# '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}),
|
||||
<<<<<<< HEAD
|
||||
'Enable GLib 2: @0@'.format(glib_dep.found()),
|
||||
'Enable GSettings: @0@'.format(gio_dep.found()),
|
||||
'Enable Gtk+ 3: @0@'.format(gtk_dep.found()),
|
||||
|
|
@ -941,21 +1141,35 @@ summary = [
|
|||
'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 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),
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
'Enable libsamplerate: @0@'.format(samplerate_dep.found()),
|
||||
'Enable ORC: @0@'.format(have_orcc),
|
||||
'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()),
|
||||
<<<<<<< HEAD
|
||||
'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')),
|
||||
=======
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
'',
|
||||
'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:',
|
||||
|
|
@ -968,19 +1182,21 @@ summary = [
|
|||
# 'Force preopen: @0@'.format(${FORCE_PREOPEN}),
|
||||
# 'Preopened modules: @0@'.format(${PREOPEN_MODS}),
|
||||
]
|
||||
endif
|
||||
|
||||
message('\n '.join(summary))
|
||||
|
||||
# Sanity checks
|
||||
|
||||
if not speex_dep.found() and not webrtc_dep.found() and not get_option('adrian-aec')
|
||||
if get_option('daemon') and 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 samplerate_dep.found()
|
||||
if get_option('daemon') and samplerate_dep.found()
|
||||
warning('Support for libsamplerate is DEPRECATED')
|
||||
endif
|
||||
|
||||
<<<<<<< HEAD
|
||||
if host_machine.system() != 'windows'
|
||||
if not dbus_dep.found()
|
||||
message = [
|
||||
|
|
@ -1011,4 +1227,36 @@ if host_machine.system() != 'windows'
|
|||
]
|
||||
warning('\n' + '\n'.join(message))
|
||||
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))
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -1,6 +1,12 @@
|
|||
option('daemon',
|
||||
type : 'boolean', value : true,
|
||||
description : 'Enable building and installation of pulseaudio daemon and supporting configuration files')
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
option('client',
|
||||
type : 'boolean', value : true,
|
||||
description : 'Build and install pulseaudio client libraries and utilities')
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
option('doxygen',
|
||||
type : 'boolean', value : true,
|
||||
description : 'Enable building and installation of documentation generated with doxygen')
|
||||
|
|
@ -96,6 +102,9 @@ 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')
|
||||
|
|
@ -162,6 +171,9 @@ 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,3 +48,8 @@ zh_CN
|
|||
zh_TW
|
||||
eo
|
||||
si
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
ka
|
||||
eu
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
|
|
|||
|
|
@ -170,6 +170,7 @@ 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
|
||||
|
|
|
|||
980
po/bn_IN.po
980
po/bn_IN.po
File diff suppressed because it is too large
Load diff
842
po/de_CH.po
842
po/de_CH.po
File diff suppressed because it is too large
Load diff
|
|
@ -1,4 +1,3 @@
|
|||
i18n = import('i18n')
|
||||
i18n.gettext(
|
||||
meson.project_name(),
|
||||
preset: 'glib',
|
||||
|
|
@ -7,5 +6,3 @@ i18n.gettext(
|
|||
args: ['--msgid-bugs-address=https://gitlab.freedesktop.org/pulseaudio/pulseaudio/issues/new',
|
||||
'--width=90'],
|
||||
)
|
||||
|
||||
po_dir = meson.current_source_dir()
|
||||
|
|
|
|||
835
po/pt_BR.po
835
po/pt_BR.po
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
952
po/sr@latin.po
952
po/sr@latin.po
File diff suppressed because it is too large
Load diff
999
po/zh_CN.po
999
po/zh_CN.po
File diff suppressed because it is too large
Load diff
757
po/zh_TW.po
757
po/zh_TW.po
File diff suppressed because it is too large
Load diff
|
|
@ -17,7 +17,21 @@ print_map_file() {
|
|||
echo "};"
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
TARGET_FILE=$1
|
||||
shift
|
||||
|
||||
cd "${MESON_SOURCE_ROOT}/${MESON_SUBDIR}" && print_map_file "$@" > ${TARGET_FILE}
|
||||
=======
|
||||
print_def_file() {
|
||||
echo "EXPORTS"
|
||||
ctags -I ${CTAGS_IDENTIFIER_LIST} -f - --c-kinds=p "$@" | awk '/^pa_/ && !/(^pa_glib_|^pa_simple_)/ { print $1 }' | sort
|
||||
}
|
||||
|
||||
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}
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
if bashcompletiondir != 'no'
|
||||
aliases = []
|
||||
<<<<<<< HEAD
|
||||
|
||||
if get_option('daemon')
|
||||
aliases += [
|
||||
|
|
@ -16,12 +17,38 @@ if bashcompletiondir != 'no'
|
|||
'parec',
|
||||
'parecord',
|
||||
]
|
||||
=======
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
install_data('pulseaudio', install_dir : bashcompletiondir)
|
||||
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
|
||||
|
||||
foreach alias : aliases
|
||||
dst = join_paths(bashcompletiondir, alias)
|
||||
cmd = 'ln -fs @0@ $DESTDIR@1@'.format('pulseaudio', dst)
|
||||
cmd = 'ln -fs @0@ $DESTDIR@1@'.format('pactl', dst)
|
||||
meson.add_install_script('sh', '-c', cmd)
|
||||
endforeach
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -109,19 +109,26 @@ in_array() {
|
|||
}
|
||||
|
||||
_pactl() {
|
||||
local cur prev words cword preprev command
|
||||
local cur prev words cword preprev word 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 set-default-sink
|
||||
set-sink-port set-default-source set-source-port set-sink-volume
|
||||
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
|
||||
set-source-volume set-sink-input-volume set-source-output-volume
|
||||
<<<<<<< HEAD:shell-completion/bash/pulseaudio
|
||||
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)
|
||||
=======
|
||||
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)
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336:shell-completion/bash/pactl
|
||||
|
||||
_init_completion -n = || return
|
||||
preprev=${words[$cword-2]}
|
||||
|
|
@ -186,6 +193,8 @@ _pactl() {
|
|||
|
||||
remove-sample) ;; # TODO
|
||||
|
||||
get-default*) ;;
|
||||
|
||||
load-module)
|
||||
comps=$(__all_modules)
|
||||
COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
|
||||
|
|
@ -255,7 +264,7 @@ _pactl() {
|
|||
complete -F _pactl pactl
|
||||
|
||||
_pacmd() {
|
||||
local cur prev words cword preprev command
|
||||
local cur prev words cword preprev word command
|
||||
local comps
|
||||
local flags='-h --help --version'
|
||||
local commands=(exit help list-modules list-cards list-sinks list-sources list-clients
|
||||
|
|
@ -500,7 +509,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-pit-file=
|
||||
--log-backtrace= -p --dl-search-path= --resample-method= --use-pid-file=
|
||||
--no-cpu-limit= --disable-shm= --enable-memfd= -L --load= -F --file= -C -n'
|
||||
_init_completion -n = || return
|
||||
|
||||
|
|
@ -18,10 +18,12 @@ _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');;
|
||||
|
|
@ -257,16 +259,22 @@ _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'
|
||||
|
|
@ -492,11 +500,15 @@ _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,3 +1,5 @@
|
|||
if zshcompletiondir != 'no'
|
||||
install_data('_pulseaudio', install_dir : zshcompletiondir)
|
||||
if get_option('client')
|
||||
if zshcompletiondir != 'no'
|
||||
install_data('_pulseaudio', install_dir : zshcompletiondir)
|
||||
endif
|
||||
endif
|
||||
|
|
|
|||
1
src/.gitignore
vendored
1
src/.gitignore
vendored
|
|
@ -71,6 +71,7 @@ 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 debug, info, notice, warn, error)."));
|
||||
pa_log(_("--log-level expects log level argument (either numeric in range 0..4 or one of error, warn, notice, info, debug)."));
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -171,5 +171,9 @@ load-module module-filter-apply
|
|||
|
||||
### Allow including a default.pa.d directory, which if present, can be used
|
||||
### for additional configuration snippets.
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
### Note that those snippet files must have a .pa file extension, not .conf
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
.nofail
|
||||
.include @PA_DEFAULT_CONFIG_DIR_UNQUOTED@/default.pa.d
|
||||
|
|
|
|||
|
|
@ -30,8 +30,13 @@ executable('pulseaudio',
|
|||
install_rpath : privlibdir,
|
||||
include_directories : [configinc, topinc],
|
||||
link_args : ['-ffast-math'],
|
||||
<<<<<<< HEAD
|
||||
link_with : [libpulsecore, libpulsecommon, libpulse],
|
||||
dependencies : [ltdl_dep, cap_dep, dbus_dep, libsystemd_dep, dl_dep, libintl_dep, platform_dep, platform_socket_dep],
|
||||
=======
|
||||
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],
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
c_args : pa_c_args,
|
||||
)
|
||||
|
||||
|
|
@ -141,7 +146,7 @@ custom_target('system.pa',
|
|||
|
||||
if dbus_dep.found()
|
||||
install_data('pulseaudio-system.conf',
|
||||
install_dir : join_paths(sysconfdir, 'dbus-1', 'system.d')
|
||||
install_dir : join_paths(datadir, 'dbus-1', 'system.d')
|
||||
)
|
||||
endif
|
||||
|
||||
|
|
|
|||
|
|
@ -69,5 +69,9 @@ load-module module-position-event-sounds
|
|||
|
||||
### Allow including a system.pa.d directory, which if present, can be used
|
||||
### for additional configuration snippets.
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
### Note that those snippet files must have a .pa file extension, not .conf
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
.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,6 +182,7 @@ if host_machine.system() == 'windows'
|
|||
else
|
||||
libpulsecommon_sources += [
|
||||
'pulsecore/mutex-posix.c',
|
||||
<<<<<<< HEAD
|
||||
'pulsecore/semaphore-posix.c',
|
||||
'pulsecore/thread-posix.c'
|
||||
]
|
||||
|
|
@ -203,10 +204,49 @@ libpulsecommon = shared_library('pulsecommon-' + pa_version_major_minor,
|
|||
platform_dep, tcpwrap_dep, platform_socket_dep, execinfo_dep,
|
||||
],
|
||||
implicit_include_directories : false)
|
||||
=======
|
||||
'pulsecore/poll-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
|
||||
|
||||
libpulsecommon_dep = declare_dependency(link_with: libpulsecommon)
|
||||
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_dep = declare_dependency(link_with: libpulsecommon)
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
subdir('pulse')
|
||||
endif
|
||||
|
||||
<<<<<<< HEAD
|
||||
subdir('pulse')
|
||||
=======
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
if get_option('daemon')
|
||||
subdir('pulsecore')
|
||||
subdir('daemon')
|
||||
|
|
|
|||
|
|
@ -107,13 +107,22 @@ 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"
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
# 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"
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
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"
|
||||
<<<<<<< HEAD
|
||||
ATTRS{idVendor}=="08bb", ATTRS{idProduct}=="2902", ENV{PULSE_PROFILE_SET}="behringer-umc22.conf"
|
||||
=======
|
||||
ATTRS{idVendor}=="08bb", ATTRS{idProduct}=="2902", ENV{PULSE_PROFILE_SET}="texas-instruments-pcm2902.conf"
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
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"
|
||||
|
||||
|
|
@ -123,6 +132,11 @@ 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"
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
# ID 1038:1282 is for SteelSeries GameDAC
|
||||
ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1282", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf"
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
# ID 1038:12c4 is for Arctis 9
|
||||
ATTRS{idVendor}=="1038", ATTRS{idProduct}=="12c4", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf"
|
||||
# Lucidsound LS31
|
||||
|
|
@ -164,6 +178,19 @@ 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"
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
# 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"
|
||||
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
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,31 +2851,57 @@ static int path_verify(pa_alsa_path *p) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
static char *get_path_config_path(const char *paths_dir, const char *fname) {
|
||||
char *path_config_path;
|
||||
=======
|
||||
static char *get_data_path(const char *data_dir, const char *data_type, const char *fname) {
|
||||
char *result;
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
char *dir;
|
||||
char *data_home;
|
||||
pa_dynarray *data_dirs;
|
||||
|
||||
<<<<<<< HEAD
|
||||
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(path_config_path);
|
||||
=======
|
||||
if (data_dir) {
|
||||
result = pa_maybe_prefix_path(fname, data_dir);
|
||||
if (access(result, R_OK) == 0)
|
||||
return result;
|
||||
else
|
||||
pa_xfree(result);
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
}
|
||||
|
||||
#ifdef HAVE_RUNNING_FROM_BUILD_TREE
|
||||
if (pa_run_from_build_tree()) {
|
||||
<<<<<<< HEAD
|
||||
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(path_config_path);
|
||||
=======
|
||||
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;
|
||||
else
|
||||
pa_xfree(result);
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pa_get_data_home_dir(&data_home) == 0) {
|
||||
<<<<<<< HEAD
|
||||
dir = pa_sprintf_malloc("%s" PA_PATH_SEP "alsa-mixer" PA_PATH_SEP "paths", data_home);
|
||||
pa_xfree(data_home);
|
||||
|
||||
|
|
@ -2886,6 +2912,18 @@ static char *get_path_config_path(const char *paths_dir, const char *fname) {
|
|||
return path_config_path;
|
||||
else
|
||||
pa_xfree(path_config_path);
|
||||
=======
|
||||
dir = pa_sprintf_malloc("%s" PA_PATH_SEP "alsa-mixer" PA_PATH_SEP "%s", data_home, data_type);
|
||||
pa_xfree(data_home);
|
||||
|
||||
result = pa_maybe_prefix_path(fname, dir);
|
||||
pa_xfree(dir);
|
||||
|
||||
if (access(result, R_OK) == 0)
|
||||
return result;
|
||||
else
|
||||
pa_xfree(result);
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
}
|
||||
|
||||
if (pa_get_data_dirs(&data_dirs) == 0) {
|
||||
|
|
@ -2893,6 +2931,7 @@ static char *get_path_config_path(const char *paths_dir, const char *fname) {
|
|||
const char *n;
|
||||
|
||||
PA_DYNARRAY_FOREACH(n, data_dirs, idx) {
|
||||
<<<<<<< HEAD
|
||||
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);
|
||||
|
|
@ -2903,14 +2942,34 @@ static char *get_path_config_path(const char *paths_dir, const char *fname) {
|
|||
}
|
||||
else {
|
||||
pa_xfree(path_config_path);
|
||||
=======
|
||||
dir = pa_sprintf_malloc("%s" PA_PATH_SEP "alsa-mixer" PA_PATH_SEP "%s", n, data_type);
|
||||
result = pa_maybe_prefix_path(fname, dir);
|
||||
pa_xfree(dir);
|
||||
|
||||
if (access(result, R_OK) == 0) {
|
||||
pa_dynarray_free(data_dirs);
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
pa_xfree(result);
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
}
|
||||
}
|
||||
|
||||
pa_dynarray_free(data_dirs);
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
path_config_path = pa_maybe_prefix_path(fname, PA_ALSA_PATHS_DIR);
|
||||
return path_config_path;
|
||||
=======
|
||||
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;
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
}
|
||||
|
||||
pa_alsa_path* pa_alsa_path_new(const char *paths_dir, const char *fname, pa_alsa_direction_t direction) {
|
||||
|
|
@ -2977,7 +3036,11 @@ 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;
|
||||
|
||||
<<<<<<< HEAD
|
||||
fn = get_path_config_path(paths_dir, fname);
|
||||
=======
|
||||
fn = get_data_path(paths_dir, "paths", fname);
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
pa_log_info("Loading path config: %s", fn);
|
||||
|
||||
|
|
@ -4971,11 +5034,9 @@ pa_alsa_profile_set* pa_alsa_profile_set_new(const char *fname, const pa_channel
|
|||
if (!fname)
|
||||
fname = "default.conf";
|
||||
|
||||
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);
|
||||
fn = get_data_path(NULL, "profile-sets", fname);
|
||||
|
||||
pa_log_info("Loading profile set: %s", fn);
|
||||
|
||||
r = pa_config_parse(fn, NULL, items, NULL, false, ps);
|
||||
pa_xfree(fn);
|
||||
|
|
@ -5074,7 +5135,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, exact_channels);
|
||||
&try_buffer_size, 0, NULL, NULL, 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,6 +342,9 @@ 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,7 +52,12 @@
|
|||
#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>
|
||||
|
||||
|
|
@ -78,11 +83,15 @@
|
|||
#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 */
|
||||
|
||||
|
|
@ -156,11 +165,18 @@ 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;
|
||||
|
||||
|
|
@ -480,9 +496,13 @@ 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;
|
||||
|
|
@ -955,7 +975,10 @@ static void update_smoother(struct userdata *u) {
|
|||
snd_pcm_sframes_t delay = 0;
|
||||
int64_t position;
|
||||
int err;
|
||||
pa_usec_t now1 = 0, now2;
|
||||
pa_usec_t now1 = 0;
|
||||
#ifndef USE_SMOOTHER_2
|
||||
pa_usec_t now2;
|
||||
#endif
|
||||
snd_pcm_status_t *status;
|
||||
snd_htimestamp_t htstamp = { 0, 0 };
|
||||
|
||||
|
|
@ -978,13 +1001,16 @@ 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;
|
||||
|
||||
|
|
@ -995,18 +1021,26 @@ 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, now2;
|
||||
pa_usec_t now1;
|
||||
#ifndef USE_SMOOTHER_2
|
||||
pa_usec_t now2;
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
|
@ -1036,7 +1070,11 @@ 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);
|
||||
|
|
@ -1683,7 +1721,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, true);
|
||||
return pa_alsa_ucm_set_port(u->ucm_context, p);
|
||||
}
|
||||
|
||||
static int sink_set_port_cb(pa_sink *s, pa_device_port *p) {
|
||||
|
|
@ -1784,12 +1822,22 @@ 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;
|
||||
}
|
||||
|
|
@ -1799,11 +1847,17 @@ 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;
|
||||
}
|
||||
|
|
@ -1812,8 +1866,15 @@ 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 */
|
||||
}
|
||||
|
||||
|
|
@ -1947,7 +2008,11 @@ 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;
|
||||
}
|
||||
|
|
@ -1981,7 +2046,11 @@ 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);
|
||||
|
|
@ -2170,7 +2239,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, true) < 0)
|
||||
if (pa_alsa_ucm_set_port(u->ucm_context, u->sink->active_port) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -2281,7 +2350,15 @@ 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;
|
||||
<<<<<<< HEAD
|
||||
void *state;
|
||||
=======
|
||||
void *state = NULL;
|
||||
#ifdef USE_SMOOTHER_2
|
||||
snd_pcm_info_t* pcm_info;
|
||||
const char *id;
|
||||
#endif
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
pa_assert(m);
|
||||
pa_assert(ma);
|
||||
|
|
@ -2394,6 +2471,7 @@ 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,
|
||||
|
|
@ -2403,6 +2481,7 @@ 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)
|
||||
|
|
@ -2452,7 +2531,9 @@ 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, mapping)))
|
||||
&b, &d,
|
||||
&u->supported_formats, &u->supported_rates,
|
||||
mapping)))
|
||||
goto fail;
|
||||
|
||||
} else if ((dev_id = pa_modargs_get_value(ma, "device_id", NULL))) {
|
||||
|
|
@ -2466,7 +2547,9 @@ 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, profile_set, &mapping)))
|
||||
&b, &d,
|
||||
&u->supported_formats, &u->supported_rates,
|
||||
profile_set, &mapping)))
|
||||
goto fail;
|
||||
|
||||
} else {
|
||||
|
|
@ -2477,7 +2560,9 @@ 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, false)))
|
||||
&b, &d,
|
||||
&u->supported_formats, &u->supported_rates,
|
||||
false)))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
|
@ -2523,13 +2608,11 @@ 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;
|
||||
|
|
@ -2613,6 +2696,25 @@ 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;
|
||||
|
|
@ -2816,7 +2918,11 @@ 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,7 +47,12 @@
|
|||
#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>
|
||||
|
||||
|
|
@ -71,11 +76,15 @@
|
|||
#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)
|
||||
|
||||
|
|
@ -140,10 +149,17 @@ 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;
|
||||
|
|
@ -452,9 +468,13 @@ 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;
|
||||
|
|
@ -462,7 +482,12 @@ 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);
|
||||
|
|
@ -877,7 +902,10 @@ static void update_smoother(struct userdata *u) {
|
|||
snd_pcm_sframes_t delay = 0;
|
||||
uint64_t position;
|
||||
int err;
|
||||
pa_usec_t now1 = 0, now2;
|
||||
pa_usec_t now1 = 0;
|
||||
#ifndef USE_SMOOTHER_2
|
||||
pa_usec_t now2;
|
||||
#endif
|
||||
snd_pcm_status_t *status;
|
||||
snd_htimestamp_t htstamp = { 0, 0 };
|
||||
|
||||
|
|
@ -900,12 +928,16 @@ 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);
|
||||
|
|
@ -913,18 +945,27 @@ 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, now2;
|
||||
pa_usec_t now1;
|
||||
#ifndef USE_SMOOTHER_2
|
||||
pa_usec_t now2;
|
||||
#endif
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -1554,7 +1595,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, false);
|
||||
return pa_alsa_ucm_set_port(u->ucm_context, p);
|
||||
}
|
||||
|
||||
static int source_set_port_cb(pa_source *s, pa_device_port *p) {
|
||||
|
|
@ -1596,12 +1637,22 @@ 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;
|
||||
}
|
||||
|
|
@ -1611,11 +1662,17 @@ 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;
|
||||
}
|
||||
|
|
@ -1624,7 +1681,15 @@ 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) {
|
||||
|
|
@ -1658,7 +1723,11 @@ 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;
|
||||
}
|
||||
|
|
@ -1686,7 +1755,11 @@ 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); */
|
||||
|
||||
|
|
@ -1870,7 +1943,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, false) < 0)
|
||||
if (pa_alsa_ucm_set_port(u->ucm_context, u->source->active_port) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -2085,6 +2158,7 @@ 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,
|
||||
|
|
@ -2094,6 +2168,7 @@ 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)
|
||||
|
|
@ -2143,7 +2218,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, mapping)))
|
||||
&b, &d, &u->supported_formats, &u->supported_rates, mapping)))
|
||||
goto fail;
|
||||
|
||||
} else if ((dev_id = pa_modargs_get_value(ma, "device_id", NULL))) {
|
||||
|
|
@ -2157,7 +2232,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, profile_set, &mapping)))
|
||||
&b, &d, &u->supported_formats, &u->supported_rates, profile_set, &mapping)))
|
||||
goto fail;
|
||||
|
||||
} else {
|
||||
|
|
@ -2168,7 +2243,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, false)))
|
||||
&b, &d, &u->supported_formats, &u->supported_rates, false)))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
|
@ -2204,13 +2279,11 @@ 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;
|
||||
|
|
@ -2293,6 +2366,10 @@ 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;
|
||||
|
|
@ -2454,7 +2531,11 @@ 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,12 +140,13 @@ 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, const char *new_profile, const char *old_profile);
|
||||
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_get_verb(snd_use_case_mgr_t *uc_mgr, const char *verb_name, const char *verb_desc, pa_alsa_ucm_verb **p_verb);
|
||||
|
||||
|
|
@ -157,14 +158,14 @@ void pa_alsa_ucm_add_ports(
|
|||
pa_card *card,
|
||||
snd_pcm_t *pcm_handle,
|
||||
bool ignore_dB);
|
||||
void pa_alsa_ucm_add_ports_combination(
|
||||
void pa_alsa_ucm_add_port(
|
||||
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, bool is_sink);
|
||||
int pa_alsa_ucm_set_port(pa_alsa_ucm_mapping_context *context, pa_device_port *port);
|
||||
|
||||
void pa_alsa_ucm_free(pa_alsa_ucm_config *ucm);
|
||||
void pa_alsa_ucm_mapping_context_free(pa_alsa_ucm_mapping_context *context);
|
||||
|
|
@ -221,11 +222,8 @@ struct pa_alsa_ucm_modifier {
|
|||
|
||||
pa_proplist *proplist;
|
||||
|
||||
int n_confdev;
|
||||
int n_suppdev;
|
||||
|
||||
const char **conflicting_devices;
|
||||
const char **supported_devices;
|
||||
pa_idxset *conflicting_devices;
|
||||
pa_idxset *supported_devices;
|
||||
|
||||
pa_direction_t action_direction;
|
||||
|
||||
|
|
@ -253,6 +251,7 @@ 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);
|
||||
|
|
@ -263,21 +262,23 @@ struct pa_alsa_ucm_mapping_context {
|
|||
pa_alsa_ucm_config *ucm;
|
||||
pa_direction_t direction;
|
||||
|
||||
pa_idxset *ucm_devices;
|
||||
pa_idxset *ucm_modifiers;
|
||||
pa_alsa_ucm_device *ucm_device;
|
||||
pa_alsa_ucm_modifier *ucm_modifier;
|
||||
};
|
||||
|
||||
struct pa_alsa_ucm_profile_context {
|
||||
pa_alsa_ucm_verb *verb;
|
||||
};
|
||||
|
||||
struct pa_alsa_ucm_port_data {
|
||||
pa_alsa_ucm_config *ucm;
|
||||
pa_device_port *core_port;
|
||||
|
||||
/* A single port will be associated with multiple devices if it represents
|
||||
* a combination of devices. */
|
||||
pa_dynarray *devices; /* pa_alsa_ucm_device */
|
||||
pa_alsa_ucm_device *device;
|
||||
|
||||
/* profile name -> pa_alsa_path for volume control */
|
||||
/* verb name -> pa_alsa_path for volume control */
|
||||
pa_hashmap *paths;
|
||||
/* Current path, set when activating profile */
|
||||
/* Current path, set when activating verb */
|
||||
pa_alsa_path *path;
|
||||
|
||||
/* ELD info */
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
#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"
|
||||
|
|
@ -522,6 +523,8 @@ 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) {
|
||||
|
||||
|
|
@ -560,6 +563,8 @@ 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) {
|
||||
|
|
@ -587,6 +592,8 @@ 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) {
|
||||
|
|
@ -611,6 +618,8 @@ 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);
|
||||
|
||||
|
|
@ -631,6 +640,8 @@ 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;
|
||||
|
|
@ -660,6 +671,8 @@ 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)
|
||||
|
|
@ -683,6 +696,8 @@ 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;
|
||||
|
|
@ -710,6 +725,12 @@ 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,
|
||||
|
|
@ -783,6 +804,8 @@ 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;
|
||||
|
|
@ -804,6 +827,8 @@ 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);
|
||||
|
|
@ -1406,13 +1431,31 @@ 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,
|
||||
384000 };
|
||||
352800, 384000,
|
||||
705600, 768000 };
|
||||
bool supported[PA_ELEMENTSOF(all_rates)] = { false, };
|
||||
snd_pcm_hw_params_t *hwparams;
|
||||
unsigned int i, j, n, *rates = NULL;
|
||||
|
|
@ -1454,39 +1497,40 @@ 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_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 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 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,
|
||||
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,
|
||||
};
|
||||
bool supported[PA_ELEMENTSOF(all_formats)] = {
|
||||
false,
|
||||
|
|
@ -1504,7 +1548,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, all_formats[i]) == 0) {
|
||||
if (snd_pcm_hw_params_test_format(pcm, hwparams, format_trans_to_pcm[all_formats[i]]) == 0) {
|
||||
supported[i] = true;
|
||||
n++;
|
||||
}
|
||||
|
|
@ -1515,7 +1559,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++] = format_trans_to_pa[all_formats[i]];
|
||||
formats[j++] = all_formats[i];
|
||||
}
|
||||
|
||||
formats[j] = PA_SAMPLE_MAX;
|
||||
|
|
@ -1523,7 +1567,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_pa[formats[0]])) < 0) {
|
||||
if ((ret = snd_pcm_hw_params_set_format(pcm, hwparams, format_trans_to_pcm[formats[0]])) < 0) {
|
||||
pa_log_debug("snd_pcm_hw_params_set_format() failed: %s", pa_alsa_strerror(ret));
|
||||
pa_xfree(formats);
|
||||
return NULL;
|
||||
|
|
@ -1614,14 +1658,16 @@ 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 device,
|
||||
unsigned int subdevice) {
|
||||
snd_mixer_elem_t *elem;
|
||||
|
||||
for (elem = snd_mixer_first_elem(mixer); elem; elem = snd_mixer_elem_next(elem)) {
|
||||
snd_hctl_elem_t *helem;
|
||||
snd_hctl_elem_t **_helem, *helem;
|
||||
if (snd_mixer_elem_get_type(elem) != SND_MIXER_ELEM_PULSEAUDIO)
|
||||
continue;
|
||||
helem = snd_mixer_elem_get_private(elem);
|
||||
_helem = snd_mixer_elem_get_private(elem);
|
||||
helem = *_helem;
|
||||
if (snd_hctl_elem_get_interface(helem) != iface)
|
||||
continue;
|
||||
if (!pa_streq(snd_hctl_elem_get_name(helem), name))
|
||||
|
|
@ -1630,17 +1676,23 @@ 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) {
|
||||
<<<<<<< HEAD
|
||||
return pa_alsa_mixer_find(mixer, SND_CTL_ELEM_IFACE_CARD, alsa_id->name, alsa_id->index, device);
|
||||
=======
|
||||
return pa_alsa_mixer_find(mixer, SND_CTL_ELEM_IFACE_CARD, alsa_id->name, alsa_id->index, device, 0);
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
}
|
||||
|
||||
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);
|
||||
return pa_alsa_mixer_find(mixer, SND_CTL_ELEM_IFACE_PCM, name, 0, device, 0);
|
||||
}
|
||||
|
||||
static int mixer_class_compare(const snd_mixer_elem_t *c1, const snd_mixer_elem_t *c2)
|
||||
|
|
@ -1649,31 +1701,79 @@ 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);
|
||||
if (mask & SND_CTL_EVENT_MASK_ADD) {
|
||||
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) {
|
||||
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;
|
||||
|
||||
/* 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;
|
||||
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;
|
||||
}
|
||||
|
||||
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 ((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 (!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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1687,14 +1787,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) {
|
||||
static int prepare_mixer(snd_mixer_t *mixer, const char *dev, snd_hctl_t *hctl) {
|
||||
int err;
|
||||
snd_mixer_class_t *class;
|
||||
|
||||
pa_assert(mixer);
|
||||
pa_assert(dev);
|
||||
|
||||
if ((err = snd_mixer_attach(mixer, dev)) < 0) {
|
||||
if ((err = snd_mixer_attach_hctl(mixer, hctl)) < 0) {
|
||||
pa_log_info("Unable to attach to mixer %s: %s", dev, pa_alsa_strerror(err));
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -1733,17 +1833,30 @@ 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);
|
||||
<<<<<<< HEAD
|
||||
|
||||
/* The quick card number/index lookup (hw:#)
|
||||
* We already know the card number/index, thus use the mixer
|
||||
|
|
@ -1764,6 +1877,8 @@ snd_mixer_t *pa_alsa_open_mixer_by_name(pa_hashmap *mixers, const char *dev, boo
|
|||
}
|
||||
}
|
||||
|
||||
=======
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
if (pm) {
|
||||
if (!probe)
|
||||
pm->used_for_probe_only = false;
|
||||
|
|
@ -1775,27 +1890,55 @@ snd_mixer_t *pa_alsa_open_mixer_by_name(pa_hashmap *mixers, const char *dev, boo
|
|||
return NULL;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
pm->used_for_probe_only = probe;
|
||||
pm->mixer_handle = m;
|
||||
pa_hashmap_put(mixers, pa_xstrdup(dev), pm);
|
||||
return m;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
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)
|
||||
return m;
|
||||
}
|
||||
|
||||
__close:
|
||||
snd_mixer_close(m);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -1836,8 +1979,10 @@ void pa_alsa_mixer_free(pa_alsa_mixer *mixer)
|
|||
{
|
||||
if (mixer->fdl)
|
||||
pa_alsa_fdlist_free(mixer->fdl);
|
||||
if (mixer->mixer_handle)
|
||||
if (mixer->mixer_handle && mixer->alias == NULL)
|
||||
snd_mixer_close(mixer->mixer_handle);
|
||||
if (mixer->alias)
|
||||
mixer->alias->alias = NULL;
|
||||
pa_xfree(mixer);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,6 +67,8 @@ 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 */
|
||||
|
||||
|
|
@ -82,6 +84,8 @@ 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 */
|
||||
|
|
@ -96,6 +100,8 @@ 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 */
|
||||
|
|
@ -111,6 +117,8 @@ 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);
|
||||
|
|
|
|||
91
src/modules/alsa/mixer/profile-sets/asus-xonar-se.conf
Normal file
91
src/modules/alsa/mixer/profile-sets/asus-xonar-se.conf
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
# 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
|
||||
|
|
@ -39,7 +39,11 @@ channel-map = aux0,aux1,left,right,aux2,aux3
|
|||
direction = output
|
||||
|
||||
[Mapping stereo-out-ef]
|
||||
<<<<<<< HEAD
|
||||
description = Analog Stereo 5/6
|
||||
=======
|
||||
description = Stereo 5/6 (S/PDIF)
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
device-strings = hw:%f,0,0
|
||||
channel-map = aux0,aux1,aux2,aux3,left,right
|
||||
direction = output
|
||||
|
|
@ -51,7 +55,11 @@ channel-map = mono,aux0,aux1,aux2,aux3,aux4
|
|||
direction = input
|
||||
|
||||
[Mapping analog-mono-in-b]
|
||||
<<<<<<< HEAD
|
||||
description = Anlog Mono Input 2
|
||||
=======
|
||||
description = Analog Mono Input 2
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
device-strings = hw:%f,0,0
|
||||
channel-map = aux0,mono,aux1,aux2,aux3,aux4
|
||||
direction = input
|
||||
|
|
@ -69,7 +77,11 @@ channel-map = aux0,aux1,left,right,aux2,aux3
|
|||
direction = input
|
||||
|
||||
[Mapping stereo-in-ef]
|
||||
<<<<<<< HEAD
|
||||
description = Stereo Input 5/6
|
||||
=======
|
||||
description = Stereo Input 5/6 (S/PDIF)
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
device-strings = hw:%f,0,0
|
||||
channel-map = aux0,aux1,aux2,aux3,left,right
|
||||
direction = input
|
||||
|
|
|
|||
|
|
@ -0,0 +1,75 @@
|
|||
# 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/>.
|
||||
|
||||
; Texas Instruments PCM2902
|
||||
;
|
||||
; 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".
|
||||
;
|
||||
; Behringer UMC22 has stereo input (representing two physical mono inputs),
|
||||
; others have mono input.
|
||||
;
|
||||
; 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 also removes default digital input/output mappings that do
|
||||
; not physically exist on cards that we've seen so far.
|
||||
;
|
||||
; Originally added by Nazar Mokrynskyi <nazar@mokrynskyi.com> for Behringer
|
||||
; UMC22.
|
||||
|
||||
[General]
|
||||
auto-profiles = yes
|
||||
|
||||
[Mapping analog-stereo-input]
|
||||
device-strings = hw:%f
|
||||
channel-map = left,right
|
||||
paths-input = analog-input-mic analog-input
|
||||
direction = input
|
||||
priority = 4
|
||||
|
||||
[Mapping analog-mono]
|
||||
device-strings = hw:%f
|
||||
channel-map = mono
|
||||
paths-input = analog-input-mic analog-input
|
||||
direction = input
|
||||
priority = 3
|
||||
|
||||
[Mapping analog-mono-left]
|
||||
device-strings = hw:%f
|
||||
channel-map = mono,aux1
|
||||
paths-input = analog-input-mic analog-input
|
||||
direction = input
|
||||
priority = 2
|
||||
|
||||
[Mapping analog-mono-right]
|
||||
device-strings = hw:%f
|
||||
channel-map = aux1,mono
|
||||
paths-input = analog-input-mic analog-input
|
||||
direction = input
|
||||
priority = 1
|
||||
|
||||
[Mapping analog-stereo-output]
|
||||
device-strings = front:%f
|
||||
channel-map = left,right
|
||||
paths-output = analog-output
|
||||
direction = output
|
||||
|
|
@ -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_ports_combination(NULL, &m->ucm_context, true, ports, cp, u->core);
|
||||
pa_alsa_ucm_add_port(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_ports_combination(NULL, &m->ucm_context, false, ports, cp, u->core);
|
||||
pa_alsa_ucm_add_port(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,8 +249,7 @@ 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 ? nd->profile->name : NULL,
|
||||
od->profile ? od->profile->name : NULL) < 0) {
|
||||
if (pa_alsa_ucm_set_profile(&u->ucm, c, nd->profile, od->profile) < 0) {
|
||||
ret = -1;
|
||||
goto finish;
|
||||
}
|
||||
|
|
@ -302,7 +301,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->name, NULL) < 0) {
|
||||
if (pa_alsa_ucm_set_profile(ucm, u->card, d->profile, NULL) < 0) {
|
||||
pa_log("Failed to set ucm profile %s", d->profile->name);
|
||||
return;
|
||||
}
|
||||
|
|
@ -371,7 +370,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);
|
||||
snd_hctl_elem_t **_elem = snd_mixer_elem_get_private(melem), *elem;
|
||||
snd_ctl_elem_value_t *elem_value;
|
||||
bool plugged_in;
|
||||
void *state;
|
||||
|
|
@ -381,6 +380,8 @@ 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
|
||||
|
|
@ -563,13 +564,18 @@ 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);
|
||||
int device = snd_hctl_elem_get_device(elem);
|
||||
snd_hctl_elem_t **_elem = snd_mixer_elem_get_private(melem), *elem;
|
||||
int device;
|
||||
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,8 +42,8 @@ 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);
|
||||
|
||||
/* Returns true if the codec can be supported on the system */
|
||||
bool (*can_be_supported)(bool for_encoding);
|
||||
|
|
|
|||
|
|
@ -490,7 +490,11 @@ 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;
|
||||
|
||||
<<<<<<< HEAD
|
||||
written = gst_transcode_buffer(codec_info, input_buffer, input_size, output_buffer, output_size, processed);
|
||||
=======
|
||||
written = gst_transcode_buffer(codec_info, timestamp, input_buffer, input_size, output_buffer, output_size, processed);
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
if (PA_UNLIKELY(*processed == 0 || *processed != input_size))
|
||||
pa_log_error("aptX encoding error");
|
||||
|
||||
|
|
@ -526,7 +530,11 @@ 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;
|
||||
|
||||
<<<<<<< HEAD
|
||||
written = gst_transcode_buffer(codec_info, input_buffer, input_size, output_buffer, output_size, processed);
|
||||
=======
|
||||
written = gst_transcode_buffer(codec_info, -1, input_buffer, input_size, output_buffer, output_size, processed);
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
/* 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,7 +564,10 @@ 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 },
|
||||
<<<<<<< HEAD
|
||||
.support_backchannel = false,
|
||||
=======
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
.can_be_supported = can_be_supported,
|
||||
.can_accept_capabilities = can_accept_capabilities,
|
||||
.choose_remote_endpoint = choose_remote_endpoint,
|
||||
|
|
@ -580,7 +591,10 @@ 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 },
|
||||
<<<<<<< HEAD
|
||||
.support_backchannel = false,
|
||||
=======
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
.can_be_supported = can_be_supported,
|
||||
.can_accept_capabilities = can_accept_capabilities_hd,
|
||||
.choose_remote_endpoint = choose_remote_endpoint_hd,
|
||||
|
|
|
|||
|
|
@ -22,12 +22,20 @@
|
|||
#endif
|
||||
|
||||
#include <arpa/inet.h>
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
#include <stdint.h>
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
#include <pulsecore/log.h>
|
||||
#include <pulsecore/macro.h>
|
||||
#include <pulsecore/once.h>
|
||||
#include <pulsecore/core-util.h>
|
||||
#include <pulse/sample.h>
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
#include <pulse/timeval.h>
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
#include <pulse/util.h>
|
||||
|
||||
#include "a2dp-codecs.h"
|
||||
|
|
@ -39,6 +47,7 @@ static void app_sink_eos(GstAppSink *appsink, gpointer userdata) {
|
|||
pa_log_debug("Sink got EOS");
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
/* Called from the GStreamer streaming thread */
|
||||
static GstFlowReturn app_sink_new_sample(GstAppSink *appsink, gpointer userdata) {
|
||||
struct gst_info *info = (struct gst_info *) userdata;
|
||||
|
|
@ -116,6 +125,21 @@ bool gst_init_common(struct gst_info *info) {
|
|||
goto fail;
|
||||
}
|
||||
g_object_set(appsrc, "is-live", FALSE, "format", GST_FORMAT_TIME, "stream-type", 0, "max-bytes", 0, NULL);
|
||||
=======
|
||||
static void gst_deinit_common(struct gst_info *info) {
|
||||
if (!info)
|
||||
return;
|
||||
if (info->app_sink)
|
||||
gst_object_unref(info->app_sink);
|
||||
if (info->bin)
|
||||
gst_object_unref(info->bin);
|
||||
}
|
||||
|
||||
bool gst_init_common(struct gst_info *info) {
|
||||
GstElement *bin = NULL;
|
||||
GstElement *appsink = NULL;
|
||||
GstAppSinkCallbacks callbacks = { 0, };
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
appsink = gst_element_factory_make("appsink", "app_sink");
|
||||
if (!appsink) {
|
||||
|
|
@ -125,6 +149,7 @@ 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;
|
||||
<<<<<<< HEAD
|
||||
callbacks.new_sample = app_sink_new_sample;
|
||||
gst_app_sink_set_callbacks(GST_APP_SINK(appsink), &callbacks, info, NULL);
|
||||
|
||||
|
|
@ -143,18 +168,31 @@ bool gst_init_common(struct gst_info *info) {
|
|||
info->sink_adapter = adapter;
|
||||
info->pipeline = pipeline;
|
||||
info->sample_ready_fdsem = pa_fdsem_new();
|
||||
=======
|
||||
gst_app_sink_set_callbacks(GST_APP_SINK(appsink), &callbacks, info, NULL);
|
||||
|
||||
bin = gst_bin_new(NULL);
|
||||
pa_assert(bin);
|
||||
|
||||
info->app_sink = appsink;
|
||||
info->bin = bin;
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
return true;
|
||||
|
||||
fail:
|
||||
<<<<<<< HEAD
|
||||
if (appsrc)
|
||||
gst_object_unref(appsrc);
|
||||
=======
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
if (appsink)
|
||||
gst_object_unref(appsink);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
/*
|
||||
* 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
|
||||
|
|
@ -194,6 +232,12 @@ static GstCaps *gst_create_caps_from_sample_spec(const pa_sample_spec *ss) {
|
|||
gchar *sample_format;
|
||||
GstCaps *caps;
|
||||
int channel_mask;
|
||||
=======
|
||||
static GstCaps *gst_create_caps_from_sample_spec(const pa_sample_spec *ss) {
|
||||
gchar *sample_format;
|
||||
GstCaps *caps;
|
||||
uint64_t channel_mask;
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
switch (ss->format) {
|
||||
case PA_SAMPLE_S16LE:
|
||||
|
|
@ -240,6 +284,13 @@ 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;
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
GstEvent *event;
|
||||
GstSegment segment;
|
||||
GstEvent *stream_start;
|
||||
guint group_id;
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
pa_assert(transcoder);
|
||||
|
||||
|
|
@ -248,6 +299,7 @@ bool gst_codec_init(struct gst_info *info, bool for_encoding, GstElement *transc
|
|||
if (!gst_init_common(info))
|
||||
goto common_fail;
|
||||
|
||||
<<<<<<< HEAD
|
||||
caps = gst_create_caps_from_sample_spec(info->ss);
|
||||
if (for_encoding)
|
||||
g_object_set(info->app_src, "caps", caps, NULL);
|
||||
|
|
@ -259,19 +311,62 @@ bool gst_codec_init(struct gst_info *info, bool for_encoding, GstElement *transc
|
|||
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)) {
|
||||
=======
|
||||
gst_bin_add_many(GST_BIN(info->bin), transcoder, info->app_sink, NULL);
|
||||
|
||||
if (!gst_element_link_many(transcoder, info->app_sink, NULL)) {
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
pa_log_error("Failed to link codec elements into pipeline");
|
||||
goto pipeline_fail;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
if (gst_element_set_state(info->pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
|
||||
=======
|
||||
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) {
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
pa_log_error("Could not start pipeline");
|
||||
goto pipeline_fail;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
/* 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);
|
||||
=======
|
||||
/* 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);
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
pa_log_info("GStreamer pipeline initialisation succeeded");
|
||||
|
||||
|
|
@ -295,6 +390,7 @@ common_fail:
|
|||
return false;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
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 available, transcoded;
|
||||
|
|
@ -311,11 +407,48 @@ size_t gst_transcode_buffer(void *codec_info, const uint8_t *input_buffer, size_
|
|||
gst_buffer_unmap(in_buf, &map_info);
|
||||
|
||||
ret = gst_app_src_push_buffer(GST_APP_SRC(info->app_src), in_buf);
|
||||
=======
|
||||
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) {
|
||||
struct gst_info *info = (struct gst_info *) codec_info;
|
||||
gsize transcoded;
|
||||
GstBuffer *in_buf;
|
||||
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);
|
||||
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));
|
||||
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
if (ret != GST_FLOW_OK) {
|
||||
pa_log_error("failed to push buffer for transcoding %d", ret);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
pa_fdsem_wait(info->sample_ready_fdsem);
|
||||
|
||||
available = gst_adapter_available(info->sink_adapter);
|
||||
|
|
@ -329,6 +462,21 @@ size_t gst_transcode_buffer(void *codec_info, const uint8_t *input_buffer, size_
|
|||
written += transcoded;
|
||||
} else
|
||||
pa_log_debug("No transcoded data available in adapter");
|
||||
=======
|
||||
while ((sample = gst_app_sink_try_pull_sample(GST_APP_SINK(info->app_sink), 0))) {
|
||||
in_buf = gst_sample_get_buffer(sample);
|
||||
|
||||
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);
|
||||
}
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
*processed = input_size;
|
||||
|
||||
|
|
@ -343,6 +491,7 @@ fail:
|
|||
void gst_codec_deinit(void *codec_info) {
|
||||
struct gst_info *info = (struct gst_info *) codec_info;
|
||||
|
||||
<<<<<<< HEAD
|
||||
if (info->sample_ready_fdsem)
|
||||
pa_fdsem_free(info->sample_ready_fdsem);
|
||||
|
||||
|
|
@ -354,6 +503,15 @@ void gst_codec_deinit(void *codec_info) {
|
|||
|
||||
if (info->sink_adapter)
|
||||
g_object_unref(info->sink_adapter);
|
||||
=======
|
||||
if (info->bin) {
|
||||
gst_element_set_state(info->bin, GST_STATE_NULL);
|
||||
gst_object_unref(info->bin);
|
||||
}
|
||||
|
||||
if (info->pad_sink)
|
||||
gst_object_unref(GST_OBJECT(info->pad_sink));
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
pa_xfree(info);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,15 +43,27 @@ struct gst_info {
|
|||
const a2dp_ldac_t *ldac_config;
|
||||
} a2dp_codec_t;
|
||||
|
||||
<<<<<<< HEAD
|
||||
GstElement *app_src, *app_sink;
|
||||
GstElement *pipeline;
|
||||
GstAdapter *sink_adapter;
|
||||
|
||||
pa_fdsem *sample_ready_fdsem;
|
||||
=======
|
||||
/* 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;
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
uint16_t seq_num;
|
||||
};
|
||||
|
||||
bool gst_codec_init(struct gst_info *info, bool for_encoding, GstElement *transcoder);
|
||||
<<<<<<< HEAD
|
||||
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);
|
||||
=======
|
||||
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);
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
void gst_codec_deinit(void *codec_info);
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ static bool can_be_supported(bool for_encoding) {
|
|||
}
|
||||
gst_object_unref(element_factory);
|
||||
|
||||
<<<<<<< HEAD
|
||||
element_factory = gst_element_factory_find("rtpldacpay");
|
||||
if (element_factory == NULL) {
|
||||
pa_log_info("LDAC RTP payloader element `rtpldacpay` not found");
|
||||
|
|
@ -53,6 +54,8 @@ static bool can_be_supported(bool for_encoding) {
|
|||
}
|
||||
gst_object_unref(element_factory);
|
||||
|
||||
=======
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -206,7 +209,10 @@ static uint8_t fill_preferred_configuration(const pa_sample_spec *default_sample
|
|||
|
||||
GstElement *gst_init_ldac(struct gst_info *info, pa_sample_spec *ss, bool for_encoding) {
|
||||
GstElement *bin;
|
||||
<<<<<<< HEAD
|
||||
GstElement *rtpldacpay;
|
||||
=======
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
GstElement *enc;
|
||||
GstPad *pad;
|
||||
|
||||
|
|
@ -270,6 +276,7 @@ GstElement *gst_init_ldac(struct gst_info *info, pa_sample_spec *ss, bool for_en
|
|||
goto fail;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
rtpldacpay = gst_element_factory_make("rtpldacpay", "rtp_ldac_pay");
|
||||
if (!rtpldacpay) {
|
||||
pa_log_error("Could not create RTP LDAC payloader element");
|
||||
|
|
@ -286,12 +293,22 @@ GstElement *gst_init_ldac(struct gst_info *info, pa_sample_spec *ss, bool for_en
|
|||
gst_object_unref(bin);
|
||||
return NULL;
|
||||
}
|
||||
=======
|
||||
bin = gst_bin_new("ldac_enc_bin");
|
||||
pa_assert(bin);
|
||||
|
||||
gst_bin_add_many(GST_BIN(bin), enc, NULL);
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
pad = gst_element_get_static_pad(enc, "sink");
|
||||
pa_assert_se(gst_element_add_pad(bin, gst_ghost_pad_new("sink", pad)));
|
||||
gst_object_unref(GST_OBJECT(pad));
|
||||
|
||||
<<<<<<< HEAD
|
||||
pad = gst_element_get_static_pad(rtpldacpay, "src");
|
||||
=======
|
||||
pad = gst_element_get_static_pad(enc, "src");
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
pa_assert_se(gst_element_add_pad(bin, gst_ghost_pad_new("src", pad)));
|
||||
gst_object_unref(GST_OBJECT(pad));
|
||||
|
||||
|
|
@ -421,18 +438,51 @@ 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) {
|
||||
<<<<<<< HEAD
|
||||
size_t written;
|
||||
|
||||
written = gst_transcode_buffer(codec_info, input_buffer, input_size, output_buffer, output_size, processed);
|
||||
if (PA_UNLIKELY(*processed != input_size))
|
||||
pa_log_error("LDAC encoding error");
|
||||
|
||||
=======
|
||||
struct gst_info *info = (struct gst_info *) codec_info;
|
||||
struct rtp_header *header;
|
||||
struct rtp_payload *payload;
|
||||
size_t written;
|
||||
|
||||
if (PA_UNLIKELY(output_size < sizeof(*header) + sizeof(*payload))) {
|
||||
*processed = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
written = gst_transcode_buffer(codec_info, timestamp, input_buffer, input_size, output_buffer + sizeof(*header) + sizeof(*payload), output_size - sizeof(*header) - sizeof(*payload), processed);
|
||||
if (PA_UNLIKELY(*processed != input_size))
|
||||
pa_log_error("LDAC encoding error");
|
||||
|
||||
if (PA_LIKELY(written > 0)) {
|
||||
header = (struct rtp_header *) output_buffer;
|
||||
pa_zero(*header);
|
||||
header->v = 2;
|
||||
header->pt = 96;
|
||||
header->sequence_number = htons(info->seq_num++);
|
||||
header->timestamp = htonl(timestamp);
|
||||
header->ssrc = htonl(1);
|
||||
payload = (struct rtp_payload*) (output_buffer + sizeof(*header));
|
||||
payload->frame_count = get_ldac_num_frames(codec_info, info->codec_type);
|
||||
written += sizeof(*header) + sizeof(*payload);
|
||||
}
|
||||
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
return written;
|
||||
}
|
||||
|
||||
const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_ldac_eqmid_hq = {
|
||||
.id = { A2DP_CODEC_VENDOR, LDAC_VENDOR_ID, LDAC_CODEC_ID },
|
||||
<<<<<<< HEAD
|
||||
.support_backchannel = false,
|
||||
=======
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
.can_be_supported = can_be_supported,
|
||||
.can_accept_capabilities = can_accept_capabilities,
|
||||
.choose_remote_endpoint = choose_remote_endpoint,
|
||||
|
|
@ -455,7 +505,10 @@ const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_ldac_eqmid_hq = {
|
|||
|
||||
const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_ldac_eqmid_sq = {
|
||||
.id = { A2DP_CODEC_VENDOR, LDAC_VENDOR_ID, LDAC_CODEC_ID },
|
||||
<<<<<<< HEAD
|
||||
.support_backchannel = false,
|
||||
=======
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
.can_be_supported = can_be_supported,
|
||||
.can_accept_capabilities = can_accept_capabilities,
|
||||
.choose_remote_endpoint = choose_remote_endpoint,
|
||||
|
|
@ -478,7 +531,10 @@ const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_ldac_eqmid_sq = {
|
|||
|
||||
const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_ldac_eqmid_mq = {
|
||||
.id = { A2DP_CODEC_VENDOR, LDAC_VENDOR_ID, LDAC_CODEC_ID },
|
||||
<<<<<<< HEAD
|
||||
.support_backchannel = false,
|
||||
=======
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
.can_be_supported = can_be_supported,
|
||||
.can_accept_capabilities = can_accept_capabilities,
|
||||
.choose_remote_endpoint = choose_remote_endpoint,
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -52,6 +52,10 @@ extern const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_ldac_eqmid_hq;
|
|||
extern const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_ldac_eqmid_sq;
|
||||
extern const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_ldac_eqmid_mq;
|
||||
#endif
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
extern const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_faststream;
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
/* This is list of supported codecs. Their order is important.
|
||||
* Codec with lower index has higher priority. */
|
||||
|
|
@ -69,6 +73,10 @@ static const pa_a2dp_endpoint_conf *pa_a2dp_endpoint_configurations[] = {
|
|||
&pa_a2dp_endpoint_conf_sbc_xq_453,
|
||||
&pa_a2dp_endpoint_conf_sbc_xq_512,
|
||||
&pa_a2dp_endpoint_conf_sbc_xq_552,
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
&pa_a2dp_endpoint_conf_faststream,
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
};
|
||||
|
||||
unsigned int pa_bluetooth_a2dp_endpoint_conf_count(void) {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@
|
|||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <pulse/util.h>
|
||||
|
||||
#include <pulsecore/shared.h>
|
||||
#include <pulsecore/core-error.h>
|
||||
#include <pulsecore/core-util.h>
|
||||
|
|
@ -36,15 +38,34 @@
|
|||
|
||||
#include "bluez5-util.h"
|
||||
#include "bt-codec-msbc.h"
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
#include "upower.h"
|
||||
|
||||
#define MANDATORY_CALL_INDICATORS \
|
||||
"(\"call\",(0-1))," \
|
||||
"(\"callsetup\",(0-3))," \
|
||||
"(\"callheld\",(0-2))" \
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
struct pa_bluetooth_backend {
|
||||
pa_core *core;
|
||||
pa_dbus_connection *connection;
|
||||
pa_bluetooth_discovery *discovery;
|
||||
pa_hook_slot *adapter_uuids_changed_slot;
|
||||
<<<<<<< HEAD
|
||||
bool enable_shared_profiles;
|
||||
bool enable_hsp_hs;
|
||||
bool enable_hfp_hf;
|
||||
=======
|
||||
pa_hook_slot *host_battery_level_changed_slot;
|
||||
pa_upower_backend *upower;
|
||||
bool enable_shared_profiles;
|
||||
bool enable_hsp_hs;
|
||||
bool enable_hfp_hf;
|
||||
bool cmer_indicator_reporting_enabled;
|
||||
uint32_t cind_enabled_indicators;
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
PA_LLIST_HEAD(pa_dbus_pending, pending);
|
||||
};
|
||||
|
|
@ -55,6 +76,7 @@ struct transport_data {
|
|||
int sco_fd;
|
||||
pa_io_event *sco_io;
|
||||
pa_mainloop_api *mainloop;
|
||||
pa_bluetooth_backend *backend;
|
||||
};
|
||||
|
||||
struct hfp_config {
|
||||
|
|
@ -65,6 +87,37 @@ struct hfp_config {
|
|||
bool supports_indicators;
|
||||
int selected_codec;
|
||||
};
|
||||
<<<<<<< HEAD
|
||||
|
||||
/*
|
||||
* the separate hansfree headset (HF) and Audio Gateway (AG) features
|
||||
*/
|
||||
enum hfp_hf_features {
|
||||
HFP_HF_EC_NR = 0,
|
||||
HFP_HF_CALL_WAITING = 1,
|
||||
HFP_HF_CLI = 2,
|
||||
HFP_HF_VR = 3,
|
||||
HFP_HF_RVOL = 4,
|
||||
HFP_HF_ESTATUS = 5,
|
||||
HFP_HF_ECALL = 6,
|
||||
HFP_HF_CODECS = 7,
|
||||
HFP_HF_INDICATORS = 8,
|
||||
};
|
||||
|
||||
enum hfp_ag_features {
|
||||
HFP_AG_THREE_WAY = 0,
|
||||
HFP_AG_EC_NR = 1,
|
||||
HFP_AG_VR = 2,
|
||||
HFP_AG_RING = 3,
|
||||
HFP_AG_NUM_TAG = 4,
|
||||
HFP_AG_REJECT = 5,
|
||||
HFP_AG_ESTATUS = 6,
|
||||
HFP_AG_ECALL = 7,
|
||||
HFP_AG_EERR = 8,
|
||||
HFP_AG_CODECS = 9,
|
||||
HFP_AG_INDICATORS = 10,
|
||||
};
|
||||
=======
|
||||
|
||||
/*
|
||||
* the separate hansfree headset (HF) and Audio Gateway (AG) features
|
||||
|
|
@ -95,6 +148,21 @@ enum hfp_ag_features {
|
|||
HFP_AG_INDICATORS = 10,
|
||||
};
|
||||
|
||||
/*
|
||||
* Always keep this struct in sync with indicator discovery of AT+CIND=?
|
||||
* These indicators are used in bitflags and intentionally start at 1
|
||||
* since AT+CIND indicators start at index 1.
|
||||
*/
|
||||
typedef enum pa_bluetooth_ag_to_hf_indicators {
|
||||
CIND_CALL_INDICATOR = 1,
|
||||
CIND_CALL_SETUP_INDICATOR = 2,
|
||||
CIND_CALL_HELD_INDICATOR = 3,
|
||||
CIND_SERVICE_INDICATOR = 4,
|
||||
CIND_BATT_CHG_INDICATOR = 5,
|
||||
CIND_INDICATOR_MAX = 6
|
||||
} pa_bluetooth_ag_to_hf_indicators_t;
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
/* gateway features we support, which is as little as we can get away with */
|
||||
static uint32_t hfp_features =
|
||||
/* HFP 1.6 requires this */
|
||||
|
|
@ -108,6 +176,9 @@ static uint32_t hfp_features =
|
|||
* The choice seems to be a bit arbitrary -- it looks like at least channels 2, 4 and 5 also work*/
|
||||
#define HSP_HS_DEFAULT_CHANNEL 3
|
||||
|
||||
/* Total number of trying to reconnect */
|
||||
#define SCO_RECONNECTION_COUNT 3
|
||||
|
||||
#define PROFILE_INTROSPECT_XML \
|
||||
DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \
|
||||
"<node>" \
|
||||
|
|
@ -320,17 +391,43 @@ fail:
|
|||
static int sco_acquire_cb(pa_bluetooth_transport *t, bool optional, size_t *imtu, size_t *omtu) {
|
||||
int sock;
|
||||
socklen_t len;
|
||||
int i;
|
||||
|
||||
if (optional)
|
||||
sock = sco_do_accept(t);
|
||||
else
|
||||
sock = sco_do_connect(t);
|
||||
else {
|
||||
for (i = 0; i < SCO_RECONNECTION_COUNT; i++) {
|
||||
sock = sco_do_connect(t);
|
||||
|
||||
if (sock < 0) {
|
||||
pa_log_debug("err is %s and reconnection count is %d", pa_cstrerror(errno), i);
|
||||
pa_msleep(300);
|
||||
continue;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (sock < 0)
|
||||
goto fail;
|
||||
|
||||
<<<<<<< HEAD
|
||||
if (imtu) *imtu = 60;
|
||||
if (omtu) *omtu = 60;
|
||||
=======
|
||||
/* The correct block size should take into account the SCO MTU from
|
||||
* the Bluetooth adapter and (for adapters in the USB bus) the MxPS
|
||||
* value from the Isoc USB endpoint in use by btusb and should be
|
||||
* made available to userspace by the Bluetooth kernel subsystem.
|
||||
*
|
||||
* Set initial MTU to max known payload length of HCI packet
|
||||
* in USB Alternate Setting 5 (144 bytes)
|
||||
* See also pa_bluetooth_transport::last_read_size handling
|
||||
* and comment about MTU size in bt_prepare_encoder_buffer()
|
||||
*/
|
||||
if (imtu) *imtu = 144;
|
||||
if (omtu) *omtu = 144;
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
if (t->device->autodetect_mtu) {
|
||||
struct sco_options sco_opt;
|
||||
|
|
@ -568,11 +665,21 @@ static pa_volume_t set_source_volume(pa_bluetooth_transport *t, pa_volume_t volu
|
|||
static bool hfp_rfcomm_handle(int fd, pa_bluetooth_transport *t, const char *buf)
|
||||
{
|
||||
struct hfp_config *c = t->config;
|
||||
<<<<<<< HEAD
|
||||
int indicator, val;
|
||||
char str[5];
|
||||
const char *r;
|
||||
size_t len;
|
||||
const char *state;
|
||||
=======
|
||||
struct transport_data *trd = t->userdata;
|
||||
pa_bluetooth_backend *b = trd->backend;
|
||||
int indicator, mode, val;
|
||||
char *str;
|
||||
const char *r;
|
||||
size_t len;
|
||||
const char *state = NULL;
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
/* first-time initialize selected codec to CVSD */
|
||||
if (c->selected_codec == 0)
|
||||
|
|
@ -587,6 +694,7 @@ static bool hfp_rfcomm_handle(int fd, pa_bluetooth_transport *t, const char *buf
|
|||
c->state = 1;
|
||||
|
||||
return true;
|
||||
<<<<<<< HEAD
|
||||
} else if (sscanf(buf, "AT+BAC=%3s", str) == 1) {
|
||||
c->support_msbc = false;
|
||||
|
||||
|
|
@ -594,11 +702,52 @@ static bool hfp_rfcomm_handle(int fd, pa_bluetooth_transport *t, const char *buf
|
|||
|
||||
/* check if codec id 2 (mSBC) is in the list of supported codecs */
|
||||
while ((r = pa_split_in_place(str, ",", &len, &state))) {
|
||||
=======
|
||||
} else if (pa_startswith(buf, "AT+BIA=")) {
|
||||
/* Indicators start with index 1 and follow the order of the AT+CIND=? response */
|
||||
|
||||
str = pa_xstrdup(buf + 7);
|
||||
for (indicator = 1; (r = pa_split_in_place(str, ",\r\n", &len, &state)); indicator++) {
|
||||
/* Ignore updates to mandatory indicators which are always ON */
|
||||
if (indicator == CIND_CALL_INDICATOR
|
||||
|| indicator == CIND_CALL_SETUP_INDICATOR
|
||||
|| indicator == CIND_CALL_HELD_INDICATOR)
|
||||
continue;
|
||||
|
||||
/* Indicators may have no value and should be skipped */
|
||||
if (len == 0)
|
||||
continue;
|
||||
|
||||
if (len == 1 && r[0] == '1')
|
||||
b->cind_enabled_indicators |= (1 << indicator);
|
||||
else if (len == 1 && r[0] == '0')
|
||||
b->cind_enabled_indicators &= ~(1 << indicator);
|
||||
else {
|
||||
pa_log_error("Unable to parse indicator of AT+BIA command: %s", buf);
|
||||
rfcomm_write_response(fd, "ERROR");
|
||||
pa_xfree(str);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
pa_xfree(str);
|
||||
|
||||
return true;
|
||||
} else if (pa_startswith(buf, "AT+BAC=")) {
|
||||
c->support_msbc = false;
|
||||
|
||||
/* check if codec id 2 (mSBC) is in the list of supported codecs */
|
||||
str = pa_xstrdup(buf + 7);
|
||||
while ((r = pa_split_in_place(str, ",\r\n", &len, &state))) {
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
if (len == 1 && r[0] == '2') {
|
||||
c->support_msbc = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
pa_xfree(str);
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
c->support_codec_negotiation = true;
|
||||
|
||||
|
|
@ -612,6 +761,7 @@ static bool hfp_rfcomm_handle(int fd, pa_bluetooth_transport *t, const char *buf
|
|||
|
||||
return true;
|
||||
} else if (c->state == 1 && pa_startswith(buf, "AT+CIND=?")) {
|
||||
<<<<<<< HEAD
|
||||
/* we declare minimal no indicators */
|
||||
rfcomm_write_response(fd, "+CIND: "
|
||||
/* many indicators can be supported, only call and
|
||||
|
|
@ -620,16 +770,58 @@ static bool hfp_rfcomm_handle(int fd, pa_bluetooth_transport *t, const char *buf
|
|||
"(\"call\",(0-1)),"
|
||||
"(\"callsetup\",(0-3)),"
|
||||
"(\"callheld\",(0-2))");
|
||||
=======
|
||||
/* UPower backend available, declare support for more indicators */
|
||||
if (b->upower) {
|
||||
rfcomm_write_response(fd, "+CIND: "
|
||||
MANDATORY_CALL_INDICATORS ","
|
||||
"(\"service\",(0-1)),"
|
||||
"(\"battchg\",(0-5))");
|
||||
|
||||
/* Minimal indicators supported without any additional backend */
|
||||
} else {
|
||||
rfcomm_write_response(fd, "+CIND: "
|
||||
MANDATORY_CALL_INDICATORS ","
|
||||
"(\"service\",(0-1))");
|
||||
}
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
c->state = 2;
|
||||
|
||||
return true;
|
||||
} else if (c->state == 2 && pa_startswith(buf, "AT+CIND?")) {
|
||||
<<<<<<< HEAD
|
||||
rfcomm_write_response(fd, "+CIND: 0,0,0,0");
|
||||
=======
|
||||
if (b->upower)
|
||||
rfcomm_write_response(fd, "+CIND: 0,0,0,0,%u", pa_upower_get_battery_level(b->upower));
|
||||
else
|
||||
rfcomm_write_response(fd, "+CIND: 0,0,0,0");
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
c->state = 3;
|
||||
|
||||
return true;
|
||||
} else if ((c->state == 2 || c->state == 3) && pa_startswith(buf, "AT+CMER=")) {
|
||||
<<<<<<< HEAD
|
||||
rfcomm_write_response(fd, "OK");
|
||||
=======
|
||||
if (sscanf(buf, "AT+CMER=%d,%*d,%*d,%d", &mode, &val) == 2) {
|
||||
/* Bluetooth HFP spec only defines mode == 3 */
|
||||
if (mode != 3)
|
||||
pa_log_warn("Unexpected mode for AT+CMER: %d", mode);
|
||||
|
||||
/* Configure CMER event reporting */
|
||||
b->cmer_indicator_reporting_enabled = !!val;
|
||||
|
||||
pa_log_debug("Event indications enabled? %s", pa_yes_no(val));
|
||||
|
||||
rfcomm_write_response(fd, "OK");
|
||||
}
|
||||
else {
|
||||
pa_log_error("Unable to parse AT+CMER command: %s", buf);
|
||||
rfcomm_write_response(fd, "ERROR");
|
||||
return false;
|
||||
}
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
if (c->support_codec_negotiation) {
|
||||
if (c->support_msbc && pa_bluetooth_discovery_get_enable_msbc(t->device->discovery)) {
|
||||
|
|
@ -715,10 +907,67 @@ static bool hfp_rfcomm_handle(int fd, pa_bluetooth_transport *t, const char *buf
|
|||
* update, but we process only the ones we care about
|
||||
*/
|
||||
return true;
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
}
|
||||
|
||||
static int get_rfcomm_fd(pa_bluetooth_discovery *discovery) {
|
||||
struct pa_bluetooth_transport *t;
|
||||
struct transport_data *trd = NULL;
|
||||
void *state = NULL;
|
||||
|
||||
/* Find RFCOMM transport by checking if a HSP or HFP profile transport is available */
|
||||
while ((t = pa_hashmap_iterate(pa_bluetooth_discovery_get_transports(discovery), &state, NULL))) {
|
||||
/* Skip non-connected transports */
|
||||
if (!t || t->state == PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Break when an RFCOMM capable transport profile is available */
|
||||
if (t->profile == PA_BLUETOOTH_PROFILE_HFP_HF) {
|
||||
trd = t->userdata;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Skip if RFCOMM channel is not available yet */
|
||||
if (!trd) {
|
||||
pa_log_info("RFCOMM not available yet, skipping notification");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return trd->rfcomm_fd;
|
||||
}
|
||||
|
||||
static pa_hook_result_t host_battery_level_changed_cb(pa_bluetooth_discovery *y, const pa_upower_backend *u, pa_bluetooth_backend *b) {
|
||||
int rfcomm_fd;
|
||||
|
||||
pa_assert(y);
|
||||
pa_assert(u);
|
||||
pa_assert(b);
|
||||
|
||||
/* Get RFCOMM channel if available */
|
||||
rfcomm_fd = get_rfcomm_fd(y);
|
||||
if (rfcomm_fd < 0)
|
||||
return PA_HOOK_OK;
|
||||
|
||||
/* Notify HF about AG battery level change over RFCOMM */
|
||||
if (b->cmer_indicator_reporting_enabled && (b->cind_enabled_indicators & (1 << CIND_BATT_CHG_INDICATOR))) {
|
||||
rfcomm_write_response(rfcomm_fd, "+CIEV: %d,%d", CIND_BATT_CHG_INDICATOR, u->battery_level);
|
||||
pa_log_debug("HG notified of AG's battery level change");
|
||||
/* Skip notification if indicator is disabled or event reporting is completely disabled */
|
||||
} else
|
||||
pa_log_debug("Battery level change indicator disabled, skipping notification");
|
||||
|
||||
return PA_HOOK_OK;
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
}
|
||||
|
||||
static void rfcomm_io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void *userdata) {
|
||||
pa_bluetooth_transport *t = userdata;
|
||||
struct transport_data *trd = t->userdata;
|
||||
pa_bluetooth_backend *b = trd->backend;
|
||||
int i;
|
||||
|
||||
pa_assert(io);
|
||||
pa_assert(t);
|
||||
|
|
@ -734,18 +983,23 @@ static void rfcomm_io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_i
|
|||
}
|
||||
|
||||
if (events & PA_IO_EVENT_INPUT) {
|
||||
char buf[512];
|
||||
char rbuf[512];
|
||||
ssize_t len;
|
||||
int gain, dummy;
|
||||
bool do_reply = false;
|
||||
int vendor, product, version, features;
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
char *buf = rbuf;
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
int num;
|
||||
|
||||
len = pa_read(fd, buf, 511, NULL);
|
||||
len = pa_read(fd, rbuf, 511, NULL);
|
||||
if (len < 0) {
|
||||
pa_log_error("RFCOMM read error: %s", pa_cstrerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
<<<<<<< HEAD
|
||||
buf[len] = 0;
|
||||
pa_log_debug("RFCOMM << %s", buf);
|
||||
|
||||
|
|
@ -834,11 +1088,119 @@ static void rfcomm_io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_i
|
|||
|
||||
if (do_reply)
|
||||
rfcomm_write_response(fd, "OK");
|
||||
=======
|
||||
rbuf[len] = 0;
|
||||
pa_log_debug("RFCOMM << %s", rbuf);
|
||||
|
||||
while (buf[0]) {
|
||||
/* There are only four HSP AT commands:
|
||||
* AT+VGS=value: value between 0 and 15, sent by the HS to AG to set the speaker gain.
|
||||
* +VGS=value is sent by AG to HS as a response to an AT+VGS command or when the gain
|
||||
* is changed on the AG side.
|
||||
* AT+VGM=value: value between 0 and 15, sent by the HS to AG to set the microphone gain.
|
||||
* +VGM=value is sent by AG to HS as a response to an AT+VGM command or when the gain
|
||||
* is changed on the AG side.
|
||||
* AT+CKPD=200: Sent by HS when headset button is pressed.
|
||||
* RING: Sent by AG to HS to notify of an incoming call. It can safely be ignored because
|
||||
* it does not expect a reply. */
|
||||
if (sscanf(buf, "AT+VGS=%d", &gain) == 1 || sscanf(buf, "\r\n+VGM%*[=:]%d\r\n", &gain) == 1) {
|
||||
if (!t->set_sink_volume) {
|
||||
pa_log_debug("HS/HF peer supports speaker gain control");
|
||||
t->set_sink_volume = set_sink_volume;
|
||||
}
|
||||
|
||||
t->sink_volume = hsp_gain_to_volume(gain);
|
||||
pa_hook_fire(pa_bluetooth_discovery_hook(t->device->discovery, PA_BLUETOOTH_HOOK_TRANSPORT_SINK_VOLUME_CHANGED), t);
|
||||
do_reply = true;
|
||||
|
||||
} else if (sscanf(buf, "AT+VGM=%d", &gain) == 1 || sscanf(buf, "\r\n+VGS%*[=:]%d\r\n", &gain) == 1) {
|
||||
if (!t->set_source_volume) {
|
||||
pa_log_debug("HS/HF peer supports microphone gain control");
|
||||
t->set_source_volume = set_source_volume;
|
||||
}
|
||||
|
||||
t->source_volume = hsp_gain_to_volume(gain);
|
||||
pa_hook_fire(pa_bluetooth_discovery_hook(t->device->discovery, PA_BLUETOOTH_HOOK_TRANSPORT_SOURCE_VOLUME_CHANGED), t);
|
||||
do_reply = true;
|
||||
} else if (sscanf(buf, "AT+CKPD=%d", &dummy) == 1) {
|
||||
do_reply = true;
|
||||
} else if (sscanf(buf, "AT+XAPL=%04x-%04x-%04x,%d", &vendor, &product, &version, &features) == 4) {
|
||||
if (features & 0x2)
|
||||
/* claim, that we support battery status reports */
|
||||
rfcomm_write_response(fd, "+XAPL=iPhone,6");
|
||||
do_reply = true;
|
||||
} else if (sscanf(buf, "AT+IPHONEACCEV=%d", &num) == 1) {
|
||||
char *substr = buf, *keystr;
|
||||
int key, val, i;
|
||||
|
||||
do_reply = true;
|
||||
|
||||
for (i = 0; i < num; ++i) {
|
||||
keystr = strchr(substr, ',');
|
||||
if (!keystr) {
|
||||
pa_log_warn("%s misses key for argument #%d", buf, i);
|
||||
do_reply = false;
|
||||
break;
|
||||
}
|
||||
keystr++;
|
||||
substr = strchr(keystr, ',');
|
||||
if (!substr) {
|
||||
pa_log_warn("%s misses value for argument #%d", buf, i);
|
||||
do_reply = false;
|
||||
break;
|
||||
}
|
||||
substr++;
|
||||
|
||||
key = atoi(keystr);
|
||||
val = atoi(substr);
|
||||
|
||||
switch (key) {
|
||||
case 1:
|
||||
pa_log_debug("Battery Level: %d0%%", val + 1);
|
||||
pa_bluetooth_device_report_battery_level(t->device, (val + 1) * 10, "Apple accessory indication");
|
||||
break;
|
||||
case 2:
|
||||
pa_log_debug("Dock Status: %s", val ? "docked" : "undocked");
|
||||
break;
|
||||
default:
|
||||
pa_log_debug("Unexpected IPHONEACCEV key %#x", key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!do_reply)
|
||||
rfcomm_write_response(fd, "ERROR");
|
||||
} else if (t->config) { /* t->config is only non-null for hfp profile */
|
||||
do_reply = hfp_rfcomm_handle(fd, t, buf);
|
||||
} else {
|
||||
rfcomm_write_response(fd, "ERROR");
|
||||
do_reply = false;
|
||||
}
|
||||
|
||||
if (do_reply)
|
||||
rfcomm_write_response(fd, "OK");
|
||||
|
||||
if (buf[0] == '\r') /* in case it is the command with format \r\nCOMMAND\r\n, skip the starting \r */
|
||||
buf = buf + 1;
|
||||
|
||||
buf = strstr(buf, "\r"); /* try to find the next AT command in the buf */
|
||||
if (!buf)
|
||||
break;
|
||||
else if (buf[1] == '\n')
|
||||
buf = buf + 2; /* skip \r\n */
|
||||
else
|
||||
buf = buf + 1; /* skip \r */
|
||||
}
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
fail:
|
||||
/* Service Connection lost, reset indicators and event reporting to default values */
|
||||
b->cmer_indicator_reporting_enabled = false;
|
||||
for (i = 1; i < CIND_INDICATOR_MAX; i++)
|
||||
b->cind_enabled_indicators |= (1 << i);
|
||||
|
||||
pa_bluetooth_transport_unlink(t);
|
||||
pa_bluetooth_transport_free(t);
|
||||
}
|
||||
|
|
@ -862,6 +1224,7 @@ static void transport_destroy(pa_bluetooth_transport *t) {
|
|||
static pa_volume_t set_sink_volume(pa_bluetooth_transport *t, pa_volume_t volume) {
|
||||
struct transport_data *trd = t->userdata;
|
||||
uint16_t gain = volume_to_hsp_gain(volume);
|
||||
<<<<<<< HEAD
|
||||
|
||||
/* Propagate rounding and bound checks */
|
||||
volume = hsp_gain_to_volume(gain);
|
||||
|
|
@ -871,6 +1234,17 @@ static pa_volume_t set_sink_volume(pa_bluetooth_transport *t, pa_volume_t volume
|
|||
|
||||
t->sink_volume = volume;
|
||||
|
||||
=======
|
||||
|
||||
/* Propagate rounding and bound checks */
|
||||
volume = hsp_gain_to_volume(gain);
|
||||
|
||||
if (t->sink_volume == volume)
|
||||
return volume;
|
||||
|
||||
t->sink_volume = volume;
|
||||
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
/* If we are in the AG role, we send an unsolicited result-code to the headset
|
||||
* to change the speaker gain. In the HS role, source and sink are swapped,
|
||||
* so in this case we notify the AG that the microphone gain has changed
|
||||
|
|
@ -887,6 +1261,7 @@ static pa_volume_t set_sink_volume(pa_bluetooth_transport *t, pa_volume_t volume
|
|||
static pa_volume_t set_source_volume(pa_bluetooth_transport *t, pa_volume_t volume) {
|
||||
struct transport_data *trd = t->userdata;
|
||||
uint16_t gain = volume_to_hsp_gain(volume);
|
||||
<<<<<<< HEAD
|
||||
|
||||
/* Propagate rounding and bound checks */
|
||||
volume = hsp_gain_to_volume(gain);
|
||||
|
|
@ -896,6 +1271,17 @@ static pa_volume_t set_source_volume(pa_bluetooth_transport *t, pa_volume_t volu
|
|||
|
||||
t->source_volume = volume;
|
||||
|
||||
=======
|
||||
|
||||
/* Propagate rounding and bound checks */
|
||||
volume = hsp_gain_to_volume(gain);
|
||||
|
||||
if (t->source_volume == volume)
|
||||
return volume;
|
||||
|
||||
t->source_volume = volume;
|
||||
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
/* If we are in the AG role, we send an unsolicited result-code to the headset
|
||||
* to change the microphone gain. In the HS role, source and sink are swapped,
|
||||
* so in this case we notify the AG that the speaker gain has changed
|
||||
|
|
@ -1001,6 +1387,7 @@ static DBusMessage *profile_new_connection(DBusConnection *conn, DBusMessage *m,
|
|||
trd = pa_xnew0(struct transport_data, 1);
|
||||
trd->rfcomm_fd = fd;
|
||||
trd->mainloop = b->core->mainloop;
|
||||
trd->backend = b;
|
||||
trd->rfcomm_io = trd->mainloop->io_new(b->core->mainloop, fd, PA_IO_EVENT_INPUT,
|
||||
rfcomm_io_callback, t);
|
||||
t->userdata = trd;
|
||||
|
|
@ -1153,9 +1540,15 @@ static void native_backend_apply_profile_registration_change(pa_bluetooth_backen
|
|||
profile_done(native_backend, PA_BLUETOOTH_PROFILE_HFP_HF);
|
||||
}
|
||||
}
|
||||
<<<<<<< HEAD
|
||||
|
||||
void pa_bluetooth_native_backend_enable_shared_profiles(pa_bluetooth_backend *native_backend, bool enable) {
|
||||
|
||||
=======
|
||||
|
||||
void pa_bluetooth_native_backend_enable_shared_profiles(pa_bluetooth_backend *native_backend, bool enable) {
|
||||
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
if (enable == native_backend->enable_shared_profiles)
|
||||
return;
|
||||
|
||||
|
|
@ -1167,6 +1560,7 @@ void pa_bluetooth_native_backend_enable_shared_profiles(pa_bluetooth_backend *na
|
|||
pa_bluetooth_backend *pa_bluetooth_native_backend_new(pa_core *c, pa_bluetooth_discovery *y, bool enable_shared_profiles) {
|
||||
pa_bluetooth_backend *backend;
|
||||
DBusError err;
|
||||
int i;
|
||||
|
||||
pa_log_debug("Bluetooth Headset Backend API support using the native backend");
|
||||
|
||||
|
|
@ -1189,6 +1583,7 @@ pa_bluetooth_backend *pa_bluetooth_native_backend_new(pa_core *c, pa_bluetooth_d
|
|||
backend->adapter_uuids_changed_slot =
|
||||
pa_hook_connect(pa_bluetooth_discovery_hook(y, PA_BLUETOOTH_HOOK_ADAPTER_UUIDS_CHANGED), PA_HOOK_NORMAL,
|
||||
(pa_hook_cb_t) adapter_uuids_changed_cb, backend);
|
||||
<<<<<<< HEAD
|
||||
|
||||
if (!backend->enable_hsp_hs && !backend->enable_hfp_hf)
|
||||
pa_log_warn("Both HSP HS and HFP HF bluetooth profiles disabled in native backend. Native backend will not register for headset connections.");
|
||||
|
|
@ -1198,6 +1593,31 @@ pa_bluetooth_backend *pa_bluetooth_native_backend_new(pa_core *c, pa_bluetooth_d
|
|||
|
||||
if (backend->enable_shared_profiles)
|
||||
native_backend_apply_profile_registration_change(backend, true);
|
||||
=======
|
||||
|
||||
backend->host_battery_level_changed_slot =
|
||||
pa_hook_connect(pa_bluetooth_discovery_hook(y, PA_BLUETOOTH_HOOK_HOST_BATTERY_LEVEL_CHANGED), PA_HOOK_NORMAL,
|
||||
(pa_hook_cb_t) host_battery_level_changed_cb, backend);
|
||||
|
||||
if (!backend->enable_hsp_hs && !backend->enable_hfp_hf)
|
||||
pa_log_warn("Both HSP HS and HFP HF bluetooth profiles disabled in native backend. Native backend will not register for headset connections.");
|
||||
|
||||
if (backend->enable_hsp_hs)
|
||||
profile_init(backend, PA_BLUETOOTH_PROFILE_HSP_HS);
|
||||
|
||||
if (backend->enable_shared_profiles)
|
||||
native_backend_apply_profile_registration_change(backend, true);
|
||||
|
||||
backend->upower = pa_upower_backend_new(c, y);
|
||||
|
||||
/* All CIND indicators are enabled by default until overriden by AT+BIA */
|
||||
for (i = 1; i < CIND_INDICATOR_MAX; i++)
|
||||
backend->cind_enabled_indicators |= (1 << i);
|
||||
|
||||
/* While all CIND indicators are enabled, event reporting is not enabled by default */
|
||||
backend->cmer_indicator_reporting_enabled = false;
|
||||
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
return backend;
|
||||
}
|
||||
|
|
@ -1210,11 +1630,23 @@ void pa_bluetooth_native_backend_free(pa_bluetooth_backend *backend) {
|
|||
if (backend->adapter_uuids_changed_slot)
|
||||
pa_hook_slot_free(backend->adapter_uuids_changed_slot);
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
if (backend->host_battery_level_changed_slot)
|
||||
pa_hook_slot_free(backend->host_battery_level_changed_slot);
|
||||
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
if (backend->enable_shared_profiles)
|
||||
native_backend_apply_profile_registration_change(backend, false);
|
||||
|
||||
if (backend->enable_hsp_hs)
|
||||
profile_done(backend, PA_BLUETOOTH_PROFILE_HSP_HS);
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
|
||||
if (backend->upower)
|
||||
pa_upower_backend_free(backend->upower);
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
pa_dbus_connection_unref(backend->connection);
|
||||
|
||||
|
|
|
|||
|
|
@ -250,6 +250,9 @@ static pa_hook_result_t device_unlink_cb(pa_bluetooth_discovery *y, const pa_blu
|
|||
pa_assert(d);
|
||||
pa_assert(card);
|
||||
|
||||
if (d != card->transport->device)
|
||||
return PA_HOOK_OK;
|
||||
|
||||
hf_audio_agent_card_removed(card->backend, card->path);
|
||||
|
||||
return PA_HOOK_OK;
|
||||
|
|
@ -330,6 +333,7 @@ static int hf_audio_agent_transport_acquire(pa_bluetooth_transport *t, bool opti
|
|||
* value from the Isoc USB endpoint in use by btusb and should be
|
||||
* made available to userspace by the Bluetooth kernel subsystem.
|
||||
*
|
||||
<<<<<<< HEAD
|
||||
* Set initial MTU to max size which is reported to be working (60 bytes)
|
||||
* See also pa_bluetooth_transport::last_read_size handling.
|
||||
*/
|
||||
|
|
@ -337,6 +341,17 @@ static int hf_audio_agent_transport_acquire(pa_bluetooth_transport *t, bool opti
|
|||
*imtu = 60;
|
||||
if (omtu)
|
||||
*omtu = 60;
|
||||
=======
|
||||
* Set initial MTU to max known payload length of HCI packet
|
||||
* in USB Alternate Setting 5 (144 bytes)
|
||||
* See also pa_bluetooth_transport::last_read_size handling
|
||||
* and comment about MTU size in bt_prepare_encoder_buffer()
|
||||
*/
|
||||
if (imtu)
|
||||
*imtu = 144;
|
||||
if (omtu)
|
||||
*omtu = 144;
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
err = socket_accept(card->fd);
|
||||
if (err < 0) {
|
||||
|
|
|
|||
|
|
@ -254,8 +254,24 @@ static const char *transport_state_to_string(pa_bluetooth_transport_state_t stat
|
|||
return "invalid";
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
static bool device_supports_profile(pa_bluetooth_device *device, pa_bluetooth_profile_t profile) {
|
||||
bool show_hfp, show_hsp;
|
||||
=======
|
||||
bool pa_bluetooth_device_supports_profile(const pa_bluetooth_device *device, pa_bluetooth_profile_t profile) {
|
||||
bool show_hfp, show_hsp, r;
|
||||
|
||||
pa_assert(device);
|
||||
|
||||
/* While discovery is being released adapters will be removed from devices,
|
||||
* and there are no profiles to support without adapter.
|
||||
*/
|
||||
if (!device->adapter) {
|
||||
pa_log_debug("Device %s (%s) has no adapter to support profile %s",
|
||||
device->alias, device->address, pa_bluetooth_profile_to_string(profile));
|
||||
return false;
|
||||
}
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
if (device->enable_hfp_hf) {
|
||||
show_hfp = pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_HF);
|
||||
|
|
@ -267,8 +283,11 @@ static bool device_supports_profile(pa_bluetooth_device *device, pa_bluetooth_pr
|
|||
|
||||
switch (profile) {
|
||||
case PA_BLUETOOTH_PROFILE_A2DP_SINK:
|
||||
return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_A2DP_SINK);
|
||||
r = !!(pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_A2DP_SINK) &&
|
||||
pa_hashmap_get(device->adapter->uuids, PA_BLUETOOTH_UUID_A2DP_SOURCE));
|
||||
break;
|
||||
case PA_BLUETOOTH_PROFILE_A2DP_SOURCE:
|
||||
<<<<<<< HEAD
|
||||
return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_A2DP_SOURCE);
|
||||
case PA_BLUETOOTH_PROFILE_HSP_HS:
|
||||
return show_hsp
|
||||
|
|
@ -280,11 +299,43 @@ static bool device_supports_profile(pa_bluetooth_device *device, pa_bluetooth_pr
|
|||
return show_hfp && !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_HF);
|
||||
case PA_BLUETOOTH_PROFILE_HFP_AG:
|
||||
return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_AG);
|
||||
=======
|
||||
r = !!(pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_A2DP_SOURCE) &&
|
||||
pa_hashmap_get(device->adapter->uuids, PA_BLUETOOTH_UUID_A2DP_SINK));
|
||||
break;
|
||||
case PA_BLUETOOTH_PROFILE_HSP_HS:
|
||||
r = show_hsp
|
||||
&& ( !!(pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_HS) &&
|
||||
pa_hashmap_get(device->adapter->uuids, PA_BLUETOOTH_UUID_HSP_AG)) ||
|
||||
!!(pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_HS_ALT) &&
|
||||
pa_hashmap_get(device->adapter->uuids, PA_BLUETOOTH_UUID_HSP_AG)) );
|
||||
break;
|
||||
case PA_BLUETOOTH_PROFILE_HSP_AG:
|
||||
r = !!(pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_AG) &&
|
||||
pa_hashmap_get(device->adapter->uuids, PA_BLUETOOTH_UUID_HSP_HS)) ||
|
||||
!!(pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_AG) &&
|
||||
pa_hashmap_get(device->adapter->uuids, PA_BLUETOOTH_UUID_HSP_HS_ALT));
|
||||
break;
|
||||
case PA_BLUETOOTH_PROFILE_HFP_HF:
|
||||
r = show_hfp
|
||||
&& !!(pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_HF) &&
|
||||
pa_hashmap_get(device->adapter->uuids, PA_BLUETOOTH_UUID_HFP_AG));
|
||||
break;
|
||||
case PA_BLUETOOTH_PROFILE_HFP_AG:
|
||||
r = !!(pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_AG) &&
|
||||
pa_hashmap_get(device->adapter->uuids, PA_BLUETOOTH_UUID_HFP_HF));
|
||||
break;
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
case PA_BLUETOOTH_PROFILE_OFF:
|
||||
default:
|
||||
pa_assert_not_reached();
|
||||
break;
|
||||
}
|
||||
|
||||
pa_assert_not_reached();
|
||||
pa_log_debug("Checking if device %s (%s) supports profile %s: %s",
|
||||
device->alias, device->address, pa_bluetooth_profile_to_string(profile), r ? "true" : "false");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static bool device_is_profile_connected(pa_bluetooth_device *device, pa_bluetooth_profile_t profile) {
|
||||
|
|
@ -299,7 +350,7 @@ static unsigned device_count_disconnected_profiles(pa_bluetooth_device *device)
|
|||
unsigned count = 0;
|
||||
|
||||
for (profile = 0; profile < PA_BLUETOOTH_PROFILE_COUNT; profile++) {
|
||||
if (!device_supports_profile(device, profile))
|
||||
if (!pa_bluetooth_device_supports_profile(device, profile))
|
||||
continue;
|
||||
|
||||
if (!device_is_profile_connected(device, profile))
|
||||
|
|
@ -332,7 +383,7 @@ static void wait_for_profiles_cb(pa_mainloop_api *api, pa_time_event* event, con
|
|||
if (device_is_profile_connected(device, profile))
|
||||
continue;
|
||||
|
||||
if (!device_supports_profile(device, profile))
|
||||
if (!pa_bluetooth_device_supports_profile(device, profile))
|
||||
continue;
|
||||
|
||||
if (first)
|
||||
|
|
@ -756,6 +807,10 @@ static void get_volume_reply(DBusPendingCall *pending, void *userdata) {
|
|||
pa_bluetooth_transport *t;
|
||||
uint16_t gain;
|
||||
pa_volume_t volume;
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
const char *error_name, *error_message;
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
|
||||
pa_assert(pending);
|
||||
pa_assert_se(p = userdata);
|
||||
|
|
@ -764,10 +819,25 @@ static void get_volume_reply(DBusPendingCall *pending, void *userdata) {
|
|||
pa_assert_se(r = dbus_pending_call_steal_reply(pending));
|
||||
|
||||
if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
|
||||
<<<<<<< HEAD
|
||||
pa_log_error(DBUS_INTERFACE_PROPERTIES ".Get %s Volume failed: %s: %s",
|
||||
dbus_message_get_path(p->message),
|
||||
dbus_message_get_error_name(r),
|
||||
pa_dbus_get_error_message(r));
|
||||
=======
|
||||
error_name = dbus_message_get_error_name(r);
|
||||
error_message = pa_dbus_get_error_message(r);
|
||||
|
||||
if (pa_streq(error_name, DBUS_ERROR_INVALID_ARGS) && pa_streq(error_message, "No such property 'Volume'")) {
|
||||
pa_log_warn(DBUS_INTERFACE_PROPERTIES ".Get %s Volume property not (yet) available",
|
||||
dbus_message_get_path(p->message));
|
||||
} else {
|
||||
pa_log_error(DBUS_INTERFACE_PROPERTIES ".Get %s Volume failed: %s: %s",
|
||||
dbus_message_get_path(p->message),
|
||||
error_name,
|
||||
error_message);
|
||||
}
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
goto finish;
|
||||
}
|
||||
dbus_message_iter_init(r, &iter);
|
||||
|
|
@ -1161,6 +1231,16 @@ bool pa_bluetooth_discovery_get_enable_msbc(pa_bluetooth_discovery *y)
|
|||
return y->enable_msbc;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
pa_hashmap* pa_bluetooth_discovery_get_transports(pa_bluetooth_discovery *y) {
|
||||
pa_assert(y);
|
||||
pa_assert(PA_REFCNT_VALUE(y) > 0);
|
||||
|
||||
return y->transports;
|
||||
}
|
||||
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
pa_bluetooth_device* pa_bluetooth_discovery_get_device_by_address(pa_bluetooth_discovery *y, const char *remote, const char *local) {
|
||||
pa_bluetooth_device *d;
|
||||
void *state = NULL;
|
||||
|
|
@ -1470,6 +1550,7 @@ static void adapter_free(pa_bluetooth_adapter *a) {
|
|||
if (d->adapter == a)
|
||||
device_set_adapter(d, NULL);
|
||||
|
||||
pa_hashmap_free(a->uuids);
|
||||
pa_xfree(a->path);
|
||||
pa_xfree(a->address);
|
||||
pa_xfree(a);
|
||||
|
|
@ -2081,7 +2162,11 @@ void pa_bluetooth_discovery_set_ofono_running(pa_bluetooth_discovery *y, bool is
|
|||
pa_bluetooth_device *d;
|
||||
|
||||
PA_HASHMAP_FOREACH(d, y->devices, state) {
|
||||
<<<<<<< HEAD
|
||||
if (device_supports_profile(d, PA_BLUETOOTH_PROFILE_HFP_AG) || device_supports_profile(d, PA_BLUETOOTH_PROFILE_HFP_HF)) {
|
||||
=======
|
||||
if (pa_bluetooth_device_supports_profile(d, PA_BLUETOOTH_PROFILE_HFP_AG) || pa_bluetooth_device_supports_profile(d, PA_BLUETOOTH_PROFILE_HFP_HF)) {
|
||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
|
||||
DBusMessage *m;
|
||||
|
||||
pa_assert_se(m = dbus_message_new_method_call(BLUEZ_SERVICE, d->path, BLUEZ_DEVICE_INTERFACE, "Disconnect"));
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue