[-]
[+]
|
Deleted |
_service:tar_git:pulseaudio-modules-droid-jb2q.changes
|
@@ -1,628 +0,0 @@
-* Fri Mar 10 2023 Matti Lehtimäki <matti.lehtimaki@jolla.com> - 14.2.101
-- [common] Fix 24-bit audio format mapping. JB#60307
-
-* Tue Dec 20 2022 Juho Hämäläinen <juho.hamalainen@jolla.com> - 14.2.100
-- [common] Add quirk for swapping headphone and router device. JB#59576
-- [sink] Add quirk for remixing stereo to mono. JB#59079
-
-* Fri Oct 07 2022 Juho Hämäläinen <juho.hamalainen@jolla.com> - 14.2.99
-- [parser] Better support for includes in xml. Fixes JB#58934
-
-* Mon Sep 19 2022 Juho Hämäläinen <juho.hamalainen@jolla.com> - 14.2.98
-- [build] Add meson support. JB#58078
-
-* Wed Feb 23 2022 Juho Hämäläinen <juho.hamalainen@jolla.com> - 14.2.97
-- [packaging] Replace old modules. JB#55832
-
-* Wed Feb 23 2022 Juho Hämäläinen <juho.hamalainen@jolla.com> - 14.2.96
-- [module] Add jb2q branding. JB#55832
-- [packaging] Rename to pulseaudio-modules-droid-jb2q. JB#55832
-
-* Mon Feb 21 2022 Juho Hämäläinen <juho.hamalainen@jolla.com> - 14.2.95
-- [common] Handle profiles with no supported channels
-- [common] New API for calling HAL functions. JB#55832
-
-* Fri Oct 08 2021 Juho Hämäläinen <juho.hamalainen@jolla.com> - 14.2.94
-- [common] Use more generic stream property for audio source. JB#55711
-
-* Fri Oct 08 2021 Juho Hämäläinen <juho.hamalainen@jolla.com> - 14.2.93
-- [common] Add generic converter for fancy audio sources.
-- [common] Allow custom audio source based on property. JB#55711
-- [common] Fix segfault with adaptations which assume empty adress is not NULL. Fixes JB#55831
-- [source] Use source-output proplist when reconfiguring input stream. JB#55711
-
-* Thu May 06 2021 Juho Hämäläinen <juho.hamalainen@jolla.com> - 14.2.92
-- [common] Add quirk speaker_before_voice. JB#53992
-- [common] Add quirk standby_set_route. JB#53992
-
-* Thu Apr 22 2021 Juho Hämäläinen <juho.hamalainen@jolla.com> - 14.2.91
-- [common] Set BT_SCO parameter for Bluetooth routes. Fixes JB#53996
-
-* Thu Mar 25 2021 Juho Hämäläinen <juho.hamalainen@jolla.com> - 14.2.90
-- [sink] Avoid segfault when voice call starts with deferred volume. JB#53687
-
-* Tue Mar 23 2021 Juho Hämäläinen <juho.hamalainen@jolla.com> - 14.2.89
-- [card] Parse quirks while loading hw module. JB#52328
-- [common] Add quirk audio_cal_wait. JB#52328
-- [common] Refactor quirks parsing. JB#52328
-- [sink] Add option to prewrite silence always. JB#53590
-- [sink] Apply channel average volume to stream. JB#53590
-- [sink] Enable deferred volume for hw volume control. JB#53590
-- [sink] Get hw module with new function in stand alone mode.
-- [source] Get hw module with new function in stand alone mode.
-
-* Mon Mar 01 2021 Matti Lehtimäki <matti.lehtimaki@jolla.com> - 14.2.88
-- [modules] Add missing include. JB#47666
-
-* Fri Feb 26 2021 Matti Lehtimäki <matti.lehtimaki@jolla.com> - 12.2.87
-- [packaging] Support new droid-devel header location. JB#51449
-
-* Wed Oct 21 2020 Juho Hämäläinen <juho.hamalainen@jolla.com> - 12.2.86
-- [parser-xml] Support module includes in configuration files. Fixes JB#51666
-
-* Mon Jun 22 2020 Simonas Leleiva <simonas.leleiva@meramo.co.uk> - 12.2.85
-- [packaging] Fix for 64bit. JB#50285
-
-* Tue Dec 10 2019 Juho Hämäläinen <juho.hamalainen@jolla.com> - 12.2.84
-- [card] Park profiles correctly when switching between virtual profiles. JB#47194
-- [common] Always set earpiece routing after enabling voice call mode. Fixes JB#47194
-
-* Tue Nov 19 2019 Juho Hämäläinen <juho.hamalainen@jolla.com> - 12.2.83
-- [common] Add quirks for FAST and DEEP_BUFFER sinks. JB#48097
-- [common] Revert to default values if input stream reconfigure fails.
-- [parser-xml] Store profiles correctly for mix and device ports.
-- [source] Add a workaround for fm-radio loopback. JB#48080
-- [source] Reconfigure stream instead of freeing and re-creating.
-
-* Mon Nov 11 2019 Juho Hämäläinen <juho.hamalainen@jolla.com> - 12.2.82
-- [common] Add missing configuration file search locations. JB#48080
-
-* Wed Oct 09 2019 Juho Hämäläinen <juho.hamalainen@jolla.com> - 12.2.81
-- [keepalive] Module relocated to its own package. JB#47579
-- [license] Fix license in spec. JB#45486
-- [modules] Fix compatibility with PulseAudio 13.0. JB#47666
-
-* Tue Oct 08 2019 Juho Hämäläinen <juho.hamalainen@jolla.com> - 12.2.80
-- [common] Always use only one input. JB#45496
-- [modules-droid] Source is reconfigured dynamically based on input. Fixes JB#47579
-
-* Fri Aug 09 2019 Juho Hämäläinen <juho.hamalainen@jolla.com> - 12.2.79
-- [card] Add voicemmode 1 and 2 virtual profiles. JB#46805
-- [source] Use format specific silence byte when needed.
-- [xml-parser] Behave better with badly formatted input.
-
-* Thu Apr 04 2019 Juho Hämäläinen <juho.hamalainen@jolla.com> - 12.2.78
-- [modules-droid] Update sink/source state correctly with PulseAudio 11.1. JB#44329
-
-* Fri Mar 22 2019 Juho Hämäläinen <jusa@hilvi.org> - 12.2.77
-- [modules-droid] Update to support PulseAudio 12.2. JB#42201
-
-* Thu Nov 15 2018 Juho Hämäläinen <juho.hamalainen@jolla.com> - 11.1.76
-- [sbj] Add missing define to fix voicecall recording. Fixes JB#43836
-
-* Thu Nov 01 2018 Juho Hämäläinen <juho.hamalainen@jolla.com> - 11.1.75
-- [xml-parser] Be less strict in parsing module attributes. JB#42564
-
-* Fri Oct 05 2018 Juho Hämäläinen <jusa@hilvi.org> - 11.1.74
-- [card] Free config after use.
-- [card] Use common pattern of getting hw module.
-- [common] Add function to duplicate configuration.
-- [common] Add quirk unload_call_exit. JB#43235
-- [common] Be less verbose about missing config.
-- [common] Duplicate config for hw module.
-- [keepalive] Update state properly.
-- [README] Add description for unload_call_exit quirk.
-- [sink] Free config after use.
-- [source] Free config after use.
-
-* Tue Aug 28 2018 Juho Hämäläinen <juho.hamalainen@jolla.com> - 11.1.73
-- [common] Make sure QCOM_HARDWARE is defined when needed. JB#42564
-
-* Thu Aug 23 2018 Juho Hämäläinen <juho.hamalainen@jolla.com> - 11.1.72
-- [build] Install common headers and pc file properly.
-- [common] Check for primary flag instead of string. JB#42564
-- [common] Check for SPEAKER_DRC_ENABLED_TAG directly. JB#42564
-- [common] Combine output and input configurations.
-- [common] Move public headers to include/droid
-- [common] Remove sllist implementation to own header.
-- [common] Remove unused config functions.
-- [common] Use global include with public headers.
-- [config] Refactor hw module creation.
-- [config] Reorder configuration file search locations. JB#42564
-- [modules] Update includes.
-- [packaging] Remove obsolete header and pc file installs.
-- [README] Add note about xml parsing.
-- [xml-parser] More generic channel mask direction workaround. JB#42564
-
-* Wed Aug 15 2018 Juho Hämäläinen <juho.hamalainen@jolla.com> - 11.1.71
-- [common] Use uint32_t for input flags. JB#42564
-- [parser-xml] No need to idfef input flags.
-- [sbj] Add empty input flag struct.
-
-* Wed Aug 15 2018 Juho Hämäläinen <jusa@hilvi.org> - 11.1.70
-- [build] Add workaround for SBJ HAL headers. JB#42564
-- [conversion] Disable input flags for API 1 and 2. JB#42564
-- [sbj] Add missing include.
-- [sbj] Disable xml explicitly.
-
-* Wed Aug 15 2018 Juho Hämäläinen <juho.hamalainen@jolla.com> - 11.1.69
-- [build] Add test for expat. JB#42564
-- [build] Use expat.
-- [common] Split configuration parsing to multiple files.
-- [config] Allocate config in parsing functions.
-- [conversion] Add workarounds for format and device parsing. JB#42564
-- [legacy-parser] Allocate config in parser.
-- [module-droid-sink] Include conversion header.
-- [modules] Update contact information.
-- [packaging] Build requires expat. JB#42564
-- [sink] Include conversion header.
-- [source] Include conversion header.
-- [xml-parser] Add workaround for certain config error. JB#42564
-- [xml-parser] Drop include parsing for now.
-- [xml-parser] New parser for xml style configuration. Fixes JB#42564
-- [xml-parser] Placeholder for xml parser implementation.
-
-* Wed May 30 2018 Juho Hämäläinen <jusa@hilvi.org> - 11.1.68
-- [build] Use portable module lib path. JB#42043
-- [card] Apply specific parameters when realcall quirk is enabled. MER#1908
-- [common] Add quirk realcall. MER#1908
-- [common] Make pa_droid_quirk inline function.
-- [README] Add description for realcall quirk.
-
-* Wed May 16 2018 Juho Hämäläinen <juho.hamalainen@jolla.com> - 11.1.67
-- [common] Add quirk output_make_writable. JB#41899
-- [README] Add description for output_make_writable quirk.
-- [sink] Implement output_make_writable quirk. JB#41899
-
-* Sat Feb 17 2018 Juho Hämäläinen <juho.hamalainen@jolla.com> - 11.1.66
-- [card] Update to PulseAudio 11.1. JB#38694
-- [common] Decrease verbosity of failing input resume.
-- [source] Post silence if resuming input stream fails.
-
-* Tue Feb 06 2018 Juho Hämäläinen <jusa@hilvi.org> - 8.0.65
-- [card] Update record profile correctly with merged input. JB#40125
-- [common] Get mapping based on device.
-- [packaging] Bump version.
-- [sink] Use pa_memblock_acquire_chunk.
-
-* Mon Dec 18 2017 Juho Hämäläinen <juho.hamalainen@jolla.com> - 8.0.64.1
-- [packaging] Bump version. JB#40125
-
-* Mon Dec 11 2017 Juho Hämäläinen <jusa@hilvi.org> - 8.0.64
-- [common] Add new quirk no_hw_volume. JB#40292
-- [common] Set input stream to standby before closing. JB#40125
-- [README] Add description for no_hw_volume quirk.
-- [sink] Allow disabling hw volume control with quirk. JB#40292
-
-* Fri Dec 08 2017 Juho Hämäläinen <jusa@hilvi.org> - 8.0.63
-- [build] Have micro version for pc version.
-- [build] Link libraries in right order.
-- [card] Add module argument for controlling input merging.
-- [card] Attach remaining moving sink-inputs to primary sink if one exists.
-- [card] Set off profile as available.
-- [card] Use default profile with primary module by default.
-- [common] Add function to get stream latency in PulseAudio default type.
-- [common] Add option to merge input streams in default profile.
-- [common] Add quirk unload_no_close.
-- [common] Enable input_atoi quirk by default with modern adaptations.
-- [common] Refactor stream data to separate structures.
-- [common] Replace combine profile with default profile.
-- [common] Use droid mapping for input stream creation.
-- [keepalive] Fix assert when closing module immediately after startup.
-- [keepalive] Use MCE given keepalive period.
-- [modules] Flag sinks and sources with type defining properties. JB#40125
-- [modules] Open multiple sinks and sources by default. JB#40125
-- [README] Add section explaining quirks.
-- [README] Update description of droid modules.
-- [sink] Apply routing changes always immediately. Fixes MER#1832
-- [sink] Default to not mixing output routes.
-- [sink] Set created sink as data for output stream.
-- [sink] Use pa_droid_stream_get_latency() from common.
-- [sink] Use updated stream structures.
-- [source] Mark source proplist with droid api string.
-- [source] Pass droid mapping when opening input stream.
-- [source] Set created source as data for input stream.
-- [source] Use input name from mapping when loaded from droid card.
-- [source] Use updated stream structures.
-
-* Tue Oct 24 2017 Juho Hämäläinen <jusa@hilvi.org> - 8.0.62
-- [build] Check for voice uplink and downlink enums. JB#40147
-- [common] Use correct input mapping with voicecall record. Fixes JB#40147
-
-* Tue Sep 26 2017 Juho Hämäläinen <juho.hamalainen@jolla.com> - 8.0.60.1
-- [sink] Set volume control callbacks properly with hw volume.
-- [sink] Use hooks for voice volume control. Fixes JB#39621
-
-* Mon Sep 04 2017 Juho Hämäläinen <jusa@hilvi.org> - 8.0.60
-- [common] Fix output channel conversion. JB#39594
-- [common] Have correct type for function.
-- [sink] Fix segfault when running standalone sink.
-
-* Thu Apr 27 2017 Juho Hämäläinen <jusa@hilvi.org> - 8.0.59
-- [card] Remove voicecall-record implementation. JB#38419
-- [common] Add AUDIO_SOURCE_FM_TUNER to input source table.
-- [common] Log active quirks only once.
-- [common] Refactor buffer round up.
-- [common] Refactor stream opening operations. JB#38419
-- [common] Refactor stream route set function.
-- [sink] Add inline function for writing.
-- [source] Add inline function for reading.
-- [source] Close input stream by default. Fixes JB#38419
-- [source] Move standby call to stream open.
-- [source] Remove extra routing control functions. JB#38419
-- [source] Remove voicecall source code. JB#38419
-
-* Fri Mar 17 2017 Juho Hämäläinen <jusa@hilvi.org> - 8.0.58
-- [card] Add module arg for setting quirks. JB#38005
-- [common] Use dynamic quirks in addition to compile time setup. JB#38005
-
-* Mon Feb 13 2017 Juho Hämäläinen <juho.hamalainen@jolla.com> - 8.0.57
-- [build] use android-config include during enum check
-- [README] Update readme about new header defines.
-- [util] Audio api major version bitwise operation fix
-- [util] define QCOM_HARDWARE earlier
-- [util] Fix last ifdefs to have_enum checks
-- [util] Various fixes to regressions. Fixes MER#1752
-
-* Fri Jan 27 2017 Juho Hämäläinen <jusa@hilvi.org> - 8.0.56
-- [util] Extend config parser. Fixes MER#1744
-
-* Tue Jan 24 2017 Simonas Leleiva <simonas.leleiva@meramo.co.uk> - 8.0.55
-- [build] Check for a couple more enums.
-- [modules] Fix some warnings.
-- [util] Allow dynamic module/output/input count. Fixes MER#1741
-- [util-audio] Conditional IN_ALL_USB.
-- [util] Don't use IN_VOICE_CALL_MONO if it's not defined.
-
-* Fri Jan 20 2017 Juho Hämäläinen <jusa@hilvi.org> - 8.0.54
-- [build] Check for surround channel enum.
-- [util] Fix warning.
-- [util] Relocate VSID define.
-- [util] Test for surround channel availability. Fixes JB#37353
-
-* Thu Jan 19 2017 Juho Hämäläinen <juho.hamalainen@jolla.com> - 8.0.53
-- [util] Check for all input flags separately. Fixes JB#37353
-
-* Thu Jan 19 2017 Juho Hämäläinen <jusa@hilvi.org> - 8.0.52
-- [build] Add macro for testing droid header contents.
-- [build] Check for various enums in droid headers.
-- [util] Lower logging level of unknown values.
-- [util] Replace version specific conversion headers. Fixes JB#37353
-- [util] Use API version from droid headers.
-- [util] Use mako set_parameters hack also on moto_msm8960_jbbl based devices.
-
-* Tue Jun 14 2016 Juho Hämäläinen <jusa@hilvi.org> - 8.0.51
-- [util] Add all profiles with combined profile as well.
-- [util] Correct naming of arguments.
-- [util] Implement combined profile properly. Fixes JB#35462
-- [util] Make sure audio_config struct is cleared before use.
-- [util] Set initial device to current active for new streams.
-
-* Wed Jun 01 2016 Juho Hämäläinen <jusa@hilvi.org> - 8.0.50
-- [source] Only refresh routing if forced. JB#34890
-
-* Fri Apr 01 2016 Juho Hämäläinen <juho.hamalainen@jolla.com> - 8.0.49
-- [util] Fix build with HAL v1 and v2 devices. Fixes JB#34737
-
-* Fri Apr 01 2016 Juho Hämäläinen <jusa@hilvi.org> - 8.0.48
-- [card] Create normal source even if voicecall source creation was unsuccessful.
-- [card] Create specific record source for qcom 5.1 devices. Fixes JB#34737
-- [util] Use mono channel mask with qcom 5.1 devices. Fixes JB#34737
-
-* Tue Mar 22 2016 Juho Hämäläinen <juho.hamalainen@jolla.com> - 8.0.47
-- [packaging] Bump minor version.
-- [sink] Updates for PulseAudio 8.0. MER#1507
-- [source] Updates for PulseAudio 8.0. MER#1507
-- [util] Updates for PulseAudio 8.0. MER#1507
-
-* Thu Mar 17 2016 Juho Hämäläinen <jusa@hilvi.org> - 6.0.46
-- [mako] Fixed non-voicecall inputs. Fixes NEMO#873.
-- [sink] Clear extra devices when doing voicecall routings. Fixes MER#1544
-- [util-42] Remove mako hacks as ATOI workaround works as well.
-
-* Fri Feb 26 2016 Juho Hämäläinen <jusa@hilvi.org> - 6.0.45
-- [card] Enable module argument for sink silence on resume. MER#1520
-- [sink] Add module argument to write silence on resume. Fixes MER#1520
-- [sink] Slave sink follows primary sink port changes. MER#1520
-- [source] Use suspend function from common.
-- [util-44] Added mako inputs. Fixes NEMO#873.
-- [util-44] Pulseaudio output fix for mako by sledges. Contributes to NEMO#873.
-- [util] Add function to suspend streams. MER#1520
-- [util] Function to check if sink is droid sink. MER#1520
-
-* Mon Feb 01 2016 Juho Hämäläinen <jusa@hilvi.org> - 6.0.44
-- [README] Add notion about common-devel.
-- [sink] Don't try to control voice volume with non-primary streams.
-- [util-44] Make microphone and other sources work in Xiaomi Redmi 1S (armani).
-- [util-51] Add define for secondary mic. Fixes MER#1445
-- [util] Add check for primary stream.
-
-* Fri Nov 13 2015 Matti Lehtimäki <matti.lehtimaki@gmail.com> - 6.0.43
-- [build] Provide device name as string.
-- [build] Workaround for relinking phase.
-- [card] Add possibility to combine outputs to profile. MER#1419
-- [card] Use new util functions for module ops.
-- [sink] List output flags in sink proplist.
-- [sink] Name sink with output name instead of module name. MER#1419
-- [sink] Parse flags for stand-alone sink.
-- [sink] Use new util functions for stream ops. MER#1419
-- [source] Use new util functions for stream ops. MER#1419
-- [util-42] Correct default device for mako.
-- [util] Add functions for using combined profiles. MER#1419
-- [util] Add new functions for stream operations. MER#1419
-- [util,card] Store mappings in idxsets. MER#1419
-- [util] Log device name.
-- [util] Use mako set_parameters hack also on other 2011 Xperias.
-
-* Mon Nov 02 2015 Juho Hämäläinen <jusa@hilvi.org> - 6.0.42
-- [card] Better support for voicecall record. Fixes MER#1390
-- [sink] Try shared object before opening hw module.
-- [source] Allow forcing port change. MER#1390
-- [util] Add default input port to source mapping. MER#1390
-- [util] Update headers with default input device.
-
-* Fri Oct 23 2015 Juho Hämäläinen <jusa@hilvi.org> - 6.0.41
-- [build] Build libdroid-util in separate directory.
-- [build] Generate pc file for libdroid-util. MER#1377
-- [packaging] Split normal packaging to common and devel. MER#1377
-- [packaging] Split sbj packaging to common and devel.
-- [util] Move util code for separating as common.
-
-* Wed Sep 30 2015 Juho Hämäläinen <jusa@hilvi.org> - 6.0.40
-- [card] Add missing general module arguments.
-- [card] Fix typo in log message.
-- [card] Implement VSID setting when changing to voicecall.
-- [card] Remove unused define.
-- [sink] Add missing modargs to module.
-- [sink] Add overriding modargs for sink.
-- [sink] Fix typo in log message.
-- [source] Add missing modargs to module.
-- [source] Add overriding modargs for source.
-- [source] Fix typo in log message.
-- [source] Pass device as integer if needed. Fixes MER#1343
-- [util-51] Enable VSID for 5.1 with qcom bsp. Fixes MER#1356
-- [util] Include android-config.h.
-
-* Fri Sep 11 2015 Juho Hämäläinen <jusa@hilvi.org> - 6.0.39
-- [util-51] Add missing formats.
-- [util-51] Add qcom specific entries.
-- [util] Correct comparison for default audio source. Fixes MER#1286
-- [util] Use default audio source if nothing specific is defined.
-
-* Fri Sep 11 2015 Juho Hämäläinen <juho.hamalainen@jolla.com> - 6.0.38.1
-- [sink] Remove mention of buffer count.
-- [sink] Set initial latency correctly.
-- [sink] Sleep after stream writing blocks. Fixes MER#1212
-
-* Wed Aug 26 2015 Juho Hämäläinen <jusa@hilvi.org> - 6.0.38
-- [util] Make attached devices parsing more tolerant of unknown devices. Fixes MER#1265
-
-* Wed Jul 22 2015 Juho Hämäläinen <jusa@hilvi.org> - 6.0.37
-- [README] Update supported versions.
-
-* Wed Jul 22 2015 Juho Hämäläinen <juho.hamalainen@jolla.com> - 6.0.36.3
-- [util] Support parsing of dynamic formats.
-- [util] Support parsing of dynamic sample rate.
-
-* Wed Jul 22 2015 Juho Hämäläinen <juho.hamalainen@jolla.com> - 6.0.36.2
-- [sink] Preliminary 5.1 support. Contributes to MER#1188
-- [source] Preliminary 5.1 support. Contributes to MER#1188
-- [util-4x] Add or rename HAL version define.
-- [util-4x] Rename output flag conversion table.
-- [util-51] Add headers for 5.1. Contributes to MER#1188
-- [util] Audio HAL version 3.
-- [util] Parse input flags with Audio HAL v3.
-- [util] Update flag parsing to distinguish input and output flags.
-
-* Sat Jun 06 2015 Juho Hämäläinen <juho.hamalainen@tieto.com> - 6.0.36
-- [source] Fix recording on iyokan. Fixes MER#1080
-- [source] Set input stream to standby before starting the loop.
-- [source] Use mako set_parameters hack also on iyokan.
-- [util-44] Add additional string conversion table entries.
-
-* Mon May 04 2015 Juho Hämäläinen <juho.hamalainen@tieto.com> - 6.0.35
-- [build] Use dynamic versioning same way as PulseAudio.
-- [packaging] Build depends on PulseAudio major.minor version.
-- [packaging] Bump version and update build for dynamic versioning.
-- [packaging] Sbj build depends on PulseAudio major.minor version.
-- [sink,source] Use updated pa_rtpoll_run(). Contributes to JB#26620
-
-* Fri Apr 03 2015 Juho Hämäläinen <jusa@hilvi.org> - 5.0.35
-- [util-41qc] Fix fancy audio source name typo.
-- [util-42] Fix fancy audio source name typo.
-- [util-44] Add missing device fancy names.
-- [util-44] Add missing fancy names. Fixes MER#921
-- [util-44] Fix fancy audio source name typo.
-
-* Tue Feb 24 2015 Juho Hämäläinen <jusa@hilvi.org> - 5.0.33
-- [build] Bump version.
-- [card] Return status from set_parameters_cb. Fixes JB#26754
-- [util] Have common_set_parameters_cb return int.
-
-* Tue Feb 24 2015 Juho Hämäläinen <jusa@hilvi.org> - 5.0.32
-- [build] Bump version.
-- [sink] Check for errors when changing routing.
-- [source] Check for errors when changing routing.
-- [source] Set active audio source to source proplist.
-- [util-41qc] Add fancy audio source names.
-- [util-41qc] Update fancy input communication name.
-- [util-42] Add fancy audio source names.
-- [util-44] Add fancy audio source names.
-- [util-44] Default audio routes for hammerhead input devices. Fixes JB#26733
-- [util] Add parser for fancy audio source names.
-
-* Thu Feb 19 2015 Juho Hämäläinen <jusa@hilvi.org> - 5.0.31
-- [sink,source] Suspend streams before closing. Contributes to JB#26337
-- [sink] Suspend stream before closing.
-- [source] Suspend stream before closing.
-
-* Thu Jan 29 2015 Juho Hämäläinen <jusa@hilvi.org> - 5.0.30
-- [sink] Use correct argument name for devices.
-- [source] Apply input source during routing if source is defined. Contributes to JB#25679
-- [source] Use correct argument name for devices.
-- [util] Add default audio source table to util headers.
-- [util] Add function to get default audio source for input device.
-
-* Wed Jan 28 2015 Marko Saukko <marko.saukko@jolla.com> - 5.0.29
-- [changelog] Workaround promotions. Contributes to JB#8168
-
-* Thu Jan 22 2015 Juho Hämäläinen <jusa@hilvi.org> - 5.0.28
-- [util] Allow unknown entries in some cases in config parser.
-
-* Thu Jan 22 2015 Juho Hämäläinen <jusa@hilvi.org> - 5.0.27
-- [card] Remove redundant includes to fix the order of #defines
-- [util] Add missing Qualcomm specific entries for support of msm7x30 based devices
-
-* Wed Dec 17 2014 Juho Hämäläinen <jusa@hilvi.org> - 5.0.26
-- [sink] Use default output device defined in config as default.
-- [util] Preliminary support for custom properties. Contributes to JB#25126
-- [util] Refactor section parsing and recognize custom configs.
-
-* Wed Dec 17 2014 Simonas Leleiva <simonas.leleiva@meramo.co.uk> - 5.0.25
-- [util] use correct macro notation for ARM
-
-* Sun Nov 30 2014 Simonas Leleiva <simonas.leleiva@meramo.co.uk> - 5.0.24
-- [util] AUDIO_DEVICE_OUT_PROXY is only in Qualcomm devices
-- [util] tmp hack: treat ARM devices as QCOM with exceptions
-
-* Tue Nov 18 2014 Juho Hämäläinen <jusa@hilvi.org> - 5.0.23
-- [source] Set and keep IN_VOICE_CALL for voicecall source.
-
-* Wed Oct 08 2014 Juho Hämäläinen <jusa@hilvi.org> - 5.0.22
-- [git] Use single git tree for the pulseaudio-modules-droid work. Contributes to JB#21989.
-- [README] Add basic explanation of usage.
-- [sink] Do routing if sink is in SUSPENDED state.
-- [sink] Fix route muting calculations.
-- [util] Log HAL version used to build the modules.
-
-* Thu Sep 18 2014 Juho Hämäläinen <juho.hamalainen@tieto.com> - 5.0.20-1
-- [packaging] Add spec file for SBJ (Jolla).
-- [packaging] Fix SBJ spec.
-
-* Fri Aug 15 2014 Juho Hämäläinen <jusa@hilvi.org> - 5.0.20
-- [util-44] process DRC tags only for Android >=4.4 versions
-
-* Tue Aug 12 2014 Juho Hämäläinen <juho.hamalainen@tieto.com> - 5.0.19+fix1
-- [util-44] Fix header for Hammerhead.
-
-* Tue Aug 12 2014 Juho Hämäläinen <jusa@hilvi.org> - 5.0.19
-- [build] Autogenerate DROID_DEVICE_FOO for droid device.
-- [card] Add availability to virtual profile and deny activating unavailable profile.
-- [card] Add support for virtual profile extensions and voicecall record.
-- [card] Refactor virtual profiles.
-- [module-droid-source] Use updated droid-source.
-- [source] Add support for voicecall source.
-- [source] Allow usage of module argument input_devices.
-- [source] Use AUDIO_IN_VOICE_CALL_MONO only with QC hardware.
-- [util] Add hint when checking android version.
-- [util] Define QCOM_HARDWARE for Hammerhead (Nexus 5).
-- [util] Define QCOM_HARDWARE for Sbj (Jolla).
-- [util] Refactor HAL includes to per-droid-version headers.
-- [util] Remove couple unused variables.
-- [util] Remove static from headers.
-
-* Thu Aug 07 2014 Juho Hämäläinen <jusa@hilvi.org> - 5.0.18
-- [headers] Added droid-util headers for 4.4
-- [util] Add AUDIO_DEVICE_OUT_PROXY in output device conversion table
-- [util] Do not fail while parsing speaker_drc_enabled entry in audio_policy.conf
-- [util] Recognise AUDIO_CHANNEL_IN_FRONT_BACK
-- [util] Recognise AUDIO_DEVICE_OUT_PROXY
-- [util] Recognise AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD, AUDIO_OUTPUT_FLAG_NON_BLOCKING
-- [util] speaker_drc_enabled is only from HAL v2
-
-* Fri Jun 06 2014 Juho Hämäläinen <jusa@hilvi.org> - 5.0.17
-- [sink] Track stream extra devices more carefully.
-
-* Mon May 26 2014 Juho Hämäläinen <juho.hamalainen@tieto.com> - 5.0.16
-- [build] Bump version.
-- [card] Add modargs for updated voice volume control in sink.
-- [droid-util] Keep shared object name in hw module struct.
-- [droid-util] Use new device port data.
-- [modules] Remove pa_bool_t and replace it with bool.
-- [modules] Update for new pa_hashmap_new_full etc.
-- [rpm] Update for PulseAudio 5.0.
-- [sink] Change voice call volume control implementation.
-- [sink] Fix droid parameter to handle multiple property changes properly.
-- [util] Set device port priority.
-
-* Fri Mar 07 2014 Simonas Leleiva <simonas.leleiva@jollamobile.com> - 4.0.13
-- [sink] Log device hex when calling set_parameters.
-- [source] Log device hex when calling set_parameters.
-- [util] Don't add AUDIO_DEVICE_BIT_IN for mako.
-
-* Sun Feb 23 2014 Simonas Leleiva <simonas.leleiva@jollamobile.com> - 4.0.12
-- [build] Detect i9305 build.
-- [droid-source] Use IN_BUILTIN_MIC as default input device.
-- [packaging] Add i9305 device to precheckin.sh
-- [packaging] Update all spec files.
-- [packaging] Update URL in spec.in
-- [sink] Use define when setting routing.
-- [source] On i9305 set input routing without AUDIO_DEVICE_BIT_IN.
-- [source] Use define when setting routing.
-- [util] Fix HALv2 input port generation.
-
-* Tue Feb 18 2014 Juho Hämäläinen <juho.hamalainen@oss.tieto.com> - 4.0.11
-- [card] Add IN_COMMUNICATION virtual profile. Contributes to JB#13862
-- [util-41qc] Add missing output port names. Fixes JB#16120
-- [util] Add asserts to port name lookups.
-
-* Wed Dec 11 2013 Juho Hämäläinen <juho.hamalainen@oss.tieto.com> - 4.0.10
-- [droid-modules] Add possibility to set additional HAL parameters. Contributes to JB#13868
-
-* Tue Nov 19 2013 Juho Hämäläinen <juho.hamalainen@oss.tieto.com> - 4.0.9
-- [modules] Transfer config struct to hw_module instead of copying. Fixes JB#13187
-
-* Fri Nov 08 2013 Juho Hämäläinen <juho.hamalainen@oss.tieto.com> - 4.0.8
-- [keepalive] Fix segfault on module load failure. Fixes JB#12570
-
-* Thu Nov 07 2013 Juho Hämäläinen <juho.hamalainen@oss.tieto.com> - 4.0.7
-- [droid-modules] Allow different buffer lengths for sink or source.
-- [droid-modules] Set proper description for sink and source. Contributes to JB#11701
-
-* Thu Oct 17 2013 Juho Hämäläinen <juho.hamalainen@oss.tieto.com> - 4.0.6
-- [sink] Add possibility to mute during routing change. Contributes to JB#10474
-
-* Thu Oct 03 2013 Juho Hämäläinen <juho.hamalainen@oss.tieto.com> - 4.0.5
-- [card] Add ringtone virtual profile.
-- [keepalive] Fix segfault if failing to get D-Bus bus. Fixes JB#10463
-- [util] Add combo conversion field to 4.2 header.
-
-* Tue Oct 01 2013 Juho Hämäläinen <juho.hamalainen@oss.tieto.com> - 4.0.4
-- [util] Generate combo port for ihf+headphone. Contributes to JB#7576
-
-* Mon Sep 23 2013 Juho Hämäläinen <juho.hamalainen@oss.tieto.com> - 4.0.3
-- [modules] Add parking profiles for mode changes.
-- [modules] Protect hw module access with mutex.
-- [modules] Use shared hw module struct.
-- [sink] Update routing based on sink-input properties. Contributes to JB#7576
-
-* Thu Sep 12 2013 Juho Hämäläinen <juho.hamalainen@oss.tieto.com> - 4.0.2
-- [keepalive] Keepalive module sends cpu keepalive requests while streams are active. Fixes JB#8280
-- [packaging] Update build requirements.
-- [util] Fix compiler warnings.
-
-* Mon Sep 09 2013 Marko Saukko <marko.saukko@jollamobile.com> - 4.0.1
-- [build] Update PulseAudio version. Contributes to JB#6791
-- [modules] Add possibility to disable source routing during voice call.
-- [modules] Changes for PulseAudio 4.0. Fixes JB#6791
-- [modules] Set routing always.
-- [packaging] Update packaging for PulseAudio 4.0. Contributes to JB#6791
-
-* Tue Sep 03 2013 Juho Hämäläinen <juho.hamalainen@oss.tieto.com> - 2.1.3
-- [modules] Implement mute control in droid-source. Fixes JB#928
-
-* Tue Aug 27 2013 Marko Saukko <marko.saukko@jollamobile.com> - 2.1.2
-- [packaging] Add packaging for sbj.
-
-* Tue Jul 30 2013 Juho Hämäläinen <juho.hamalainen@oss.tieto.com> - 2.1.1
-- [build] Parameter to forward device type.
-- [modules] Add mako specific hack. Fixes JB#7737
-- [modules] Use voice volume control while in call. Contributes to JB#7560
-- [packaging] Pass device type to configure.
-
-* Fri Jul 19 2013 Juho Hämäläinen <juho.hamalainen@tieto.com> - 2.1.0
-- [modules] Initial version of droid-{card,sink,source}.
-- [packaging] Add base packaging.
-- [packaging] Add packaging for mako and boston.
-- [packaging] Fix BuildRequires.
-
|
[-]
[+]
|
Added |
_service:tar_git:pulseaudio-modules-droid.changes
^
|
|
[-]
[+]
|
Deleted |
_service:tar_git:pulseaudio-modules-droid-jb2q.spec
^
|
@@ -1,84 +0,0 @@
-%define pulseversion %{expand:%(rpm -q --qf '[%%{version}]' pulseaudio)}
-%define pulsemajorminor %{expand:%(echo '%{pulseversion}' | cut -d+ -f1)}
-%define moduleversion %{pulsemajorminor}.%{expand:%(echo '%{version}' | cut -d. -f3)}
-
-Name: pulseaudio-modules-droid-jb2q
-
-Summary: PulseAudio Droid HAL modules
-Version: 14.2.101
-Release: 1
-License: LGPLv2+
-URL: https://github.com/mer-hybris/pulseaudio-modules-droid-jb2q
-Source0: %{name}-%{version}.tar.bz2
-Requires: pulseaudio >= %{pulseversion}
-Requires: %{name}-common = %{version}-%{release}
-Requires: pulseaudio-module-keepalive >= 1.0.0
-BuildRequires: libtool-ltdl-devel
-BuildRequires: meson
-BuildRequires: pkgconfig(pulsecore) >= %{pulsemajorminor}
-BuildRequires: pkgconfig(android-headers)
-BuildRequires: pkgconfig(libhardware)
-BuildRequires: pkgconfig(expat)
-Provides: pulseaudio-modules-droid = %{version}
-Obsoletes: pulseaudio-modules-droid <= 14.2.95
-
-%description
-PulseAudio Droid HAL modules, supports Android versions from 4 to 10.
-
-%package common
-Summary: Common libs for the PulseAudio droid modules
-Requires: pulseaudio >= %{pulseversion}
-Provides: pulseaudio-modules-droid-common = %{version}
-Obsoletes: pulseaudio-modules-droid-common <= 14.2.95
-
-%description common
-This contains common libs for the PulseAudio droid modules.
-
-%package devel
-Summary: Development files for PulseAudio droid modules
-Requires: %{name}-common = %{version}-%{release}
-Requires: pulseaudio >= %{pulseversion}
-Provides: pulseaudio-modules-droid-devel = %{version}
-Obsoletes: pulseaudio-modules-droid-devel <= 14.2.95
-
-%description devel
-This contains development files for PulseAudio droid modules.
-
-%prep
-%autosetup -n %{name}-%{version}
-
-%build
-echo "%{moduleversion}" > .tarball-version
-# Obtain the DEVICE from the same source as used in /etc/os-release
-if [ -e "%{_includedir}/droid-devel/hw-release.vars" ]; then
-. %{_includedir}/droid-devel/hw-release.vars
-else
-. %{_libdir}/droid-devel/hw-release.vars
-fi
-%meson -Ddroid-device=$MER_HA_DEVICE
-%meson_build
-
-%install
-%meson_install
-
-%files
-%defattr(-,root,root,-)
-%{_libdir}/pulse-%{pulsemajorminor}/modules/libdroid-sink.so
-%{_libdir}/pulse-%{pulsemajorminor}/modules/libdroid-source.so
-%{_libdir}/pulse-%{pulsemajorminor}/modules/module-droid-sink.so
-%{_libdir}/pulse-%{pulsemajorminor}/modules/module-droid-source.so
-%{_libdir}/pulse-%{pulsemajorminor}/modules/module-droid-card.so
-%license COPYING
-
-%files common
-%defattr(-,root,root,-)
-%{_libdir}/pulse-%{pulsemajorminor}/modules/libdroid-util.so
-
-%files devel
-%defattr(-,root,root,-)
-%dir %{_prefix}/include/pulsecore/modules/droid
-%{_prefix}/include/pulsecore/modules/droid/version.h
-%{_prefix}/include/pulsecore/modules/droid/conversion.h
-%{_prefix}/include/pulsecore/modules/droid/droid-config.h
-%{_prefix}/include/pulsecore/modules/droid/droid-util.h
-%{_libdir}/pkgconfig/*.pc
|
[-]
[+]
|
Added |
_service:tar_git:pulseaudio-modules-droid.spec
^
|
|
[-]
[+]
|
Changed |
_service
^
|
@@ -1,8 +1,8 @@
<services>
<service name="tar_git">
- <param name="url">https://github.com/mer-hybris/pulseaudio-modules-droid-jb2q.git</param>
+ <param name="url">https://github.com/mer-hybris/pulseaudio-modules-droid.git</param>
<param name="branch">master</param>
- <param name="revision">14.2.101</param>
+ <param name="revision">14.2.100</param>
<param name="token"/>
<param name="debian"/>
<param name="dumb"/>
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-14.2.100.tar.bz2/README.md
^
|
@@ -1,7 +1,8 @@
-PulseAudio Droid modules jb2q
-=============================
+PulseAudio Droid modules
+========================
-For **Android 11+** modules see [pulseaudio-modules-droid](https://github.com/mer-hybris/pulseaudio-modules-droid).
+For adapdations for Android versions 4 to 10,
+see [pulseaudio-modules-droid-jb2q](https://github.com/mer-hybris/pulseaudio-modules-droid-jb2q)
Building of droid modules is split to two packages
* **common** (and **common-devel**) which contains shared library code for use in
@@ -13,21 +14,13 @@
Supported Android versions:
-* 4.1.x with Qualcomm extensions (tested with 4.1.2)
-* 4.2.x
-* 4.4.x
-* 5.x
-* 6.0.x
-* 7.x
-* 8.x
-* 9.x
-* 10.x
+* 11.x
Headers for defining devices and strings for different droid versions are in
-src/common/droid-util-audio.h (legacy headers for Jolla 1 in droid-util-41qc.h).
+src/common/droid-util-audio.h.
-When new devices with relevant new enums appear, add enum check to meson.build.
-Meson build will create macros HAVE_ENUM_FOO, STRING_ENTRY_IF_FOO
+When new devices with relevant new enums appear, add enum check to configure.ac.
+CC_CHECK_DROID_ENUM macro will create macros HAVE_ENUM_FOO, STRING_ENTRY_IF_FOO
and FANCY_ENTRY_IF_FOO if enum FOO exists in HAL audio.h.
For example:
@@ -71,28 +64,19 @@
### Audio policy configuration parsing
-To populate our configuration structs there exists two parsers, legacy parser
-for old .conf format present in Android versions 7.0 and older and new xml
-format present from version 7.0 upwards. The legacy format is obsoleted in
-version 7.0 but by default still in use and most 7.0 adaptations probably
-contain the legacy format. But 8.0 adaptations and up start to include only
-the new style xml format configuration files.
+Configuration parser reads audio policy xml files.
### Configuration files
-By default new style xml format is tried first and if it is not found old
-config is read next. If the configuration is in non-default location for
-some reason "config" module argument (available for all modules, card, sink,
-and source) can be used to point to the configuration file location.
+If the configuration is in non-default location for some reason "config"
+module argument can be used to point to the configuration file location.
By default files are tried in following order,
- /odm/etc/audio_policy_configuration.xml (new xml format)
- /vendor/etc/audio/audio_policy_configuration.xml (new xml format)
- /vendor/etc/audio_policy_configuration.xml (new xml format)
- /vendor/etc/audio_policy.conf (legacy format)
- /system/etc/audio_policy_configuration.xml (new xml format)
- /system/etc/audio_policy.conf (legacy format)
+ /odm/etc/audio_policy_configuration.xml
+ /vendor/etc/audio/audio_policy_configuration.xml
+ /vendor/etc/audio_policy_configuration.xml
+ /system/etc/audio_policy_configuration.xml
module-droid-card
-----------------
@@ -104,39 +88,15 @@
default profile
---------------
-When module-droid-card is loaded with default arguments, droid-card will try
-to create a default profile (called surprisingly "default"). The default
-profile will try to merge useful output and input streams to one profile,
+When module-droid-card is loaded with default arguments, droid-card will
+create a default profile (called unsurprisingly "default"). The default
+profile will merge supported output and input streams to one profile,
to allow use of possible low latency or deep buffer outputs.
-For example configuration with
-
- audio_hw_modules {
- primary {
- outputs {
- primary {}
- deep_buffer {}
- }
- inputs {
- primary {}
- voice_rx {}
- }
- }
- other {
- ...
- }
- }
-
-The default profile would contain two sinks, sink.primary and sink.deep_buffer
-and one source, source.droid.
-
-Usually this default profile is everything that is needed in normal use, and
-additional profiles created should be needed only for testing things out etc.
-
virtual profiles
----------------
-In addition to aforementioned card profiles, droid-card creates some additional
+In addition to aforementioned card profile, droid-card creates some additional
virtual profiles. These virtual profiles are used when enabling voicecall
routings etc. When virtual profile is enabled, possible sinks and sources
previously active profile had are not removed.
@@ -144,9 +104,6 @@
As an illustration, following command line sequence enables voicecall mode and
routes audio to internal handsfree (ihf - "handsfree speaker"):
-(Before starting, droid_card.primary is using profile primary-primary and
-sink.primary port output-speaker)
-
pactl set-card-profile droid_card.primary voicecall
pactl set-sink-port sink.primary output-parking
pactl set-sink-port sink.primary output-speaker
@@ -156,11 +113,11 @@
To disable voicecall and return to media audio:
- pactl set-card-profile droid_card.primary primary-primary
+ pactl set-card-profile droid_card.primary default
pactl set-sink-port sink.primary output-parking
pactl set-sink-port sink.primary output-speaker
-With this example sequence sinks and sources are the ones from primary-primary
+With this example sequence sinks and sources are the ones from default
card profile, and they are maintained for the whole duration of the voicecall
and after.
@@ -182,32 +139,9 @@
related optimizations etc. Voicecall-record profile can be enabled when
voicecall profile is active.
-debugging profiles
-------------------
-
-If needed in favour of default profile one can opt to creating combinations
-of all output and input definitions in a module definition. This can be
-done by passing "default=false" to module-droid-card. Module argument
-module_id will then defines which module to load (by default "primary").
-Without default profile all input and output definitions are translated
-to PulseAudio card profiles. For example configuration with
-
- audio_hw_modules {
- primary {
- outputs {
- primary {}
- lpa {}
- }
- inputs {
- primary {}
- }
- }
- other {
- ...
- }
- }
-
-Would map to card profiles ([output]-[input]) primary-primary and lpa-primary.
+If mix port with flag AUDIO_OUTPUT_FLAG_VOIP_RX exists when communication
+virtual profile is enabled additional droid-sink is created with the config
+defined in the mix port. Voip audio should then be played to this new sink.
module-droid-sink and module-droid-source
-----------------------------------------
@@ -216,49 +150,15 @@
hand, but droid-card loads appropriate modules based on the active card
profile.
-Output and input ports for droid-sink and droid-source are generated from the
-audio_policy_configuration.xml (where available) or audio_policy.conf (legacy),
-where each device generates (usually) one port, for example:
-
- audio_hw_modules {
- primary {
- outputs {
- primary {
- devices = AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_WIRED_HEADPHONE
- }
- lpa {}
- }
- inputs {
- primary {
- devices = AUDIO_DEVICE_IN_BUILTIN_MIC
- }
- }
- }
- }
-
-Would create following ports for sink.primary:
- * output-speaker
- * output-earpiece
- * output-wired_headphone
- * output-speaker+wired_headphone
-
-And for source.primary:
- * input-builtin_mic
-
-Only exception to one device one port rule is if output device list has both
-OUT_SPEAKER and OUT_WIRED_HEADPHONE, then one additional combination port is
-generated. How the devices are called in sink and source ports are defined in
-droid-util-XXX.h
-
-Changing output routing is then as simple as
+Changing output routing is as simple as
pactl set-sink-port sink.primary output-wired_headphone
-Sink or source do not track possible headphone/other wired accessory plugging,
-but this needs to be handled elsewhere and then that other entity needs to
-control sinks and sources. (For example in SailfishOS this entity is OHM with
-accessory-plugin and pulseaudio-policy-enforcement module for actually making
-the port switching)
+Sinks or sources do not track possible headphone/other wired accessory
+plugging, but this needs to be handled elsewhere and then that other entity
+needs to control sinks and sources. (For example in SailfishOS this entity is
+OHM with accessory-plugin and pulseaudio-policy-enforcement module for
+actually making the port switching)
Droid source automatic reconfiguration
--------------------------------------
@@ -308,6 +208,7 @@
* droid.output.low_latency
* droid.output.media_latency
* droid.output.offload
+ * droid.output.voip
* For droid sources
* droid.input.builtin
* droid.input.external
@@ -331,24 +232,20 @@
Right now there exists only one source (input device) which will always have
both properties as true.
-Quirks
-------
+Options
+-------
There are some adaptations that require hacks to get things working. These
-hacks can be enabled or disabled with module argument "quirks". Some quirks
-are enabled by default with some adaptations etc.
+hacks can be enabled or disabled with module argument "options". Some options
+are enabled by default with some adaptations etc. There are also some more
+generic options.
-Currently there are following quirks:
+Currently there are following options:
* input_atoi
* Enabled by default with Android versions 5 and up.
* Due to how atoi works in bionic vs libc we need to pass the input
route a bit funny. If input routing doesn't work switch this on or off.
-* set_parameters
- * Disabled by default.
- * Some adaptations need to use hw module's generic set_parameters call
- to change input routing. If input routing doesn't work switch this
- on or off. (mostly just older adaptations)
* close_input
* Enabled by default.
* Close input stream when not in use instead of suspending the stream.
@@ -357,22 +254,16 @@
* Disabled by default.
* Don't call audio_hw_device_close() for the hw module when unloading.
Mostly useful for tracking module unload issues.
-* no_hw_volume
- * Disabled by default.
+* hw_volume
+ * Enabled by default.
* Some broken implementations are incorrectly probed for supporting hw
volume control. This is manifested by always full volume with volume
- control not affecting volume level. To fix this enable this quirk.
-* output_make_writable
- * Disabled by default.
- * Some implementations modify write buffer in-place when this should
- not be done. This can result in random segfaults when playing audio.
- As a workaround make the buffer memchunk writable before passing to
- audio HAL.
+ control not affecting volume level. To fix this disable this option.
* realcall
* Disabled by default.
* Some vendors apply custom realcall parameter to HAL device when
doing voicecall routing. If there is no voicecall audio you can
- try enabling this quirk so that the realcall parameter is applied
+ try enabling this option so that the realcall parameter is applied
when switching to voicecall profile.
* unload_call_exit
* Disabled by default.
@@ -382,36 +273,39 @@
* output_fast
* Enabled by default.
* Create separate sink if AUDIO_OUTPUT_FLAG_FAST is found. If this sink
- is misbehaving try disabling this quirk.
+ is misbehaving try disabling this option.
* output_deep_buffer
* Enabled by default.
* Create separate sink if AUDIO_OUTPUT_FLAG_DEEP_BUFFER is found. If
- this sink is misbehaving try disabling this quirk.
+ this sink is misbehaving try disabling this option.
* audio_cal_wait
* Disabled by default.
* Certain devices do audio calibration during hw module open and
writing audio too early will break the calibration. In these cases
- this quirk can be enabled and 10 seconds of sleep is added after
+ this option can be enabled and 10 seconds of sleep is added after
opening hw module.
-* standby_set_route
- * Disabled by default.
- * Some devices don't like to receive set_parameters() call while they
- are in write(), even if it seems the mutexes are correctly in place.
- Standby is another synchronization point which seems to work better.
- If there are hiccups like long delays when setting route during
- voice call start try enabling this quirk.
* speaker_before_voice
* Disabled by default.
* Set route to speaker before changing audio mode to AUDIO_MODE_IN_CALL.
Some devices don't get routing right if the route is something else
(like AUDIO_DEVICE_OUT_WIRED_HEADSET) before calling set_mode().
If routing is wrong when call starts with wired accessory connected
- try enabling this quirk.
+ try enabling this option.
+* output_voip_rx
+ * Enabled by default.
+ * When audio configuration has AUDIO_OUTPUT_FLAG_VOIP_RX special voip
+ sink is created when AUDIO_MODE_IN_COMMUNICATION is active and the
+ sink is classified as droid.output.voip. If this is not desired then
+ by disabling this option the voip sink is not classified but is still
+ created normally.
+* record_voice_16k
+ * Disabled by default.
+ * When enabled voice call recording source is forced to sample rate
+ of 16kHz.
-For example, to disable input_atoi and enable close_input quirks, use module
-argument
+Options can be enabled or disabled normally as module arguments, for example:
- quirks=-input_atoi,+close_input
+ load-module module-droid-card hw_volume=false record_voice_16k=true
Volume control during voicecall
-------------------------------
@@ -460,8 +354,3 @@
set_parameters(handle, "route=2;");
char *value = get_parameters(handle, "connected");
-
-module-droid-keepalive
-----------------------
-
-Module relocated to its own package pulseaudio-module-keepalive.
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-14.2.100.tar.bz2/meson.build
^
|
@@ -1,4 +1,4 @@
-project('pulseaudio-modules-droid-jb2q', 'c',
+project('pulseaudio-modules-droid', 'c',
version : run_command(find_program('git-version-gen'), join_paths(meson.current_source_dir(), '.tarball-version'), check: true).stdout().strip(),
meson_version : '>= 0.50.0',
default_options : [ 'c_std=gnu11' ]
@@ -17,9 +17,7 @@
# dependencies
droid_headers_dep = dependency('android-headers', required : true)
-if get_option('xml')
- expat_dep = dependency('expat', version : '>= 2.1', required : true)
-endif
+expat_dep = dependency('expat', version : '>= 2.1', required : true)
hybris_dep = dependency('libhardware', version : '>= 0.1.0', required : true)
hybris_common_dep = cc.find_library('hybris-common', required : true)
ltdl_dep = cc.find_library('ltdl', required : true)
@@ -49,10 +47,6 @@
cdata.set_quoted('PACKAGE_VERSION', pa_version_str)
cdata.set_quoted('VERSION', pa_version_str)
-if get_option('xml')
- cdata.set('HAVE_EXPAT', 1)
-endif
-
# Atomic operations
if get_option('atomic-arm-memory-barrier')
@@ -124,75 +118,21 @@
endif
check_enums = [
-# Output devices
- 'AUDIO_DEVICE_OUT_HDMI',
- 'AUDIO_DEVICE_OUT_HDMI_ARC',
- 'AUDIO_DEVICE_OUT_TELEPHONY_TX',
- 'AUDIO_DEVICE_OUT_LINE',
- 'AUDIO_DEVICE_OUT_SPDIF',
- 'AUDIO_DEVICE_OUT_AUX_LINE',
- 'AUDIO_DEVICE_OUT_SPEAKER_SAFE',
- 'AUDIO_DEVICE_OUT_FM',
- 'AUDIO_DEVICE_OUT_FM_TX',
- 'AUDIO_DEVICE_OUT_ANC_HEADSET',
- 'AUDIO_DEVICE_OUT_ANC_HEADPHONE',
- 'AUDIO_DEVICE_OUT_PROXY',
-# Added in 6.0
- 'AUDIO_DEVICE_OUT_IP',
-
-# Input devices
- 'AUDIO_DEVICE_IN_HDMI',
- 'AUDIO_DEVICE_IN_TELEPHONY_RX',
- 'AUDIO_DEVICE_IN_FM_TUNER',
- 'AUDIO_DEVICE_IN_TV_TUNER',
- 'AUDIO_DEVICE_IN_LINE',
- 'AUDIO_DEVICE_IN_SPDIF',
- 'AUDIO_DEVICE_IN_BLUETOOTH_A2DP',
- 'AUDIO_DEVICE_IN_LOOPBACK',
- 'AUDIO_DEVICE_IN_PROXY',
+ # Input devices
'AUDIO_DEVICE_IN_FM_RX',
'AUDIO_DEVICE_IN_FM_RX_A2DP',
- 'AUDIO_DEVICE_IN_ALL_USB',
-# Added in 6.0
- 'AUDIO_DEVICE_IN_IP',
-
-# Audio sources
+ # Audio sources
+ 'AUDIO_SOURCE_ECHO_REFERENCE',
'AUDIO_SOURCE_FM_TUNER',
'AUDIO_SOURCE_FM_RX',
'AUDIO_SOURCE_FM_RX_A2DP',
-
-# Output flags
- 'AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD',
- 'AUDIO_OUTPUT_FLAG_NON_BLOCKING',
- 'AUDIO_OUTPUT_FLAG_HW_AV_SYNC',
- 'AUDIO_OUTPUT_FLAG_VOIP_RX',
- 'AUDIO_OUTPUT_FLAG_INCALL_MUSIC',
+ # Output flags
'AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH',
-# Added in 6.0
- 'AUDIO_OUTPUT_FLAG_TTS',
- 'AUDIO_OUTPUT_FLAG_RAW',
- 'AUDIO_OUTPUT_FLAG_SYNC',
- 'AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO',
-
-# Input flags
- 'AUDIO_INPUT_FLAG_NONE',
- 'AUDIO_INPUT_FLAG_FAST',
- 'AUDIO_INPUT_FLAG_HW_HOTWORD',
- 'AUDIO_INPUT_FLAG_RAW',
- 'AUDIO_INPUT_FLAG_SYNC',
- 'AUDIO_INPUT_FLAG_MMAP_NOIRQ',
- 'AUDIO_INPUT_FLAG_VOIP_TX',
-
-# Channels
- 'AUDIO_CHANNEL_OUT_SURROUND',
- 'AUDIO_CHANNEL_OUT_5POINT1_BACK',
- 'AUDIO_CHANNEL_OUT_5POINT1_SIDE',
+ # Channels
'AUDIO_CHANNEL_IN_VOICE_CALL_MONO',
'AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO',
'AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO',
-
-# Formats
- 'AUDIO_FORMAT_PCM_24_BIT_PACKED',
+ # Formats
'AUDIO_FORMAT_PCM_OFFLOAD',
'AUDIO_FORMAT_FLAC',
'AUDIO_FORMAT_OPUS',
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-14.2.100.tar.bz2/meson_options.txt
^
|
@@ -13,7 +13,3 @@
option('modlibexecdir',
type : 'string',
description : 'Specify location where modules will be installed')
-option('xml',
- type : 'boolean',
- value : true,
- description : 'Enable optional xml config support')
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-14.2.100.tar.bz2/src/common/config-parser-xml.c
^
|
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 Jolla Ltd.
+ * Copyright (C) 2018-2022 Jolla Ltd.
*
* Contact: Juho Hämäläinen <juho.hamalainen@jolla.com>
*
@@ -26,15 +26,6 @@
#include "droid/droid-config.h"
-#ifndef HAVE_EXPAT
-#include <unistd.h>
-pa_droid_config_audio *pa_parse_droid_audio_config_xml(const char *filename) {
- if (access(filename, F_OK) == 0)
- pa_log_warn("Could not parse %s, xml configuration parsing support not compiled in", filename);
- return NULL;
-}
-#else
-
#include <stdarg.h>
#include <string.h>
#include <expat.h>
@@ -46,6 +37,9 @@
#include "droid/conversion.h"
#include "droid/sllist.h"
+#include "droid/utils.h"
+#include "droid/droid-config.h"
+#include "config-parser-xml.h"
#ifdef XML_UNICODE_WCHAR_T
# include <wchar.h>
@@ -86,6 +80,9 @@
#define ATTRIBUTE_sources "sources"
#define ATTRIBUTE_type "type"
#define ATTRIBUTE_href "href"
+#define ATTRIBUTE_maxOpenCount "maxOpenCount"
+#define ATTRIBUTE_maxActiveCount "maxActiveCount"
+#define ATTRIBUTE_address "address"
#define PORT_TYPE_sink "sink"
#define PORT_TYPE_source "source"
@@ -302,7 +299,7 @@
char *name;
audio_format_t format;
uint32_t sampling_rates[AUDIO_MAX_SAMPLING_RATES];
- audio_channel_mask_t channel_masks;
+ audio_channel_mask_t channel_masks[AUDIO_MAX_CHANNEL_MASKS];
struct profile *next;
};
@@ -310,6 +307,8 @@
char *name;
char *role;
uint32_t flags;
+ int max_open_count;
+ int max_active_count;
struct profile *profiles;
struct mix_port *next;
};
@@ -318,6 +317,7 @@
char *tag_name;
audio_devices_t type;
char *role;
+ char *address;
struct profile *profiles;
struct device_port *next;
};
@@ -423,6 +423,7 @@
profile_list_free(p->profiles);
pa_xfree(p->tag_name);
pa_xfree(p->role);
+ pa_xfree(p->address);
pa_xfree(p);
}
}
@@ -717,6 +718,8 @@
struct mix_port *p;
bool parsed = false;
char *flags = NULL;
+ char *max_open_count = NULL;
+ char *max_active_count = NULL;
p = pa_xmalloc0(sizeof(*p));
@@ -734,6 +737,14 @@
goto done;
}
+ /* maxOpenCount is not mandatory element attribute */
+ if (get_element_attr(data, attributes, false, ATTRIBUTE_maxOpenCount, &max_open_count))
+ pa_atoi(max_open_count, &p->max_open_count);
+
+ /* maxActiveCount is not mandatory element attribute */
+ if (get_element_attr(data, attributes, false, ATTRIBUTE_maxActiveCount, &max_active_count))
+ pa_atoi(max_open_count, &p->max_active_count);
+
parsed = true;
done:
pa_xfree(flags);
@@ -749,18 +760,6 @@
return parsed;
}
-static void replace_in_place(char **string, const char *a, const char *b) {
- char *tmp;
-
- pa_assert(*string);
- pa_assert(a);
- pa_assert(b);
-
- tmp = pa_replace(*string, a, b);
- pa_xfree(*string);
- *string = tmp;
-}
-
static bool parse_profile(struct parser_data *data, const char *element_name, const XML_Char **attributes) {
struct profile *p;
int channel_count = -1;
@@ -796,24 +795,24 @@
if (output && pa_startswith(channelMasks, "AUDIO_CHANNEL_IN_")) {
pa_log_info("[%s:%u] Output has wrong direction channel mask (%s), reversing.",
data->fn, data->lineno, channelMasks);
- replace_in_place(&channelMasks, "AUDIO_CHANNEL_IN_", "AUDIO_CHANNEL_OUT_");
+ dm_replace_in_place(&channelMasks, "AUDIO_CHANNEL_IN_", "AUDIO_CHANNEL_OUT_");
}
else if (!output && pa_startswith(channelMasks, "AUDIO_CHANNEL_OUT_")) {
pa_log_info("[%s:%u] Input has wrong direction channel mask (%s), reversing.",
data->fn, data->lineno, channelMasks);
- replace_in_place(&channelMasks, "AUDIO_CHANNEL_OUT_", "AUDIO_CHANNEL_IN_");
+ dm_replace_in_place(&channelMasks, "AUDIO_CHANNEL_OUT_", "AUDIO_CHANNEL_IN_");
}
}
- if (!pa_conversion_parse_sampling_rates(data->fn, data->lineno, samplingRates, false, p->sampling_rates))
+ if (!pa_conversion_parse_sampling_rates(data->fn, data->lineno, samplingRates, p->sampling_rates))
goto done;
- if (!pa_conversion_parse_formats(data->fn, data->lineno, format, false, &p->format))
+ if (!pa_conversion_parse_formats(data->fn, data->lineno, format, &p->format))
unknown_format = true;
if (!unknown_format && channelMasks && (channel_count = output ?
- pa_conversion_parse_output_channels(data->fn, data->lineno, channelMasks, false, &p->channel_masks)
- : pa_conversion_parse_input_channels(data->fn, data->lineno, channelMasks, false, &p->channel_masks)) == -1)
+ pa_conversion_parse_output_channels(data->fn, data->lineno, channelMasks, p->channel_masks)
+ : pa_conversion_parse_input_channels(data->fn, data->lineno, channelMasks, p->channel_masks)) == -1)
goto done;
parsed = true;
@@ -860,10 +859,13 @@
goto done;
if (!(pa_streq(d->role, ATTRIBUTE_sink) ?
- pa_conversion_parse_output_devices(data->fn, data->lineno, type, false, false, &d->type)
- : pa_conversion_parse_input_devices(data->fn, data->lineno, type, false, false, &d->type)))
+ pa_conversion_parse_output_devices(data->fn, data->lineno, type, false, &d->type)
+ : pa_conversion_parse_input_devices(data->fn, data->lineno, type, false, &d->type)))
unknown_device = true;
+ /* address is not mandatory element attribute */
+ get_element_attr(data, attributes, false, ATTRIBUTE_address, &d->address);
+
parsed = true;
done:
pa_xfree(type);
@@ -973,133 +975,205 @@
return ret;
}
-static struct device_port *find_device_port(struct module *module, const char *name) {
- struct device_port *port;
+static void generate_config_profiles(struct profile *profiles, dm_list *list) {
+ struct profile *profile;
- SLLIST_FOREACH(port, module->device_ports) {
- if (pa_streq(port->tag_name, name))
- return port;
+ SLLIST_FOREACH(profile, profiles) {
+ dm_config_profile *c_profile = pa_xnew0(dm_config_profile, 1);
+ c_profile->name = pa_xstrdup(profile->name ? profile->name : "");
+ c_profile->format = profile->format;
+ memcpy(c_profile->sampling_rates,
+ profile->sampling_rates,
+ sizeof(c_profile->sampling_rates));
+ memcpy(c_profile->channel_masks,
+ profile->channel_masks,
+ sizeof(c_profile->channel_masks));
+ dm_list_push_back(list, c_profile);
}
-
- return NULL;
}
-static bool device_in_list(struct device *list, const char *name) {
- struct device *dev;
+static dm_config_port *config_device_port_new(dm_config_module *module,
+ struct device_port *device_port) {
+ dm_config_port *c_device_port = pa_xnew0(dm_config_port, 1);
+
+ c_device_port->module = module;
+ c_device_port->port_type = DM_CONFIG_TYPE_DEVICE_PORT;
+ c_device_port->name = pa_xstrdup(device_port->tag_name);
+ c_device_port->type = device_port->type;
+ c_device_port->role = pa_safe_streq(device_port->role, "sink") ? DM_CONFIG_ROLE_SINK : DM_CONFIG_ROLE_SOURCE;
+ c_device_port->address = pa_xstrdup(device_port->address ? device_port->address : "");
+ c_device_port->profiles = dm_list_new();
+ if (device_port->profiles->next)
+ pa_log("More than 1 profile for devicePort %s, ignoring extra profiles.", device_port->tag_name);
+ generate_config_profiles(device_port->profiles, c_device_port->profiles);
+
+ return c_device_port;
+}
+
+static dm_config_port *config_mix_port_new(dm_config_module *module,
+ struct mix_port *mix_port) {
+ dm_config_port *c_mix_port = pa_xnew0(dm_config_port, 1);
+
+ c_mix_port->module = module;
+ c_mix_port->port_type = DM_CONFIG_TYPE_MIX_PORT;
+ c_mix_port->name = pa_xstrdup(mix_port->name);
+ c_mix_port->role = pa_safe_streq(mix_port->role, "sink") ? DM_CONFIG_ROLE_SINK : DM_CONFIG_ROLE_SOURCE;
+ c_mix_port->flags = mix_port->flags;
+ c_mix_port->max_open_count = mix_port->max_open_count;
+ c_mix_port->max_active_count = mix_port->max_active_count;
+ c_mix_port->profiles = dm_list_new();
+ generate_config_profiles(mix_port->profiles, c_mix_port->profiles);
+
+ return c_mix_port;
+}
+
+/* If a devicePort doesn't have any profiles defined let's just make something
+ * up that could work. */
+static struct profile *default_profile(const char *role) {
+ struct profile *p;
+ bool output;
- pa_assert(name);
+ output = pa_safe_streq(role, PORT_TYPE_sink);
- SLLIST_FOREACH(dev, list) {
- if (pa_streq(name, dev->name))
- return true;
- }
+ p = pa_xmalloc0(sizeof(*p));
+
+ p->name = pa_sprintf_malloc("generated-default");
+ pa_assert(pa_string_convert_str_to_num(CONV_STRING_FORMAT, "AUDIO_FORMAT_PCM_16_BIT", &p->format));
+ p->sampling_rates[0] = 48000;
+ pa_assert(pa_string_convert_str_to_num(output ? CONV_STRING_OUTPUT_CHANNELS : CONV_STRING_INPUT_CHANNELS,
+ output ? "AUDIO_CHANNEL_OUT_STEREO" : "AUDIO_CHANNEL_IN_STEREO",
+ &p->channel_masks[0]));
+ p->next = NULL;
- return false;
+ return p;
}
-static void add_output(struct module *module, struct mix_port *mix_port, pa_droid_config_hw_module *hw_module) {
- pa_droid_config_device *output;
- struct profile *profile;
- struct route *route;
+static void generate_config_for_module(struct module *module, dm_config_device *config) {
+ dm_config_module *c_module;
+ struct mix_port *mix_port;
struct device_port *device_port;
+ struct device *device;
+ struct route *route;
- output = pa_droid_config_device_new(hw_module, PA_DIRECTION_OUTPUT, mix_port->name);
- output->flags = mix_port->flags;
- SLLIST_FOREACH(profile, mix_port->profiles) {
- memcpy(output->sampling_rates, profile->sampling_rates, sizeof(output->sampling_rates));
- output->channel_masks |= profile->channel_masks;
- output->formats |= profile->format;
- }
+ pa_assert(module);
+ pa_assert(config);
- SLLIST_FOREACH(route, module->routes) {
- struct device *source;
- SLLIST_FOREACH(source, route->sources) {
- if (pa_streq(source->name, mix_port->name)) {
- if ((device_port = find_device_port(module, route->sink))) {
- output->devices |= device_port->type;
- if (device_in_list(module->attached_devices, device_port->tag_name))
- hw_module->global_config->attached_output_devices |= device_port->type;
- if (device_in_list(module->default_output, device_port->tag_name))
- hw_module->global_config->default_output_device |= device_port->type;
- break;
- } else
- pa_log_info("Couldn't find matching <" ELEMENT_devicePort " tagName=%s> for <" ELEMENT_mixPort " name=%s>",
- route->sink, source->name);
- }
+ c_module = pa_xnew0(dm_config_module, 1);
+ c_module->config = config;
+ c_module->name = pa_xstrdup(module->name);
+ c_module->version_major = 0; /* Not used */
+ c_module->version_minor = 0; /* Not used */
+ c_module->attached_devices = dm_list_new();
+ c_module->mix_ports = dm_list_new();
+ c_module->device_ports = dm_list_new();
+ c_module->ports = dm_list_new();
+ c_module->routes = dm_list_new();
+
+ /* Device ports */
+
+ SLLIST_FOREACH(device_port, module->device_ports) {
+ dm_config_port *c_device_port;
+
+ if (!device_port->profiles) {
+ pa_log_info("No profile defined for devicePort %s, generating default.", device_port->tag_name);
+ SLLIST_APPEND(struct profile, device_port->profiles, default_profile(device_port->role));
}
+
+ c_device_port = config_device_port_new(c_module, device_port);
+ dm_list_push_back(c_module->ports, c_device_port);
+ dm_list_push_back(c_module->device_ports, c_device_port);
}
- pa_log_debug("config: %s: New output: %s", hw_module->name, output->name);
- SLLIST_APPEND(pa_droid_config_device, hw_module->outputs, output);
-}
+ /* Attached devices */
-static void add_input(struct module *module, struct mix_port *mix_port, pa_droid_config_hw_module *hw_module) {
- pa_droid_config_device *input;
- struct profile *profile;
- struct route *route;
- struct device_port *device_port;
+ SLLIST_FOREACH(device, module->attached_devices) {
+ dm_config_port *c_device_port;
+ void *state;
- input = pa_droid_config_device_new(hw_module, PA_DIRECTION_INPUT, mix_port->name);
- input->flags = mix_port->flags;
- SLLIST_FOREACH(profile, mix_port->profiles) {
- memcpy(input->sampling_rates, profile->sampling_rates, sizeof(input->sampling_rates));
- input->channel_masks |= profile->channel_masks;
- input->formats |= profile->format;
+ DM_LIST_FOREACH_DATA(c_device_port, c_module->device_ports, state) {
+ if (pa_safe_streq(c_device_port->name, device->name)) {
+ dm_list_push_back(c_module->attached_devices, c_device_port);
+ break;
+ }
+ }
}
- SLLIST_FOREACH(route, module->routes) {
- if (pa_streq(route->sink, mix_port->name)) {
- struct device *source;
- SLLIST_FOREACH(source, route->sources) {
- if ((device_port = find_device_port(module, source->name))) {
- input->devices |= device_port->type;
- if (device_in_list(module->attached_devices, device_port->tag_name))
- hw_module->global_config->attached_input_devices |= device_port->type;
- } else
- pa_log_info("Couldn't find matching <" ELEMENT_mixPort " name=%s> for <" ELEMENT_devicePort " tagName=%s>",
- source->name, route->sink);
+ /* Default output device */
+ if (module->default_output) {
+ dm_config_port *c_device_port;
+ void *state;
+
+ DM_LIST_FOREACH_DATA(c_device_port, c_module->device_ports, state) {
+ if (pa_safe_streq(c_device_port->name, module->default_output->name)) {
+ c_module->default_output_device = c_device_port;
+ break;
}
}
}
- pa_log_debug("config: %s: New input: %s", hw_module->name, input->name);
- SLLIST_APPEND(pa_droid_config_device, hw_module->inputs, input);
-}
+ /* Mix ports */
-static void generate_config_for_module(struct module *module, pa_droid_config_audio *config) {
- pa_droid_config_hw_module *hw_module;
- struct mix_port *mix_port;
+ SLLIST_FOREACH(mix_port, module->mix_ports) {
+ dm_config_port *c_mix_port = config_mix_port_new(c_module, mix_port);
+ dm_list_push_back(c_module->ports, c_mix_port);
+ dm_list_push_back(c_module->mix_ports, c_mix_port);
+ }
- pa_assert(module);
- pa_assert(config);
- pa_assert(config->global_config);
+ /* Routes */
- hw_module = pa_droid_config_hw_module_new(config, module->name);
- if (module->attached_devices || module->default_output)
- hw_module->global_config = pa_xnew0(pa_droid_config_global, 1);
- SLLIST_APPEND(pa_droid_config_hw_module, config->hw_modules, hw_module);
+ SLLIST_FOREACH(route, module->routes) {
+ dm_config_route *c_route = pa_xnew0(dm_config_route, 1);
+ dm_config_port *c_port;
+ void *state;
+ c_route->sources = dm_list_new();
+
+ if (!pa_safe_streq(route->type, "mix"))
+ pa_log("Unknown route type %s.", route->type);
+ c_route->type = DM_CONFIG_TYPE_MIX;
+
+ DM_LIST_FOREACH_DATA(c_port, c_module->ports, state) {
+ if (pa_safe_streq(route->sink, c_port->name)) {
+ c_route->sink = c_port;
+ break;
+ }
+ }
- SLLIST_FOREACH(mix_port, module->mix_ports) {
- if (pa_streq(mix_port->role, PORT_TYPE_source))
- add_output(module, mix_port, hw_module);
- else if (pa_streq(mix_port->role, ATTRIBUTE_sink))
- add_input(module, mix_port, hw_module);
- else
- pa_log_warn("Unknown <" ELEMENT_mixPort "> role \"%s\"", mix_port->role);
+ SLLIST_FOREACH(device, route->sources) {
+ DM_LIST_FOREACH_DATA(c_port, c_module->ports, state) {
+ if (pa_safe_streq(device->name, c_port->name)) {
+ dm_list_push_back(c_route->sources, c_port);
+ break;
+ }
+ }
+ }
+
+ dm_list_push_back(c_module->routes, c_route);
}
+
+ dm_list_push_back(config->modules, c_module);
}
-static pa_droid_config_audio *convert_config(struct audio_policy_configuration *source) {
- pa_droid_config_audio *config = NULL;
+static dm_config_device *process_config(struct audio_policy_configuration *source) {
+ dm_config_device *config = NULL;
+ struct global_configuration *global_config;
struct module *module;
pa_assert(source);
- config = pa_xnew0(pa_droid_config_audio, 1);
- config->global_config = pa_xnew0(pa_droid_config_global, 1);
+ config = pa_xnew0(dm_config_device, 1);
+ config->global_config = dm_list_new();
+ config->modules = dm_list_new();
+
+ pa_log_debug("Process configuration ...");
+
+ SLLIST_FOREACH(global_config, source->global) {
+ dm_config_global *c_global = pa_xnew0(dm_config_global, 1);
+ c_global->key = pa_xstrdup(global_config->key);
+ c_global->value = pa_xstrdup(global_config->value);
+ dm_list_push_back(config->global_config, c_global);
+ };
- pa_log_debug("Convert configuration ...");
SLLIST_FOREACH(module, source->modules)
generate_config_for_module(module, config);
@@ -1131,8 +1205,8 @@
return fn;
}
-pa_droid_config_audio *pa_parse_droid_audio_config_xml(const char *filename) {
- pa_droid_config_audio *config = NULL;
+dm_config_device *pa_parse_droid_audio_config_xml(const char *filename) {
+ dm_config_device *config = NULL;
struct parser_data data;
bool ret = true;
@@ -1161,7 +1235,7 @@
}
}
- config = convert_config(data.conf);
+ config = process_config(data.conf);
done:
if (data.conf)
@@ -1169,5 +1243,3 @@
return config;
}
-
-#endif
|
[-]
[+]
|
Added |
_service:tar_git:pulseaudio-modules-droid-14.2.100.tar.bz2/src/common/config-parser-xml.h
^
|
@@ -0,0 +1,33 @@
+#ifndef foodroidconfigparserxmlfoo
+#define foodroidconfigparserxmlfoo
+
+/*
+ * Copyright (C) 2022 Jolla Ltd.
+ *
+ * Contact: Juho Hämäläinen <juho.hamalainen@jolla.com>
+ *
+ * These PulseAudio Modules are 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
+ * version 2.1 of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <droid/droid-config.h>
+
+dm_config_device *pa_parse_droid_audio_config_xml(const char *filename);
+
+#endif
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-14.2.100.tar.bz2/src/common/conversion.c
^
|
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2018 Jolla Ltd.
+ * Copyright (C) 2013-2022 Jolla Ltd.
*
* Contact: Juho Hämäläinen <juho.hamalainen@jolla.com>
*
@@ -55,7 +55,7 @@
CONVERT_FUNC(output_channel);
CONVERT_FUNC(input_channel);
-#define value_separator(legacy) (legacy ? "|" : ",")
+#define VALUE_SEPARATOR ","
static bool string_convert_num_to_str(const struct string_conversion *list, const uint32_t value, const char **to_str) {
pa_assert(list);
@@ -88,18 +88,7 @@
char *str = NULL;
char *tmp;
-#if AUDIO_API_VERSION_MAJ >= 2
- if (flags & AUDIO_DEVICE_BIT_IN)
- flags &= ~AUDIO_DEVICE_BIT_IN;
-#endif
-
for (unsigned int i = 0; list[i].str; i++) {
-#if AUDIO_API_VERSION_MAJ >= 2
- if (list[i].value & AUDIO_DEVICE_BIT_IN) {
- if (popcount(list[i].value & ~AUDIO_DEVICE_BIT_IN) != 1)
- continue;
- } else
-#endif
if (popcount(list[i].value) != 1)
continue;
@@ -189,10 +178,6 @@
return string_convert_str_to_num(string_conversion_table_output_device, str, (uint32_t*) to_value);
}
-char *pa_list_string_output_device(audio_devices_t devices) {
- return list_string(string_conversion_table_output_device, devices);
-}
-
/* Input device */
bool pa_string_convert_input_device_num_to_str(audio_devices_t value, const char **to_str) {
return string_convert_num_to_str(string_conversion_table_input_device, (uint32_t) value, to_str);
@@ -202,10 +187,6 @@
return string_convert_str_to_num(string_conversion_table_input_device, str, (uint32_t*) to_value);
}
-char *pa_list_string_input_device(audio_devices_t devices) {
- return list_string(string_conversion_table_input_device, devices);
-}
-
/* Flags */
bool pa_string_convert_flag_num_to_str(audio_output_flags_t value, const char **to_str) {
return string_convert_num_to_str(string_conversion_table_output_flag, (uint32_t) value, to_str);
@@ -221,13 +202,9 @@
bool pa_input_device_default_audio_source(audio_devices_t input_device, audio_source_t *default_source)
{
-#if AUDIO_API_VERSION_MAJ >= 2
- input_device &= ~AUDIO_DEVICE_BIT_IN;
-#endif
-
/* Note converting HAL values to different HAL values! */
for (unsigned int i = 0; i < sizeof(conversion_table_default_audio_source) / (sizeof(uint32_t) * 2); i++) {
- if (conversion_table_default_audio_source[i][0] & input_device) {
+ if (conversion_table_default_audio_source[i][0] == input_device) {
*default_source = conversion_table_default_audio_source[i][1];
return true;
}
@@ -321,7 +298,7 @@
}
bool pa_conversion_parse_sampling_rates(const char *fn, const unsigned ln,
- const char *str, bool legacy,
+ const char *str,
uint32_t sampling_rates[AUDIO_MAX_SAMPLING_RATES]) {
pa_assert(fn);
pa_assert(str);
@@ -330,16 +307,14 @@
const char *state = NULL;
uint32_t pos = 0;
- while ((entry = pa_split(str, value_separator(legacy), &state))) {
+ while ((entry = pa_split(str, VALUE_SEPARATOR, &state))) {
int32_t val;
-#if AUDIO_API_VERSION_MAJ >= 3
if (pos == 0 && pa_streq(entry, "dynamic")) {
sampling_rates[pos++] = (uint32_t) -1;
pa_xfree(entry);
break;
}
-#endif
if (pos == AUDIO_MAX_SAMPLING_RATES) {
pa_log("[%s:%u] Too many sample rate entries (> %d)", fn, ln, AUDIO_MAX_SAMPLING_RATES);
@@ -389,7 +364,7 @@
}
bool pa_conversion_parse_formats(const char *fn, const unsigned ln,
- const char *str, bool legacy,
+ const char *str,
audio_format_t *formats) {
int count;
char *unknown = NULL;
@@ -398,18 +373,13 @@
pa_assert(str);
pa_assert(formats);
-#if AUDIO_API_VERSION_MAJ >= 3
/* Needs to be probed later */
if (pa_streq(str, "dynamic")) {
*formats = 0;
return true;
}
-#endif
-
- count = pa_conversion_parse_list(CONV_STRING_FORMAT, value_separator(legacy), str, formats, &unknown);
- if (legacy)
- return check_and_log(fn, ln, "formats", count, str, unknown, false);
+ count = pa_conversion_parse_list(CONV_STRING_FORMAT, VALUE_SEPARATOR, str, formats, &unknown);
/* As the new XML configuration lists formats as one per profile, unknown
* formats will cause the parser to quit. As a workaround for non-legacy
@@ -420,23 +390,46 @@
static int parse_channels(const char *fn, const unsigned ln,
const char *str, bool in_output,
- bool legacy, audio_channel_mask_t *channels) {
- int count;
+ audio_channel_mask_t channel_masks[AUDIO_MAX_CHANNEL_MASKS]) {
bool success;
+ int count = 0;
char *unknown = NULL;
+ char *entry;
+ const char *state = NULL;
pa_assert(fn);
pa_assert(str);
- pa_assert(channels);
/* Needs to be probed later */
if (pa_streq(str, "dynamic")) {
- *channels = 0;
+ channel_masks[0] = 0;
return 1;
}
- count = pa_conversion_parse_list(in_output ? CONV_STRING_OUTPUT_CHANNELS : CONV_STRING_INPUT_CHANNELS,
- value_separator(legacy), str, channels, &unknown);
+ while ((entry = pa_split(str, VALUE_SEPARATOR, &state))) {
+ uint32_t val;
+
+ if (count == AUDIO_MAX_CHANNEL_MASKS) {
+ pa_log("[%s:%u] Too many channel mask entries (> %d)", fn, ln, AUDIO_MAX_CHANNEL_MASKS);
+ pa_xfree(entry);
+ return false;
+ }
+
+ if (!string_convert_str_to_num(in_output ? string_conversion_table_output_channels
+ : string_conversion_table_input_channels,
+ entry,
+ &val)) {
+ pa_log_debug("[%s:%u] Ignore unknown channel mask value %s", fn, ln, entry);
+ pa_xfree(entry);
+ continue;
+ }
+
+ channel_masks[count++] = val;
+
+ pa_xfree(entry);
+ }
+
+ channel_masks[count] = 0;
/* Avoid aborting parsing when no supported channel is found */
success = check_and_log(fn, ln, in_output ? "output channel_masks" : "input channel_masks",
@@ -445,20 +438,20 @@
}
int pa_conversion_parse_output_channels(const char *fn, const unsigned ln,
- const char *str, bool legacy,
- audio_channel_mask_t *channels) {
- return parse_channels(fn, ln, str, true, legacy, channels);
+ const char *str,
+ audio_channel_mask_t channel_masks[AUDIO_MAX_CHANNEL_MASKS]) {
+ return parse_channels(fn, ln, str, true, channel_masks);
}
int pa_conversion_parse_input_channels(const char *fn, const unsigned ln,
- const char *str, bool legacy,
- audio_channel_mask_t *channels) {
- return parse_channels(fn, ln, str, false, legacy, channels);
+ const char *str,
+ audio_channel_mask_t channel_masks[AUDIO_MAX_CHANNEL_MASKS]) {
+ return parse_channels(fn, ln, str, false, channel_masks);
}
static bool parse_devices(const char *fn, const unsigned ln,
const char *str, bool in_output,
- bool legacy, bool must_recognize_all,
+ bool must_recognize_all,
audio_devices_t *devices) {
int count;
char *unknown = NULL;
@@ -468,11 +461,7 @@
pa_assert(devices);
count = pa_conversion_parse_list(in_output ? CONV_STRING_OUTPUT_DEVICE : CONV_STRING_INPUT_DEVICE,
- value_separator(legacy), str, devices, &unknown);
-
- if (legacy)
- return check_and_log(fn, ln, in_output ? "output devices" : "input devices",
- count, str, unknown, must_recognize_all);
+ VALUE_SEPARATOR, str, devices, &unknown);
/* As the new XML configuration lists devices as one per devicePort, unknown
* devices will cause the parser to quit. As a workaround for non-legacy
@@ -483,15 +472,15 @@
}
bool pa_conversion_parse_output_devices(const char *fn, const unsigned ln,
- char *str, bool legacy, bool must_recognize_all,
+ char *str, bool must_recognize_all,
audio_devices_t *devices) {
- return parse_devices(fn, ln, str, true, legacy, must_recognize_all, devices);
+ return parse_devices(fn, ln, str, true, must_recognize_all, devices);
}
bool pa_conversion_parse_input_devices(const char *fn, const unsigned ln,
- char *str, bool legacy, bool must_recognize_all,
+ char *str, bool must_recognize_all,
audio_devices_t *devices) {
- return parse_devices(fn, ln, str, false, legacy, must_recognize_all, devices);
+ return parse_devices(fn, ln, str, false, must_recognize_all, devices);
}
bool pa_conversion_parse_output_flags(const char *fn, const unsigned ln,
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-14.2.100.tar.bz2/src/common/droid-config.c
^
|
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2018 Jolla Ltd.
+ * Copyright (C) 2013-2022 Jolla Ltd.
*
* Contact: Juho Hämäläinen <juho.hamalainen@jolla.com>
*
@@ -26,6 +26,7 @@
#include "droid/version.h"
#include "droid/droid-config.h"
#include "droid/sllist.h"
+#include "config-parser-xml.h"
#include <signal.h>
#include <stdio.h>
@@ -36,52 +37,28 @@
#include <valgrind/memcheck.h>
#endif
-#include <pulse/rtclock.h>
-#include <pulse/timeval.h>
-#include <pulse/volume.h>
#include <pulse/xmalloc.h>
-
-#include <pulsecore/core.h>
-#include <pulsecore/core-error.h>
-#include <pulsecore/i18n.h>
-#include <pulsecore/module.h>
-#include <pulsecore/memchunk.h>
-#include <pulsecore/sink.h>
-#include <pulsecore/modargs.h>
-#include <pulsecore/core-rtclock.h>
#include <pulsecore/core-util.h>
-#include <pulsecore/sample-util.h>
#include <pulsecore/log.h>
#include <pulsecore/macro.h>
-#include <pulsecore/thread.h>
-#include <pulsecore/thread-mq.h>
-#include <pulsecore/rtpoll.h>
-#include <pulsecore/time-smoother.h>
-#include <pulsecore/refcnt.h>
-#include <pulsecore/shared.h>
-#include <pulsecore/mutex.h>
-#include <pulsecore/strlist.h>
-#include <pulsecore/atomic.h>
+#include <pulsecore/modargs.h>
#include <hardware/audio.h>
-#include <hardware_legacy/audio_policy_conf.h>
-#define ODM_AUDIO_POLICY_CONFIG_XML_FILE "/odm/etc/audio_policy_configuration.xml"
-#define VENDOR_AUDIO_AUDIO_POLICY_CONFIG_XML_FILE "/vendor/etc/audio/audio_policy_configuration.xml"
-#define VENDOR_AUDIO_POLICY_CONFIG_XML_FILE "/vendor/etc/audio_policy_configuration.xml"
-#define SYSTEM_AUDIO_POLICY_CONFIG_XML_FILE "/system/etc/audio_policy_configuration.xml"
+#define ODM_AUDIO_POLICY_CONFIG_XML_FILE "/odm/etc/audio_policy_configuration.xml"
+#define VENDOR_AUDIO_AUDIO_POLICY_CONFIG_XML_FILE "/vendor/etc/audio/audio_policy_configuration.xml"
+#define VENDOR_AUDIO_POLICY_CONFIG_XML_FILE "/vendor/etc/audio_policy_configuration.xml"
+#define SYSTEM_AUDIO_POLICY_CONFIG_XML_FILE "/system/etc/audio_policy_configuration.xml"
-pa_droid_config_audio *pa_droid_config_load(pa_modargs *ma) {
- pa_droid_config_audio *config = NULL;
+dm_config_device *dm_config_load(pa_modargs *ma) {
+ dm_config_device *config = NULL;
const char *manual_config;
const char *config_location[] = {
ODM_AUDIO_POLICY_CONFIG_XML_FILE,
VENDOR_AUDIO_AUDIO_POLICY_CONFIG_XML_FILE,
VENDOR_AUDIO_POLICY_CONFIG_XML_FILE,
- AUDIO_POLICY_VENDOR_CONFIG_FILE,
SYSTEM_AUDIO_POLICY_CONFIG_XML_FILE,
- AUDIO_POLICY_CONFIG_FILE,
NULL};
pa_assert(ma);
@@ -106,92 +83,210 @@
return config;
}
-pa_droid_config_audio *pa_droid_config_dup(const pa_droid_config_audio *config) {
- pa_droid_config_audio *config_copy;
- pa_droid_config_hw_module *module, *module_copy;
- pa_droid_config_device *device, *device_copy;
+static dm_config_profile *config_profile_dup(const dm_config_profile *profile) {
+ dm_config_profile *copy = pa_xnew0(dm_config_profile, 1);
- pa_assert(config);
+ copy->name = pa_xstrdup(profile->name);
+ copy->format = profile->format;
+ memcpy(copy->sampling_rates,
+ profile->sampling_rates,
+ sizeof(profile->sampling_rates));
+ memcpy(copy->channel_masks,
+ profile->channel_masks,
+ sizeof(profile->channel_masks));
+
+ return copy;
+}
+
+static dm_config_port *config_port_dup(const dm_config_port *port, dm_config_module *module) {
+ dm_config_port *copy = pa_xnew0(dm_config_port, 1);
+ const dm_list_entry *i;
+
+ copy->module = module;
+ copy->port_type = port->port_type;
+ copy->name = pa_xstrdup(port->name);
+ copy->role = port->role;
+ copy->profiles = dm_list_new();
+
+ DM_LIST_FOREACH(i, port->profiles)
+ dm_list_push_back(copy->profiles, config_profile_dup(i->data));
+
+ if (port->port_type == DM_CONFIG_TYPE_DEVICE_PORT) {
+ copy->type = port->type;
+ copy->address = pa_xstrdup(port->address);
+ }
+
+ if (port->port_type == DM_CONFIG_TYPE_MIX_PORT) {
+ copy->flags = port->flags;
+ copy->max_open_count = port->max_open_count;
+ copy->max_active_count = port->max_active_count;
+ }
+
+ return copy;
+}
- config_copy = pa_xnew0(pa_droid_config_audio, 1);
+static dm_config_route *config_route_dup(const dm_config_route *route, dm_list *ports) {
+ dm_config_route *copy = pa_xnew0(dm_config_route, 1);
+ dm_config_port *port_copy, *port;
+ void *state, *state2;
- if (config->global_config)
- config_copy->global_config = pa_xmemdup(config->global_config, sizeof(*config->global_config));
+ copy->type = route->type;
+ copy->sources = dm_list_new();
- SLLIST_FOREACH(module, config->hw_modules) {
- module_copy = pa_droid_config_hw_module_new(config_copy, module->name);
- if (module->global_config)
- module_copy->global_config = pa_xmemdup(module->global_config, sizeof(*module->global_config));
-
- SLLIST_FOREACH(device, module->outputs) {
- device_copy = pa_xmemdup(device, sizeof(*device));
- device_copy->module = module_copy;
- device_copy->name = pa_xstrdup(device->name);
- SLLIST_APPEND(pa_droid_config_device, module_copy->outputs, device_copy);
+ DM_LIST_FOREACH_DATA(port, route->sources, state) {
+ DM_LIST_FOREACH_DATA(port_copy, ports, state2) {
+ if (dm_config_port_equal(port, port_copy)) {
+ dm_list_push_back(copy->sources, port_copy);
+ break;
+ }
}
+ }
- SLLIST_FOREACH(device, module->inputs) {
- device_copy = pa_xmemdup(device, sizeof(*device));
- device_copy->module = module_copy;
- device_copy->name = pa_xstrdup(device->name);
- SLLIST_APPEND(pa_droid_config_device, module_copy->inputs, device_copy);
+ DM_LIST_FOREACH_DATA(port_copy, ports, state) {
+ if (dm_config_port_equal(port_copy, route->sink)) {
+ copy->sink = port_copy;
+ break;
}
+ }
- SLLIST_APPEND(pa_droid_config_hw_module, config_copy->hw_modules, module_copy);
+ return copy;
+}
+
+static dm_config_module *config_module_dup(const dm_config_module *module) {
+ dm_config_module *copy = pa_xnew0(dm_config_module, 1);
+ dm_config_port *device_port, *attached_device, *mix_port;
+ dm_config_route *route;
+ void *state, *state2;
+
+ copy = pa_xnew0(dm_config_module, 1);
+ copy->name = pa_xstrdup(module->name);
+ copy->version_major = module->version_major;
+ copy->version_minor = module->version_minor;
+ copy->attached_devices = dm_list_new();
+ copy->default_output_device = NULL;
+ copy->mix_ports = dm_list_new();
+ copy->device_ports = dm_list_new();
+ copy->ports = dm_list_new();
+ copy->routes = dm_list_new();
+
+ DM_LIST_FOREACH_DATA(device_port, module->device_ports, state) {
+ dm_config_port *device_port_copy = config_port_dup(device_port, copy);
+ dm_list_push_back(copy->device_ports, device_port_copy);
+ dm_list_push_back(copy->ports, device_port_copy);
+ if (module->default_output_device == device_port)
+ copy->default_output_device = device_port_copy;
+ DM_LIST_FOREACH_DATA(attached_device, module->attached_devices, state2) {
+ if (attached_device == device_port) {
+ dm_list_push_back(copy->attached_devices, device_port_copy);
+ break;
+ }
+ }
}
- return config_copy;
+ DM_LIST_FOREACH_DATA(mix_port, module->mix_ports, state) {
+ dm_config_port *mix_port_copy = config_port_dup(mix_port, copy);
+ dm_list_push_back(copy->mix_ports, mix_port_copy);
+ dm_list_push_back(copy->ports, mix_port_copy);
+ }
+
+ DM_LIST_FOREACH_DATA(route, module->routes, state)
+ dm_list_push_back(copy->routes, config_route_dup(route, copy->ports));
+
+ return copy;
}
-pa_droid_config_audio *pa_parse_droid_audio_config(const char *filename) {
- const char *suffix;
+dm_config_device *dm_config_dup(const dm_config_device *config) {
+ dm_config_device *copy;
+ dm_config_module *module;
+ void *state;
- pa_assert(filename);
+ pa_assert(config);
- if ((suffix = rindex(filename, '.'))) {
- if (strlen(suffix) == 4 && pa_streq(suffix, ".xml"))
- return pa_parse_droid_audio_config_xml(filename);
- else if (strlen(suffix) == 5 && pa_streq(suffix, ".conf"))
- return pa_parse_droid_audio_config_legacy(filename);
+ copy = pa_xnew0(dm_config_device, 1);
+ copy->global_config = dm_list_new();
+ copy->modules = dm_list_new();
+
+ if (config->global_config) {
+ dm_config_global *global, *global_copy;
+
+ DM_LIST_FOREACH_DATA(global, config->global_config, state) {
+ global_copy = pa_xnew0(dm_config_global, 1);
+ global_copy->key = pa_xstrdup(global->key);
+ global_copy->value = pa_xstrdup(global->value);
+ dm_list_push_back(copy->global_config, global_copy);
+ }
}
- return NULL;
+ DM_LIST_FOREACH_DATA(module, config->modules, state)
+ dm_list_push_back(copy->modules, config_module_dup(module));
+
+ return copy;
}
-void pa_droid_config_free(pa_droid_config_audio *config) {
- pa_droid_config_hw_module *module;
- pa_droid_config_device *device;
+dm_config_device *pa_parse_droid_audio_config(const char *filename) {
+ return pa_parse_droid_audio_config_xml(filename);
+}
- if (!config)
- return;
+static void config_global_free(void *data) {
+ dm_config_global *global = data;
- while (config->hw_modules) {
- SLLIST_STEAL_FIRST(module, config->hw_modules);
+ pa_xfree(global->key);
+ pa_xfree(global->value);
+ pa_xfree(global);
+}
- while (module->outputs) {
- SLLIST_STEAL_FIRST(device, module->outputs);
- pa_droid_config_device_free(device);
- }
+static void config_profile_free(void *data) {
+ dm_config_profile *profile = data;
- while (module->inputs) {
- SLLIST_STEAL_FIRST(device, module->inputs);
- pa_droid_config_device_free(device);
- }
+ pa_xfree(profile->name);
+ pa_xfree(profile);
+}
- pa_droid_config_hw_module_free(module);
- }
+static void config_port_free(void *data) {
+ dm_config_port *port = data;
- pa_xfree(config->global_config);
+ pa_xfree(port->name);
+ pa_xfree(port->address);
+ dm_list_free(port->profiles, config_profile_free);
+ pa_xfree(port);
+}
+
+static void config_route_free(void *data) {
+ dm_config_route *route = data;
+
+ dm_list_free(route->sources, NULL);
+ pa_xfree(route);
+}
+
+static void config_module_free(void *data) {
+ dm_config_module *module = data;
+
+ pa_xfree(module->name);
+ dm_list_free(module->attached_devices, NULL);
+ dm_list_free(module->ports, config_port_free);
+ dm_list_free(module->device_ports, NULL);
+ dm_list_free(module->mix_ports, NULL);
+ dm_list_free(module->routes, config_route_free);
+ pa_xfree(module);
+}
+
+void dm_config_free(dm_config_device *config) {
+ if (!config)
+ return;
+
+ dm_list_free(config->global_config, config_global_free);
+ dm_list_free(config->modules, config_module_free);
pa_xfree(config);
}
-const pa_droid_config_hw_module *pa_droid_config_find_module(const pa_droid_config_audio *config, const char* module_id) {
- pa_droid_config_hw_module *module;
+dm_config_module *dm_config_find_module(dm_config_device *config, const char* module_id) {
+ dm_config_module *module;
+ void *state;
pa_assert(config);
pa_assert(module_id);
- SLLIST_FOREACH(module, config->hw_modules) {
+ DM_LIST_FOREACH_DATA(module, config->modules, state) {
if (pa_streq(module_id, module->name))
return module;
}
@@ -199,71 +294,73 @@
return NULL;
}
-static const pa_droid_config_device *find_device(const pa_droid_config_hw_module *module, bool output, const char* device_name) {
- pa_droid_config_device *device;
+dm_config_port *dm_config_find_port(dm_config_module *module, const char* name) {
+ dm_config_port *port;
+ void *state;
pa_assert(module);
- pa_assert(device_name);
+ pa_assert(name);
- SLLIST_FOREACH(device, output ? module->outputs : module->inputs) {
- if (pa_streq(device_name, device->name))
- return device;
+ DM_LIST_FOREACH_DATA(port, module->ports, state) {
+ if (pa_streq(name, port->name))
+ return port;
}
return NULL;
}
-const pa_droid_config_device *pa_droid_config_find_output(const pa_droid_config_hw_module *module, const char* output_name) {
- return find_device(module, true, output_name);
-}
+dm_config_port *dm_config_default_output_device(dm_config_module *module) {
+ pa_assert(module);
-const pa_droid_config_device *pa_droid_config_find_input(const pa_droid_config_hw_module *module, const char* input_name) {
- return find_device(module, false, input_name);
+ if (module->default_output_device)
+ return module->default_output_device;
+ else {
+ pa_log("Module %s doesn't have default output device.", module->name);
+ return 0;
+ }
}
-pa_droid_config_hw_module *pa_droid_config_hw_module_new(const pa_droid_config_audio *config, const char *name) {
- pa_droid_config_hw_module *hw_module;
+char *dm_config_escape_string(const char *string) {
+ if (!string)
+ return NULL;
- pa_assert(config);
- pa_assert(name);
+ /* Just replace whitespace with underscores for now. */
- hw_module = pa_xnew0(pa_droid_config_hw_module, 1);
- hw_module->config = config;
- hw_module->name = pa_xstrndup(name, AUDIO_HARDWARE_MODULE_ID_MAX_LEN);
-
- return hw_module;
+ return pa_replace(string, " ", "_");
}
-void pa_droid_config_hw_module_free(pa_droid_config_hw_module *hw_module) {
- if (!hw_module)
- return;
+dm_config_port *dm_config_find_device_port(dm_config_port *port, audio_devices_t device) {
+ dm_config_port *device_port;
+ void *state;
- pa_xfree(hw_module->name);
- pa_xfree(hw_module->global_config);
- pa_xfree(hw_module);
-}
+ pa_assert(port);
-pa_droid_config_device *pa_droid_config_device_new(const pa_droid_config_hw_module *module,
- pa_direction_t direction,
- const char *name) {
- pa_droid_config_device *device;
+ DM_LIST_FOREACH_DATA(device_port, port->module->device_ports, state) {
+ if (device_port->type == device)
+ return device_port;
+ }
- pa_assert(module);
- pa_assert(direction == PA_DIRECTION_OUTPUT || direction == PA_DIRECTION_INPUT);
- pa_assert(name);
+ return NULL;
+}
- device = pa_xnew0(pa_droid_config_device, 1);
- device->module = module;
- device->direction = direction;
- device->name = pa_replace(name, " ", "_");
+bool dm_config_port_equal(const dm_config_port *a, const dm_config_port *b) {
+ if ((!a && b) || (a && !b))
+ return false;
- return device;
+ else if (!a && !b)
+ return true;
+
+ return (pa_streq(a->name, b->name) && a->type == b->type);
}
-void pa_droid_config_device_free(pa_droid_config_device *device) {
- if (!device)
- return;
+dm_config_port *dm_config_find_mix_port(dm_config_module *module, const char *name) {
+ dm_config_port *mix_port = NULL;
+ void *state;
- pa_xfree(device->name);
- pa_xfree(device);
+ DM_LIST_FOREACH_DATA(mix_port, module->mix_ports, state) {
+ if (pa_streq(mix_port->name, name))
+ return mix_port;
+ }
+
+ return NULL;
}
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-14.2.100.tar.bz2/src/common/droid-util-audio.h
^
|
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Jolla Ltd.
+ * Copyright (C) 2017-2022 Jolla Ltd.
*
* Contact: Juho Hämäläinen <juho.hamalainen@jolla.com>
*
@@ -28,7 +28,6 @@
#endif
#include <hardware/audio.h>
-#include <hardware_legacy/audio_policy_conf.h>
#include <pulse/channelmap.h>
@@ -91,9 +90,7 @@
{ PA_SAMPLE_U8, AUDIO_FORMAT_PCM_8_BIT },
{ PA_SAMPLE_S16LE, AUDIO_FORMAT_PCM_16_BIT },
{ PA_SAMPLE_S32LE, AUDIO_FORMAT_PCM_32_BIT },
-#if HAVE_ENUM_AUDIO_FORMAT_PCM_24_BIT_PACKED
{ PA_SAMPLE_S24LE, AUDIO_FORMAT_PCM_24_BIT_PACKED }
-#endif
};
uint32_t conversion_table_default_audio_source[][2] = {
@@ -104,18 +101,33 @@
{ AUDIO_DEVICE_IN_WIRED_HEADSET, AUDIO_SOURCE_MIC },
{ AUDIO_DEVICE_IN_AUX_DIGITAL, AUDIO_SOURCE_MIC },
{ AUDIO_DEVICE_IN_VOICE_CALL, AUDIO_SOURCE_VOICE_CALL },
+ { AUDIO_DEVICE_IN_TELEPHONY_RX, AUDIO_SOURCE_VOICE_CALL },
{ AUDIO_DEVICE_IN_BACK_MIC, AUDIO_SOURCE_MIC },
{ AUDIO_DEVICE_IN_REMOTE_SUBMIX, AUDIO_SOURCE_REMOTE_SUBMIX },
+ { AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET, AUDIO_SOURCE_MIC },
+ { AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET, AUDIO_SOURCE_MIC },
+ { AUDIO_DEVICE_IN_USB_ACCESSORY, AUDIO_SOURCE_MIC },
+ { AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_SOURCE_MIC },
+ { AUDIO_DEVICE_IN_FM_TUNER, AUDIO_SOURCE_FM_TUNER },
+ { AUDIO_DEVICE_IN_TV_TUNER, AUDIO_SOURCE_MIC },
+ { AUDIO_DEVICE_IN_LINE, AUDIO_SOURCE_MIC },
+ { AUDIO_DEVICE_IN_SPDIF, AUDIO_SOURCE_MIC },
+ { AUDIO_DEVICE_IN_BLUETOOTH_A2DP, AUDIO_SOURCE_MIC },
+ { AUDIO_DEVICE_IN_LOOPBACK, AUDIO_SOURCE_MIC },
+ { AUDIO_DEVICE_IN_IP, AUDIO_SOURCE_MIC },
+ { AUDIO_DEVICE_IN_BUS, AUDIO_SOURCE_MIC },
+ { AUDIO_DEVICE_IN_PROXY, AUDIO_SOURCE_MIC },
+ { AUDIO_DEVICE_IN_USB_HEADSET, AUDIO_SOURCE_MIC },
+ { AUDIO_DEVICE_IN_BLUETOOTH_BLE, AUDIO_SOURCE_MIC },
+ { AUDIO_DEVICE_IN_HDMI_ARC, AUDIO_SOURCE_MIC },
+ { AUDIO_DEVICE_IN_ECHO_REFERENCE, AUDIO_SOURCE_MIC },
+
#if defined(HAVE_ENUM_AUDIO_DEVICE_IN_FM_RX) && defined(HAVE_ENUM_AUDIO_SOURCE_FM_RX)
{ AUDIO_DEVICE_IN_FM_RX, AUDIO_SOURCE_FM_RX },
#endif
-#if defined(HAVE_ENUM_AUDIO_DEVICE_IN_FM_TUNER) && defined(HAVE_ENUM_AUDIO_SOURCE_FM_TUNER)
- { AUDIO_DEVICE_IN_FM_TUNER, AUDIO_SOURCE_FM_TUNER },
-#endif
#if defined(HAVE_ENUM_AUDIO_DEVICE_IN_FM_RX_A2DP) && defined(HAVE_ENUM_AUDIO_SOURCE_FM_RX_A2DP)
{ AUDIO_DEVICE_IN_FM_RX_A2DP, AUDIO_SOURCE_FM_RX_A2DP },
#endif
- { AUDIO_DEVICE_IN_ALL, AUDIO_SOURCE_DEFAULT }
};
/* Output devices */
@@ -138,30 +150,30 @@
STRING_ENTRY( AUDIO_DEVICE_OUT_USB_ACCESSORY ),
STRING_ENTRY( AUDIO_DEVICE_OUT_USB_DEVICE ),
STRING_ENTRY( AUDIO_DEVICE_OUT_REMOTE_SUBMIX ),
+ STRING_ENTRY( AUDIO_DEVICE_OUT_TELEPHONY_TX ),
+ STRING_ENTRY( AUDIO_DEVICE_OUT_LINE ),
+ STRING_ENTRY( AUDIO_DEVICE_OUT_HDMI_ARC ),
+ STRING_ENTRY( AUDIO_DEVICE_OUT_SPDIF ),
+ STRING_ENTRY( AUDIO_DEVICE_OUT_FM ),
+ STRING_ENTRY( AUDIO_DEVICE_OUT_AUX_LINE ),
+ STRING_ENTRY( AUDIO_DEVICE_OUT_SPEAKER_SAFE ),
+ STRING_ENTRY( AUDIO_DEVICE_OUT_IP ),
+ STRING_ENTRY( AUDIO_DEVICE_OUT_BUS ),
+ STRING_ENTRY( AUDIO_DEVICE_OUT_PROXY ),
+ STRING_ENTRY( AUDIO_DEVICE_OUT_USB_HEADSET ),
+ STRING_ENTRY( AUDIO_DEVICE_OUT_HEARING_AID ),
+ STRING_ENTRY( AUDIO_DEVICE_OUT_ECHO_CANCELLER ),
STRING_ENTRY( AUDIO_DEVICE_OUT_DEFAULT ),
- /* Devices which may or may not be defined for all devices,
- * update meson.build check_enums list if you encounter new ones. */
- STRING_ENTRY_IF_AUDIO_DEVICE_OUT_HDMI
- STRING_ENTRY_IF_AUDIO_DEVICE_OUT_HDMI_ARC
- STRING_ENTRY_IF_AUDIO_DEVICE_OUT_TELEPHONY_TX
- STRING_ENTRY_IF_AUDIO_DEVICE_OUT_LINE
- STRING_ENTRY_IF_AUDIO_DEVICE_OUT_SPDIF
- STRING_ENTRY_IF_AUDIO_DEVICE_OUT_AUX_LINE
- STRING_ENTRY_IF_AUDIO_DEVICE_OUT_SPEAKER_SAFE
- STRING_ENTRY_IF_AUDIO_DEVICE_OUT_FM
- STRING_ENTRY_IF_AUDIO_DEVICE_OUT_FM_TX
- STRING_ENTRY_IF_AUDIO_DEVICE_OUT_ANC_HEADSET
- STRING_ENTRY_IF_AUDIO_DEVICE_OUT_ANC_HEADPHONE
- STRING_ENTRY_IF_AUDIO_DEVICE_OUT_PROXY
- STRING_ENTRY_IF_AUDIO_DEVICE_OUT_IP
-
- /* Combination entries consisting of multiple devices defined above.
- * These don't require counterpart in string_conversion_table_output_device_fancy. */
- STRING_ENTRY( AUDIO_DEVICE_OUT_ALL ),
- STRING_ENTRY( AUDIO_DEVICE_OUT_ALL_A2DP ),
- STRING_ENTRY( AUDIO_DEVICE_OUT_ALL_SCO ),
- STRING_ENTRY( AUDIO_DEVICE_OUT_ALL_USB ),
+ { 0, NULL }
+};
+
+struct string_conversion string_conversion_table_audio_mode_fancy[] = {
+ { AUDIO_MODE_NORMAL, "normal" },
+ { AUDIO_MODE_RINGTONE, "ringtone" },
+ { AUDIO_MODE_IN_CALL, "in call" },
+ { AUDIO_MODE_IN_COMMUNICATION, "in communication" },
+ { AUDIO_MODE_CALL_SCREEN, "call screen" },
{ 0, NULL }
};
@@ -169,8 +181,6 @@
struct string_conversion string_conversion_table_output_device_fancy[] = {
{ AUDIO_DEVICE_OUT_EARPIECE, "output-earpiece" },
{ AUDIO_DEVICE_OUT_SPEAKER, "output-speaker" },
- { AUDIO_DEVICE_OUT_SPEAKER
- | AUDIO_DEVICE_OUT_WIRED_HEADPHONE, "output-speaker+wired_headphone" },
{ AUDIO_DEVICE_OUT_WIRED_HEADSET, "output-wired_headset" },
{ AUDIO_DEVICE_OUT_WIRED_HEADPHONE, "output-wired_headphone" },
{ AUDIO_DEVICE_OUT_BLUETOOTH_SCO, "output-bluetooth_sco" },
@@ -185,23 +195,21 @@
{ AUDIO_DEVICE_OUT_USB_ACCESSORY, "output-usb_accessory" },
{ AUDIO_DEVICE_OUT_USB_DEVICE, "output-usb_device" },
{ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "output-remote_submix" },
+ { AUDIO_DEVICE_OUT_TELEPHONY_TX, "output-telephony_tx" },
+ { AUDIO_DEVICE_OUT_LINE, "output-line" },
+ { AUDIO_DEVICE_OUT_HDMI_ARC, "output-hdmi_arc" },
+ { AUDIO_DEVICE_OUT_SPDIF, "output-spdif" },
+ { AUDIO_DEVICE_OUT_FM, "output-fm" },
+ { AUDIO_DEVICE_OUT_AUX_LINE, "output-aux_line" },
+ { AUDIO_DEVICE_OUT_SPEAKER_SAFE, "output-speaker_safe" },
+ { AUDIO_DEVICE_OUT_IP, "output-ip" },
+ { AUDIO_DEVICE_OUT_BUS, "output-bus" },
+ { AUDIO_DEVICE_OUT_PROXY, "output-proxy" },
+ { AUDIO_DEVICE_OUT_USB_HEADSET, "output-usb_headset" },
+ { AUDIO_DEVICE_OUT_HEARING_AID, "output-hearing_aid" },
+ { AUDIO_DEVICE_OUT_ECHO_CANCELLER, "output-echo_canceller" },
{ AUDIO_DEVICE_OUT_DEFAULT, "output-default" },
- /* Devices which may or may not be defined for all devices, */
- FANCY_ENTRY_IF_AUDIO_DEVICE_OUT_HDMI ( "output-hdmi" )
- FANCY_ENTRY_IF_AUDIO_DEVICE_OUT_HDMI_ARC ( "output-hdmi_arc" )
- FANCY_ENTRY_IF_AUDIO_DEVICE_OUT_TELEPHONY_TX ( "output-telephony_tx" )
- FANCY_ENTRY_IF_AUDIO_DEVICE_OUT_LINE ( "output-line" )
- FANCY_ENTRY_IF_AUDIO_DEVICE_OUT_SPDIF ( "output-spdif" )
- FANCY_ENTRY_IF_AUDIO_DEVICE_OUT_AUX_LINE ( "output-aux_line" )
- FANCY_ENTRY_IF_AUDIO_DEVICE_OUT_SPEAKER_SAFE ( "output-speaker_safe" )
- FANCY_ENTRY_IF_AUDIO_DEVICE_OUT_FM ( "output-fm" )
- FANCY_ENTRY_IF_AUDIO_DEVICE_OUT_FM_TX ( "output-fm_tx" )
- FANCY_ENTRY_IF_AUDIO_DEVICE_OUT_ANC_HEADSET ( "output-and_headset" )
- FANCY_ENTRY_IF_AUDIO_DEVICE_OUT_ANC_HEADPHONE ( "output-anc_headphone" )
- FANCY_ENTRY_IF_AUDIO_DEVICE_OUT_PROXY ( "output-proxy" )
- FANCY_ENTRY_IF_AUDIO_DEVICE_OUT_IP ( "output-ip" )
-
{ 0, NULL }
};
@@ -215,39 +223,33 @@
STRING_ENTRY( AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET ),
STRING_ENTRY( AUDIO_DEVICE_IN_WIRED_HEADSET ),
STRING_ENTRY( AUDIO_DEVICE_IN_AUX_DIGITAL ),
+ STRING_ENTRY( AUDIO_DEVICE_IN_HDMI ), /* Same as AUDIO_DEVICE_IN_AUX_DIGITAL */
STRING_ENTRY( AUDIO_DEVICE_IN_VOICE_CALL ),
+ STRING_ENTRY( AUDIO_DEVICE_IN_TELEPHONY_RX ), /* Same as AUDIO_DEVICE_IN_VOICE_CALL */
STRING_ENTRY( AUDIO_DEVICE_IN_BACK_MIC ),
STRING_ENTRY( AUDIO_DEVICE_IN_REMOTE_SUBMIX ),
STRING_ENTRY( AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET ),
STRING_ENTRY( AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET ),
STRING_ENTRY( AUDIO_DEVICE_IN_USB_ACCESSORY ),
STRING_ENTRY( AUDIO_DEVICE_IN_USB_DEVICE ),
+ STRING_ENTRY( AUDIO_DEVICE_IN_FM_TUNER ),
+ STRING_ENTRY( AUDIO_DEVICE_IN_TV_TUNER ),
+ STRING_ENTRY( AUDIO_DEVICE_IN_LINE ),
+ STRING_ENTRY( AUDIO_DEVICE_IN_SPDIF ),
+ STRING_ENTRY( AUDIO_DEVICE_IN_BLUETOOTH_A2DP ),
+ STRING_ENTRY( AUDIO_DEVICE_IN_LOOPBACK ),
+ STRING_ENTRY( AUDIO_DEVICE_IN_IP ),
+ STRING_ENTRY( AUDIO_DEVICE_IN_BUS ),
+ STRING_ENTRY( AUDIO_DEVICE_IN_PROXY ),
+ STRING_ENTRY( AUDIO_DEVICE_IN_USB_HEADSET ),
+ STRING_ENTRY( AUDIO_DEVICE_IN_BLUETOOTH_BLE ),
+ STRING_ENTRY( AUDIO_DEVICE_IN_HDMI_ARC ),
+ STRING_ENTRY( AUDIO_DEVICE_IN_ECHO_REFERENCE ),
STRING_ENTRY( AUDIO_DEVICE_IN_DEFAULT ),
- /* Devices which may or may not be defined for all devices,
- * update meson.build check_enums list if you encounter new ones. */
- STRING_ENTRY_IF_AUDIO_DEVICE_IN_HDMI
- STRING_ENTRY_IF_AUDIO_DEVICE_IN_TELEPHONY_RX
- STRING_ENTRY_IF_AUDIO_DEVICE_IN_FM_TUNER
- STRING_ENTRY_IF_AUDIO_DEVICE_IN_TV_TUNER
- STRING_ENTRY_IF_AUDIO_DEVICE_IN_LINE
- STRING_ENTRY_IF_AUDIO_DEVICE_IN_SPDIF
- STRING_ENTRY_IF_AUDIO_DEVICE_IN_BLUETOOTH_A2DP
- STRING_ENTRY_IF_AUDIO_DEVICE_IN_LOOPBACK
- STRING_ENTRY_IF_AUDIO_DEVICE_IN_PROXY
+ /* Devices which may or may not be defined for all devices. */
STRING_ENTRY_IF_AUDIO_DEVICE_IN_FM_RX
STRING_ENTRY_IF_AUDIO_DEVICE_IN_FM_RX_A2DP
- STRING_ENTRY_IF_AUDIO_DEVICE_IN_IP
-
-#ifdef DROID_AUDIO_HAL_SECONDARY_MIC
- STRING_ENTRY( AUDIO_DEVICE_IN_SECONDARY_MIC ),
-#endif
-
- /* Combination entries consisting of multiple devices defined above.
- * These don't require counterpart in string_conversion_table_input_device_fancy. */
- STRING_ENTRY( AUDIO_DEVICE_IN_ALL ),
- STRING_ENTRY( AUDIO_DEVICE_IN_ALL_SCO ),
- STRING_ENTRY_IF_AUDIO_DEVICE_IN_ALL_USB
{ 0, NULL }
};
@@ -260,31 +262,31 @@
{ AUDIO_DEVICE_IN_WIRED_HEADSET, "input-wired_headset" },
{ AUDIO_DEVICE_IN_AUX_DIGITAL, "input-aux_digital" },
{ AUDIO_DEVICE_IN_VOICE_CALL, "input-voice_call" },
+ { AUDIO_DEVICE_IN_TELEPHONY_RX, "input-telephony_rx", },
{ AUDIO_DEVICE_IN_BACK_MIC, "input-back_mic" },
{ AUDIO_DEVICE_IN_REMOTE_SUBMIX, "input-remote_submix" },
{ AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET, "input-analog_dock_headset" },
{ AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET, "input-digital_dock_headset" },
{ AUDIO_DEVICE_IN_USB_ACCESSORY, "input-usb_accessory" },
{ AUDIO_DEVICE_IN_USB_DEVICE, "input-usb_device" },
+ { AUDIO_DEVICE_IN_FM_TUNER, "input-fm_tuner" },
+ { AUDIO_DEVICE_IN_TV_TUNER, "input-tv_tuner" },
+ { AUDIO_DEVICE_IN_LINE, "input-line" },
+ { AUDIO_DEVICE_IN_SPDIF, "input-spdif" },
+ { AUDIO_DEVICE_IN_BLUETOOTH_A2DP, "input-bluetooth_a2dp" },
+ { AUDIO_DEVICE_IN_LOOPBACK, "input-loopback" },
+ { AUDIO_DEVICE_IN_IP, "input-ip" },
+ { AUDIO_DEVICE_IN_BUS, "input-bus" },
+ { AUDIO_DEVICE_IN_PROXY, "input-proxy" },
+ { AUDIO_DEVICE_IN_USB_HEADSET, "input-usb_headset" },
+ { AUDIO_DEVICE_IN_BLUETOOTH_BLE, "input-bluetooth_ble" },
+ { AUDIO_DEVICE_IN_HDMI_ARC, "input-hdmi_arc" },
+ { AUDIO_DEVICE_IN_ECHO_REFERENCE, "input-echo_reference" },
{ AUDIO_DEVICE_IN_DEFAULT, "input-default" },
- /* Devices which may or may not be defined for all devices, */
- FANCY_ENTRY_IF_AUDIO_DEVICE_IN_HDMI ( "input-hdmi" )
- FANCY_ENTRY_IF_AUDIO_DEVICE_IN_TELEPHONY_RX ( "input-telephony_rx" )
- FANCY_ENTRY_IF_AUDIO_DEVICE_IN_FM_TUNER ( "input-fm_tuner" )
- FANCY_ENTRY_IF_AUDIO_DEVICE_IN_TV_TUNER ( "input-tv_tuner" )
- FANCY_ENTRY_IF_AUDIO_DEVICE_IN_LINE ( "input-line" )
- FANCY_ENTRY_IF_AUDIO_DEVICE_IN_SPDIF ( "input-spdif" )
- FANCY_ENTRY_IF_AUDIO_DEVICE_IN_BLUETOOTH_A2DP ( "input-bluetooth_a2dp" )
- FANCY_ENTRY_IF_AUDIO_DEVICE_IN_LOOPBACK ( "input-loopback" )
- FANCY_ENTRY_IF_AUDIO_DEVICE_IN_PROXY ( "input-proxy" )
+ /* Devices which may or may not be defined for all devices. */
FANCY_ENTRY_IF_AUDIO_DEVICE_IN_FM_RX ( "input-fm_rx" )
FANCY_ENTRY_IF_AUDIO_DEVICE_IN_FM_RX_A2DP ( "input-fm_rx_a2dp" )
- FANCY_ENTRY_IF_AUDIO_DEVICE_IN_IP ( "input-ip" )
-
-#ifdef DROID_AUDIO_HAL_SECONDARY_MIC
- { AUDIO_DEVICE_IN_SECONDARY_MIC, "input-secondary_mic" },
-#endif
{ 0, NULL }
};
@@ -300,8 +302,11 @@
{ AUDIO_SOURCE_VOICE_RECOGNITION, "voice recognition" },
{ AUDIO_SOURCE_VOICE_COMMUNICATION, "voice communication" },
{ AUDIO_SOURCE_REMOTE_SUBMIX, "remote submix" },
+ { AUDIO_SOURCE_UNPROCESSED, "unprocessed" },
+ { AUDIO_SOURCE_VOICE_PERFORMANCE, "voice performance" },
- /* Audio sources which may or may not be defined for all devices, */
+ /* Audio sources which may or may not be defined for all devices. */
+ FANCY_ENTRY_IF_AUDIO_SOURCE_ECHO_REFERENCE ( "echo reference" )
FANCY_ENTRY_IF_AUDIO_SOURCE_FM_TUNER ( "fm tuner" )
FANCY_ENTRY_IF_AUDIO_SOURCE_FM_RX ( "fm rx" )
FANCY_ENTRY_IF_AUDIO_SOURCE_FM_RX_A2DP ( "fm rx a2dp" )
@@ -316,33 +321,34 @@
STRING_ENTRY( AUDIO_OUTPUT_FLAG_PRIMARY ),
STRING_ENTRY( AUDIO_OUTPUT_FLAG_FAST ),
STRING_ENTRY( AUDIO_OUTPUT_FLAG_DEEP_BUFFER ),
+ STRING_ENTRY( AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD ),
+ STRING_ENTRY( AUDIO_OUTPUT_FLAG_NON_BLOCKING ),
+ STRING_ENTRY( AUDIO_OUTPUT_FLAG_HW_AV_SYNC ),
+ STRING_ENTRY( AUDIO_OUTPUT_FLAG_TTS ),
+ STRING_ENTRY( AUDIO_OUTPUT_FLAG_RAW ),
+ STRING_ENTRY( AUDIO_OUTPUT_FLAG_SYNC ),
+ STRING_ENTRY( AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO ),
+ STRING_ENTRY( AUDIO_OUTPUT_FLAG_DIRECT_PCM ),
+ STRING_ENTRY( AUDIO_OUTPUT_FLAG_MMAP_NOIRQ ),
+ STRING_ENTRY( AUDIO_OUTPUT_FLAG_VOIP_RX ),
+ STRING_ENTRY( AUDIO_OUTPUT_FLAG_INCALL_MUSIC ),
- /* Audio output flags which may or may not be defined for all devices,
- * update meson.build check_enums list if you encounter new ones. */
- STRING_ENTRY_IF_AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD
- STRING_ENTRY_IF_AUDIO_OUTPUT_FLAG_NON_BLOCKING
- STRING_ENTRY_IF_AUDIO_OUTPUT_FLAG_HW_AV_SYNC
- STRING_ENTRY_IF_AUDIO_OUTPUT_FLAG_VOIP_RX
- STRING_ENTRY_IF_AUDIO_OUTPUT_FLAG_INCALL_MUSIC
+ /* Audio output flags which may or may not be defined for all devices. */
STRING_ENTRY_IF_AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH
- STRING_ENTRY_IF_AUDIO_OUTPUT_FLAG_TTS
- STRING_ENTRY_IF_AUDIO_OUTPUT_FLAG_RAW
- STRING_ENTRY_IF_AUDIO_OUTPUT_FLAG_SYNC
- STRING_ENTRY_IF_AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO
{ 0, NULL }
};
struct string_conversion string_conversion_table_input_flag[] = {
- /* Audio output flags which may or may not be defined for all devices,
- * update meson.build check_enums list if you encounter new ones. */
- STRING_ENTRY_IF_AUDIO_INPUT_FLAG_NONE
- STRING_ENTRY_IF_AUDIO_INPUT_FLAG_FAST
- STRING_ENTRY_IF_AUDIO_INPUT_FLAG_HW_HOTWORD
- STRING_ENTRY_IF_AUDIO_INPUT_FLAG_RAW
- STRING_ENTRY_IF_AUDIO_INPUT_FLAG_SYNC
- STRING_ENTRY_IF_AUDIO_INPUT_FLAG_MMAP_NOIRQ
- STRING_ENTRY_IF_AUDIO_INPUT_FLAG_VOIP_TX
+ STRING_ENTRY( AUDIO_INPUT_FLAG_NONE ),
+ STRING_ENTRY( AUDIO_INPUT_FLAG_FAST ),
+ STRING_ENTRY( AUDIO_INPUT_FLAG_HW_HOTWORD ),
+ STRING_ENTRY( AUDIO_INPUT_FLAG_RAW ),
+ STRING_ENTRY( AUDIO_INPUT_FLAG_SYNC ),
+ STRING_ENTRY( AUDIO_INPUT_FLAG_MMAP_NOIRQ ),
+ STRING_ENTRY( AUDIO_INPUT_FLAG_VOIP_TX ),
+ STRING_ENTRY( AUDIO_INPUT_FLAG_HW_AV_SYNC ),
+ STRING_ENTRY( AUDIO_INPUT_FLAG_DIRECT ),
{ 0, NULL }
};
@@ -371,13 +377,6 @@
STRING_ENTRY( AUDIO_CHANNEL_OUT_STEREO ),
STRING_ENTRY( AUDIO_CHANNEL_OUT_QUAD ),
- STRING_ENTRY_IF_AUDIO_CHANNEL_OUT_SURROUND
- STRING_ENTRY( AUDIO_CHANNEL_OUT_5POINT1 ),
- STRING_ENTRY_IF_AUDIO_CHANNEL_OUT_5POINT1_BACK
- STRING_ENTRY_IF_AUDIO_CHANNEL_OUT_5POINT1_SIDE
- STRING_ENTRY(AUDIO_CHANNEL_OUT_7POINT1 ),
- STRING_ENTRY(AUDIO_CHANNEL_OUT_ALL ),
-
{ 0, NULL }
};
@@ -399,7 +398,6 @@
STRING_ENTRY( AUDIO_CHANNEL_IN_MONO ),
STRING_ENTRY( AUDIO_CHANNEL_IN_STEREO ),
STRING_ENTRY( AUDIO_CHANNEL_IN_FRONT_BACK ),
- STRING_ENTRY( AUDIO_CHANNEL_IN_ALL ),
STRING_ENTRY_IF_AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO
STRING_ENTRY_IF_AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO
STRING_ENTRY_IF_AUDIO_CHANNEL_IN_VOICE_CALL_MONO
@@ -411,27 +409,22 @@
struct string_conversion string_conversion_table_format[] = {
/* Omit most formats as we aren't usually interested in
* other than the pcm formats anyway. */
+ STRING_ENTRY( AUDIO_FORMAT_INVALID ),
STRING_ENTRY( AUDIO_FORMAT_DEFAULT ),
STRING_ENTRY( AUDIO_FORMAT_PCM ),
- STRING_ENTRY( AUDIO_FORMAT_MP3 ),
STRING_ENTRY( AUDIO_FORMAT_AMR_NB ),
STRING_ENTRY( AUDIO_FORMAT_AMR_WB ),
- STRING_ENTRY( AUDIO_FORMAT_AAC ),
- STRING_ENTRY( AUDIO_FORMAT_HE_AAC_V1 ),
- STRING_ENTRY( AUDIO_FORMAT_HE_AAC_V2 ),
+ STRING_ENTRY( AUDIO_FORMAT_FLAC ),
+ STRING_ENTRY( AUDIO_FORMAT_MP3 ),
+ STRING_ENTRY( AUDIO_FORMAT_OPUS ),
+ STRING_ENTRY( AUDIO_FORMAT_SBC ),
STRING_ENTRY( AUDIO_FORMAT_VORBIS ),
STRING_ENTRY( AUDIO_FORMAT_PCM_16_BIT ),
STRING_ENTRY( AUDIO_FORMAT_PCM_8_BIT ),
STRING_ENTRY( AUDIO_FORMAT_PCM_32_BIT ),
STRING_ENTRY( AUDIO_FORMAT_PCM_8_24_BIT ),
-
- /* Audio formats which may or may not be defined for all devices,
- * update meson.build check_enums list if you encounter new ones. */
- STRING_ENTRY_IF_AUDIO_FORMAT_PCM_24_BIT_PACKED
- STRING_ENTRY_IF_AUDIO_FORMAT_PCM_OFFLOAD
- STRING_ENTRY_IF_AUDIO_FORMAT_FLAC
- STRING_ENTRY_IF_AUDIO_FORMAT_OPUS
+ STRING_ENTRY( AUDIO_FORMAT_PCM_24_BIT_PACKED ),
{ 0, NULL }
};
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-14.2.100.tar.bz2/src/common/droid-util.c
^
|
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2018 Jolla Ltd.
+ * Copyright (C) 2013-2022 Jolla Ltd.
*
* Contact: Juho Hämäläinen <juho.hamalainen@jolla.com>
*
@@ -31,6 +31,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <grp.h>
+#include <stdarg.h>
#ifdef HAVE_VALGRIND_MEMCHECK_H
#include <valgrind/memcheck.h>
@@ -70,38 +71,43 @@
#include "droid/droid-config.h"
#include "droid/conversion.h"
#include "droid/sllist.h"
+#include "droid/utils.h"
-struct droid_quirk {
+struct droid_option {
const char *name;
uint32_t value;
};
-struct droid_quirk valid_quirks[] = {
- { "input_atoi", QUIRK_INPUT_ATOI },
- { "set_parameters", QUIRK_SET_PARAMETERS },
- { "close_input", QUIRK_CLOSE_INPUT },
- { "unload_no_close", QUIRK_UNLOAD_NO_CLOSE },
- { "no_hw_volume", QUIRK_NO_HW_VOLUME },
- { "output_make_writable", QUIRK_OUTPUT_MAKE_WRITABLE },
- { "realcall", QUIRK_REALCALL },
- { "unload_call_exit", QUIRK_UNLOAD_CALL_EXIT },
- { "output_fast", QUIRK_OUTPUT_FAST },
- { "output_deep_buffer", QUIRK_OUTPUT_DEEP_BUFFER },
- { "audio_cal_wait", QUIRK_AUDIO_CAL_WAIT },
- { "standby_set_route", QUIRK_STANDBY_SET_ROUTE },
- { "speaker_before_voice", QUIRK_SPEAKER_BEFORE_VOICE },
- { "swap_headphone_speaker", QUIRK_SWAP_HEADPHONE_SPEAKER },
- { "output_remix_to_mono", QUIRK_OUTPUT_REMIX_TO_MONO },
+struct droid_option valid_options[] = {
+ { "input_atoi", DM_OPTION_INPUT_ATOI },
+ { "close_input", DM_OPTION_CLOSE_INPUT },
+ { "unload_no_close", DM_OPTION_UNLOAD_NO_CLOSE },
+ { "hw_volume", DM_OPTION_HW_VOLUME },
+ { "realcall", DM_OPTION_REALCALL },
+ { "unload_call_exit", DM_OPTION_UNLOAD_CALL_EXIT },
+ { "output_fast", DM_OPTION_OUTPUT_FAST },
+ { "output_deep_buffer", DM_OPTION_OUTPUT_DEEP_BUFFER },
+ { "audio_cal_wait", DM_OPTION_AUDIO_CAL_WAIT },
+ { "speaker_before_voice", DM_OPTION_SPEAKER_BEFORE_VOICE },
+ { "output_voip_rx", DM_OPTION_OUTPUT_VOIP_RX },
+ { "record_voice_16k", DM_OPTION_RECORD_VOICE_16K },
};
-#define QUIRK_AUDIO_CAL_WAIT_S (10)
-#define QUIRK_AUDIO_CAL_FILE "/data/vendor/audio/cirrus_sony.cal"
-#define QUIRK_AUDIO_CAL_GROUP "audio"
-#define QUIRK_AUDIO_CAL_MODE (0664)
-
-#define DEFAULT_PRIORITY (100)
-#define DEFAULT_AUDIO_FORMAT (AUDIO_FORMAT_PCM_16_BIT)
+struct user_options {
+ struct user_option {
+ bool enable;
+ bool set;
+ } options[DM_OPTION_COUNT];
+};
+#define DM_OPTION_AUDIO_CAL_WAIT_S (10)
+#define DM_OPTION_AUDIO_CAL_FILE "/data/vendor/audio/cirrus_sony.cal"
+#define DM_OPTION_AUDIO_CAL_GROUP "audio"
+#define DM_OPTION_AUDIO_CAL_MODE (0664)
+
+#define DEFAULT_PRIORITY (100)
+#define DEFAULT_AUDIO_FORMAT (AUDIO_FORMAT_PCM_16_BIT)
+#define DROID_VOIP_RX_SAMPLE_RATE (16000)
#ifndef AUDIO_PARAMETER_VALUE_ON
#define AUDIO_PARAMETER_VALUE_ON "on"
@@ -120,14 +126,15 @@
static void droid_port_free(pa_droid_port *p);
-static int input_stream_set_route(pa_droid_hw_module *hw_module, pa_droid_stream *s);
+static int input_stream_set_route(pa_droid_stream *stream, const dm_config_port *device_port);
static int droid_set_parameters(pa_droid_hw_module *hw, const char *parameters);
-static bool droid_set_audio_source(pa_droid_hw_module *hw_module, audio_source_t audio_source);
-
-static pa_droid_hw_module *hw_primary = NULL;
+static bool droid_set_audio_source(pa_droid_stream *stream, audio_source_t audio_source);
+static void add_output_ports(pa_droid_mapping *droid_mapping, dm_config_port *device_port);
+static void add_input_ports(pa_droid_mapping *droid_mapping, dm_config_port *device_port);
+static void audio_patch_release(pa_droid_stream *stream);
static pa_droid_profile *profile_new(pa_droid_profile_set *ps,
- const pa_droid_config_hw_module *module,
+ dm_config_module *module,
const char *name,
const char *description) {
pa_droid_profile *p;
@@ -145,82 +152,14 @@
p->priority = DEFAULT_PRIORITY;
p->output_mappings = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+ p->input_mappings = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
pa_hashmap_put(ps->profiles, p->name, p);
return p;
}
-static pa_droid_profile *droid_profile_new(pa_droid_profile_set *ps,
- const pa_droid_config_device *primary_output,
- const pa_droid_config_device *output,
- const pa_droid_config_device *inputs) {
- pa_droid_profile *p;
- char *name;
- char *description;
-
- pa_assert(ps);
- pa_assert(output);
- pa_assert(!primary_output || primary_output->direction == PA_DIRECTION_OUTPUT);
- pa_assert(!inputs || inputs->direction == PA_DIRECTION_INPUT);
-
- name = pa_sprintf_malloc("%s%s%s", output->name, inputs ? "-" : "", inputs ? inputs->name : "");
- description = pa_sprintf_malloc("%s output%s%s%s", output->name,
- inputs ? " and " : "",
- inputs ? inputs->name : "",
- inputs ? " inputs." : "");
-
- p = profile_new(ps, output->module, name, description);
- pa_xfree(name);
- pa_xfree(description);
-
- if (pa_streq(output->name, "primary")) {
- p->priority += DEFAULT_PRIORITY;
-
- if (inputs && pa_streq(inputs->name, "primary"))
- p->priority += DEFAULT_PRIORITY;
- }
-
- if (primary_output && primary_output != output)
- pa_idxset_put(p->output_mappings, pa_droid_mapping_get(ps, primary_output), NULL);
- if (output)
- pa_idxset_put(p->output_mappings, pa_droid_mapping_get(ps, output), NULL);
- if (inputs)
- p->input_mapping = pa_droid_mapping_get(ps, inputs);
-
- return p;
-}
-
-void pa_droid_profile_add_mapping(pa_droid_profile *p, pa_droid_mapping *am) {
- pa_assert(p);
- pa_assert(am);
-
- if (am->direction == PA_DIRECTION_OUTPUT)
- pa_idxset_put(p->output_mappings, am, NULL);
- else
- p->input_mapping = am;
-}
-
-static pa_droid_profile *add_profile(pa_droid_profile_set *ps,
- const pa_droid_config_device *primary_output,
- const pa_droid_config_device *output,
- const pa_droid_config_device *input) {
- pa_droid_profile *ap;
-
- pa_assert(!primary_output || primary_output->direction == PA_DIRECTION_OUTPUT);
- pa_assert(output && output->direction == PA_DIRECTION_OUTPUT);
- pa_assert(!input || input->direction == PA_DIRECTION_INPUT);
-
- pa_log_debug("New profile: %s-%s", output->name, input ? input->name : "no input");
-
- ap = droid_profile_new(ps, primary_output, output, input);
-
- pa_hashmap_put(ps->profiles, ap->name, ap);
-
- return ap;
-}
-
-static pa_droid_profile_set *profile_set_new(const pa_droid_config_hw_module *module) {
+static pa_droid_profile_set *profile_set_new(dm_config_module *module) {
pa_droid_profile_set *ps;
pa_assert(module);
@@ -239,118 +178,160 @@
return ps;
}
-static void add_all_profiles(pa_droid_profile_set *ps,
- const pa_droid_config_hw_module *module) {
- const pa_droid_config_device *primary_output = NULL;
- const pa_droid_config_device *output;
- const pa_droid_config_device *input;
+static pa_droid_mapping *mapping_by_name(pa_idxset *idxset, const char *name) {
+ pa_droid_mapping *droid_mapping;
+ uint32_t idx;
- pa_assert(ps);
+ PA_IDXSET_FOREACH(droid_mapping, idxset, idx) {
+ if (pa_streq(droid_mapping->mix_port->name, name))
+ return droid_mapping;
+ }
+
+ return NULL;
+}
+
+static pa_droid_mapping *droid_mapping_update(pa_droid_mapping *droid_mapping,
+ pa_droid_profile_set *profile_set,
+ dm_config_module *module,
+ dm_config_port *mix_port,
+ dm_config_port *device_port) {
+ pa_hashmap *map;
+ bool output_mapping = true;
+
+ pa_assert(profile_set);
pa_assert(module);
+ pa_assert(mix_port);
+ pa_assert(device_port);
- SLLIST_FOREACH(output, module->outputs) {
- if (output->flags & AUDIO_OUTPUT_FLAG_PRIMARY) {
- primary_output = output;
- break;
- }
- }
+ if (mix_port->role == DM_CONFIG_ROLE_SINK)
+ output_mapping = false;
- /* Each distinct hw module output matches one profile. If there are multiple inputs
- * combinations are made so that all possible outputs and inputs can be selected.
- * So for outputs "primary" and "hdmi" and input "primary" profiles
- * "primary-primary" and "hdmi-primary" are created. */
-
- SLLIST_FOREACH(output, module->outputs) {
-
- if (module->inputs) {
- SLLIST_FOREACH(input, module->inputs)
- add_profile(ps, primary_output, output, input);
- } else
- add_profile(ps, primary_output, output, NULL);
+ map = output_mapping ? profile_set->output_mappings : profile_set->input_mappings;
+
+ if (!(droid_mapping = pa_hashmap_get(map, mix_port->name))) {
+ pa_log_debug("New %s mapping \"%s\"", output_mapping ? "output" : "input", mix_port->name);
+
+ droid_mapping = pa_xnew0(pa_droid_mapping, 1);
+ droid_mapping->module = module;
+ droid_mapping->profile_set = profile_set;
+ droid_mapping->proplist = pa_proplist_new();
+ droid_mapping->direction = output_mapping ? PA_DIRECTION_OUTPUT : PA_DIRECTION_INPUT;
+ droid_mapping->ports = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);;
+ droid_mapping->mix_port = mix_port;
+ droid_mapping->device_ports = dm_list_new();
+ droid_mapping->name = pa_xstrdup(mix_port->name);
+
+ pa_hashmap_put(map, droid_mapping->name, droid_mapping);
}
-}
-pa_droid_profile_set *pa_droid_profile_set_new(const pa_droid_config_hw_module *module) {
- pa_droid_profile_set *ps;
+ /* Device ports associated with the mapping */
+ dm_list_push_back(droid_mapping->device_ports, device_port);
- ps = profile_set_new(module);
- add_all_profiles(ps, module);
+ if (droid_mapping->direction == PA_DIRECTION_OUTPUT)
+ add_output_ports(droid_mapping, device_port);
+ else
+ add_input_ports(droid_mapping, device_port);
+
+ return droid_mapping;
- return ps;
}
-static void add_default_profile(pa_droid_profile_set *ps,
- const pa_droid_config_hw_module *module,
- const pa_droid_config_device *primary_output,
- const pa_droid_config_device *low_latency_output,
- const pa_droid_config_device *media_latency_output,
- const pa_droid_config_device *inputs) {
+#define ALLOWED_OUTPUT_TYPES (AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_PRIMARY | AUDIO_OUTPUT_FLAG_DEEP_BUFFER)
- pa_droid_profile *p;
+static void update_mapping(pa_droid_profile_set *profile_set,
+ pa_droid_profile *profile,
+ dm_config_module *module,
+ dm_config_port *source,
+ dm_config_port *sink) {
- pa_assert(ps);
- pa_assert(module);
- pa_assert(!primary_output || primary_output->direction == PA_DIRECTION_OUTPUT);
- pa_assert(!low_latency_output || low_latency_output->direction == PA_DIRECTION_OUTPUT);
- pa_assert(!media_latency_output || media_latency_output->direction == PA_DIRECTION_OUTPUT);
-
- pa_log_debug("New default profile");
-
- p = profile_new(ps, module, "default", "Default profile");
-
- if (primary_output)
- pa_idxset_put(p->output_mappings, pa_droid_mapping_get(ps, primary_output), NULL);
- if (low_latency_output && primary_output != low_latency_output)
- pa_idxset_put(p->output_mappings, pa_droid_mapping_get(ps, low_latency_output), NULL);
- if (media_latency_output && primary_output != media_latency_output && low_latency_output != media_latency_output)
- pa_idxset_put(p->output_mappings, pa_droid_mapping_get(ps, media_latency_output), NULL);
- if (inputs)
- p->input_mapping = pa_droid_mapping_get(ps, inputs);
+ pa_droid_mapping *droid_mapping = NULL;
+ pa_idxset *mappings;
+ bool put = true;
- p->priority += DEFAULT_PRIORITY * (pa_idxset_size(p->output_mappings) + p->input_mapping ? 1 : 0);
- p->priority += primary_output ? DEFAULT_PRIORITY : 0;
- pa_hashmap_put(ps->profiles, p->name, p);
-}
+ /* source sink
+ * For output routes PulseAudio -> mixPort -> devicePort
+ * input routes devicePort -> mixPort -> PulseAudio
+ */
+ if (source->port_type == DM_CONFIG_TYPE_MIX_PORT &&
+ sink->port_type == DM_CONFIG_TYPE_DEVICE_PORT) {
-static void auto_add_profiles(pa_droid_profile_set *ps,
- const pa_droid_config_hw_module *module) {
- const pa_droid_config_device *output;
- const pa_droid_config_device *primary_output = NULL;
- const pa_droid_config_device *low_latency_output = NULL;
- const pa_droid_config_device *media_latency_output = NULL;
+ mappings = profile->output_mappings;
- pa_assert(ps);
- pa_assert(module);
+ if ((droid_mapping = mapping_by_name(mappings, source->name)))
+ put = false;
- /* first find different output types */
- SLLIST_FOREACH(output, module->outputs) {
- if (output->flags & AUDIO_OUTPUT_FLAG_PRIMARY)
- primary_output = output;
-
-#if defined(HAVE_ENUM_AUDIO_OUTPUT_FLAG_RAW)
- else if (output->flags & AUDIO_OUTPUT_FLAG_RAW)
- pa_log_debug("Ignore output %s with flag AUDIO_OUTPUT_FLAG_RAW", output->name);
-#endif
+ droid_mapping = droid_mapping_update(droid_mapping, profile_set, module, source, sink);
-#if defined(HAVE_ENUM_AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)
- else if (output->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)
- pa_log_debug("Ignore output %s with flag AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD", output->name);
-#endif
+ } else if (source->port_type == DM_CONFIG_TYPE_DEVICE_PORT &&
+ sink->port_type == DM_CONFIG_TYPE_MIX_PORT) {
+
+ mappings = profile->input_mappings;
- else if (output->flags & AUDIO_OUTPUT_FLAG_FAST)
- low_latency_output = output;
+ if ((droid_mapping = mapping_by_name(mappings, sink->name)))
+ put = false;
- else if (output->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER)
- media_latency_output = output;
+ droid_mapping = droid_mapping_update(droid_mapping, profile_set, module, sink, source);
+
+ } else {
+ pa_log("Internal data structures are confused.");
+ pa_assert_not_reached();
}
- add_default_profile(ps, module,
- primary_output, low_latency_output, media_latency_output,
- module->inputs);
+
+ if (put)
+ pa_idxset_put(mappings, droid_mapping, NULL);
+}
+
+static void auto_add_profiles(pa_droid_profile_set *profile_set,
+ dm_config_module *module) {
+ pa_droid_profile *profile;
+ dm_config_route *route;
+ void *state, *state2;
+
+ pa_assert(profile_set);
+ pa_assert(module);
+
+ profile = profile_new(profile_set, module, "default", "Default profile");
+
+ /* Droid profiles, mappings and ports are genrated like this:
+ *
+ * 1. route definitions in audio policy configuration are iterated through
+ * 2. for every route, update_mapping is called for every combination of
+ * sink and source, so practically the function is called many times
+ * with identical sink and different source
+ *
+ * PulseAudio internals and audio policy configuration are mapped like this:
+ *
+ * For outputs:
+ *
+ * audio policy xml | port type | PulseAudio
+ * ---------------------|---------------|------------------------
+ * mixPort | source | pa_droid_mapping
+ * devicePort | sink | pa_droid_port
+ *
+ * For inputs:
+ *
+ * audio policy xml | port type | PulseAudio
+ * ---------------------|---------------|------------------------
+ * mixPort | sink | pa_droid_mapping
+ * devicePort | source | pa_droid_port
+ *
+ * In other words, for every mixPort there will be one sink or source,
+ * and for every devicePort there will be one output or input port used
+ * by sinks and sources.
+ */
+
+ DM_LIST_FOREACH_DATA(route, module->routes, state) {
+ dm_config_port *source;
+
+ DM_LIST_FOREACH_DATA(source, route->sources, state2) {
+ update_mapping(profile_set, profile, module, source, route->sink);
+ }
+ }
}
-pa_droid_profile_set *pa_droid_profile_set_default_new(const pa_droid_config_hw_module *module) {
+pa_droid_profile_set *pa_droid_profile_set_default_new(dm_config_module *module) {
pa_droid_profile_set *ps;
ps = profile_set_new(module);
@@ -365,6 +346,7 @@
pa_xfree(am->name);
pa_proplist_free(am->proplist);
pa_idxset_free(am->ports, NULL);
+ dm_list_free(am->device_ports, NULL);
pa_xfree(am);
}
@@ -375,6 +357,8 @@
pa_xfree(ap->description);
if (ap->output_mappings)
pa_idxset_free(ap->output_mappings, NULL);
+ if (ap->input_mappings)
+ pa_idxset_free(ap->input_mappings, NULL);
ap->input_mapping = NULL;
pa_xfree(ap);
}
@@ -405,14 +389,15 @@
pa_xfree(ps);
}
-static pa_droid_port *create_o_port(pa_droid_mapping *am, uint32_t device, const char *name, const char *description) {
+static pa_droid_port *create_output_port(pa_droid_mapping *am,
+ dm_config_port *device_port,
+ const char *name,
+ const char *description) {
pa_droid_port *p;
- char *desc;
pa_assert(am);
pa_assert(name);
- pa_log_debug(" New output port %s", name);
p = pa_xnew0(pa_droid_port, 1);
p->mapping = am;
@@ -420,223 +405,155 @@
if (description) {
p->description = pa_xstrdup(description);
} else {
- desc = pa_replace(name, "output-", "Output to ");
- p->description = pa_replace(desc, "_", " ");
- pa_xfree(desc);
+ p->description = pa_replace(name, "output-", "Output to ");
+ dm_replace_in_place(&p->description, "_", " ");
}
p->priority = DEFAULT_PRIORITY;
- p->device = device;
+ p->device_port = device_port;
- if (am->output->module->global_config ? am->output->module->global_config->attached_output_devices & device
- : am->profile_set->config->global_config->attached_output_devices & device)
- p->priority += DEFAULT_PRIORITY;
-
- if (am->output->module->global_config ? am->output->module->global_config->default_output_device & device
- : am->profile_set->config->global_config->default_output_device & device)
- p->priority += DEFAULT_PRIORITY;
+ if (device_port) {
+ if (am->module->attached_devices) {
+ const dm_config_port *attached_port;
+ void *state;
+
+ DM_LIST_FOREACH_DATA(attached_port, am->module->attached_devices, state) {
+ if (attached_port->type == device_port->type) {
+ p->priority += DEFAULT_PRIORITY;
+ break;
+ }
+ }
+ }
+
+ if (am->module->default_output_device &&
+ am->module->default_output_device->type == device_port->type)
+ p->priority += DEFAULT_PRIORITY;
+ }
return p;
}
-static void add_o_ports(pa_droid_mapping *am) {
- pa_droid_port *p;
+static void add_output_ports(pa_droid_mapping *droid_mapping, dm_config_port *device_port) {
+ pa_droid_port *port;
const char *name;
- uint32_t devices;
- uint32_t combo_devices;
- uint32_t i = 0;
-
- pa_assert(am);
-
- devices = am->output->devices;
-
- /* IHF combo devices, these devices are combined with IHF, only if swap quirk is disabled. */
- if (!pa_droid_quirk(hw_primary, QUIRK_SWAP_HEADPHONE_SPEAKER))
- combo_devices = AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
+ bool new = false;
- while (devices) {
- uint32_t cur_device = (1 << i++);
+ pa_assert(droid_mapping);
- if (devices & cur_device) {
+ pa_assert_se(pa_droid_output_port_name(device_port->type, &name));
- if (pa_droid_quirk(hw_primary, QUIRK_SWAP_HEADPHONE_SPEAKER) &&
- cur_device & (AUDIO_DEVICE_OUT_WIRED_HEADPHONE | AUDIO_DEVICE_OUT_SPEAKER)) {
- if (cur_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE)
- pa_assert_se(pa_droid_output_port_name(AUDIO_DEVICE_OUT_SPEAKER, &name));
- else /* cur_device & AUDIO_DEVICE_OUT_SPEAKER */
- pa_assert_se(pa_droid_output_port_name(AUDIO_DEVICE_OUT_WIRED_HEADPHONE, &name));
- } else
- pa_assert_se(pa_droid_output_port_name(cur_device, &name));
+ /* First add parking port */
- if (!(p = pa_hashmap_get(am->profile_set->all_ports, name))) {
-
- p = create_o_port(am, cur_device, name, NULL);
- pa_hashmap_put(am->profile_set->all_ports, p->name, p);
- } else
- pa_log_debug(" Output port %s from cache", name);
-
- pa_idxset_put(am->ports, p, NULL);
+ if (!(port = pa_hashmap_get(droid_mapping->profile_set->all_ports, PA_DROID_OUTPUT_PARKING))) {
+ /* Create parking port for output mapping to be used when audio_mode_t changes. */
+ port = create_output_port(droid_mapping, NULL, PA_DROID_OUTPUT_PARKING, "Parking port");
+ /* Reset priority to half of default */
+ port->priority = DEFAULT_PRIORITY / 2;
- devices &= ~cur_device;
- }
+ pa_hashmap_put(droid_mapping->profile_set->all_ports, port->name, port);
}
- /* Combo devices, route to multiple routing targets simultaneously. */
- if (am->output->devices & combo_devices) {
- pa_assert_se(pa_droid_output_port_name(combo_devices, &name));
- if (!(p = pa_hashmap_get(am->profile_set->all_ports, name))) {
- p = create_o_port(am, combo_devices, name, NULL);
- /* Reset priority to default. */
- p->priority = DEFAULT_PRIORITY;
+ pa_idxset_put(droid_mapping->ports, port, NULL);
- pa_hashmap_put(am->profile_set->all_ports, p->name, p);
- } else
- pa_log_debug(" Output port %s from cache", name);
+ /* Then add normal port */
- pa_idxset_put(am->ports, p, NULL);
+ if (!(port = pa_hashmap_get(droid_mapping->profile_set->all_ports, name))) {
+ new = true;
+ port = create_output_port(droid_mapping, device_port, name, NULL);
+ pa_hashmap_put(droid_mapping->profile_set->all_ports, port->name, port);
}
- if (!(p = pa_hashmap_get(am->profile_set->all_ports, PA_DROID_OUTPUT_PARKING))) {
- /* Create parking port for output mapping to be used when audio_mode_t changes. */
- p = create_o_port(am, 0, PA_DROID_OUTPUT_PARKING, "Parking port");
- /* Reset priority to half of default */
- p->priority = DEFAULT_PRIORITY / 2;
-
- pa_hashmap_put(am->profile_set->all_ports, p->name, p);
- } else
- pa_log_debug(" Output port %s from cache", PA_DROID_OUTPUT_PARKING);
+ if (new)
+ pa_log_debug(" Mapping %s add new output port %s", droid_mapping->name, name);
+ else
+ pa_log_debug(" Mapping %s add output port %s from cache", droid_mapping->name, name);
- pa_idxset_put(am->ports, p, NULL);
+ pa_idxset_put(droid_mapping->ports, port, NULL);
}
-static void add_i_port(pa_droid_mapping *am, uint32_t device, const char *name) {
+static pa_droid_port *create_input_port(pa_droid_mapping *am,
+ dm_config_port *device_port,
+ const char *name,
+ const char *description) {
pa_droid_port *p;
- char *desc;
pa_assert(am);
pa_assert(name);
- if (!(p = pa_hashmap_get(am->profile_set->all_ports, name))) {
- pa_log_debug(" New input port %s", name);
- p = pa_xnew0(pa_droid_port, 1);
-
- p->mapping = am;
- p->name = pa_xstrdup(name);
- desc = pa_replace(name, "input-", "Input from ");
- p->description = pa_replace(desc, "_", " ");
- pa_xfree(desc);
- p->priority = DEFAULT_PRIORITY;
- p->device = device;
+ p = pa_xnew0(pa_droid_port, 1);
- if (am->inputs->module->global_config ? am->inputs->module->global_config->attached_input_devices & device
- : am->profile_set->config->global_config->attached_input_devices & device)
- p->priority += DEFAULT_PRIORITY;
+ p->mapping = am;
+ p->name = pa_xstrdup(name);
+ if (description) {
+ p->description = pa_xstrdup(description);
+ } else {
+ p->description = pa_replace(name, "input-", "Input from ");
+ dm_replace_in_place(&p->description, "_", " ");
+ }
+ p->priority = DEFAULT_PRIORITY;
+ p->device_port = device_port;
- pa_hashmap_put(am->profile_set->all_ports, p->name, p);
- } else
- pa_log_debug(" Input port %s from cache", name);
+ if (device_port) {
+ if (am->module->attached_devices) {
+ const dm_config_port *attached_port;
+ void *state;
+
+ DM_LIST_FOREACH_DATA(attached_port, am->module->attached_devices, state) {
+ if (attached_port->type == device_port->type) {
+ p->priority += DEFAULT_PRIORITY;
+ break;
+ }
+ }
+ }
+ }
- pa_idxset_put(am->ports, p, NULL);
+ return p;
}
-static void add_i_ports(pa_droid_mapping *am) {
- pa_droid_port *p;
+static void add_input_ports(pa_droid_mapping *droid_mapping, dm_config_port *device_port) {
+ pa_droid_port *port;
const char *name;
- const pa_droid_config_device *input;
- uint32_t devices = AUDIO_DEVICE_IN_DEFAULT;
- uint32_t i = 0;
-
- pa_assert(am);
-
- SLLIST_FOREACH(input, am->inputs)
- devices |= input->devices;
+ bool new = false;
-#if AUDIO_API_VERSION_MAJ >= 2
- devices &= ~AUDIO_DEVICE_BIT_IN;
-#endif
-
- while (devices) {
- uint32_t cur_device = (1 << i++);
-
- if (devices & cur_device) {
+ pa_assert(droid_mapping);
+ pa_assert(device_port);
-#if AUDIO_API_VERSION_MAJ >= 2
- cur_device |= AUDIO_DEVICE_BIT_IN;
-#endif
+ pa_assert_se(pa_droid_input_port_name(device_port->type, &name));
- pa_assert_se(pa_droid_input_port_name(cur_device, &name));
- add_i_port(am, cur_device, name);
+ /* First add parking port */
- devices &= ~cur_device;
- }
- }
-
-#if AUDIO_API_VERSION_MAJ == 1
- /* HAL v1 has default input device defined as another input device,
- * so we need to add it by hand here. */
- add_i_port(am, AUDIO_DEVICE_IN_DEFAULT, "input-default");
-#endif
-
- if (!(p = pa_hashmap_get(am->profile_set->all_ports, PA_DROID_INPUT_PARKING))) {
- pa_log_debug(" New input port %s", PA_DROID_INPUT_PARKING);
+ if (!(port = pa_hashmap_get(droid_mapping->profile_set->all_ports, PA_DROID_INPUT_PARKING))) {
/* Create parking port for input mapping to be used when audio_mode_t changes. */
- p = pa_xnew0(pa_droid_port, 1);
- p->mapping = am;
- p->name = pa_sprintf_malloc(PA_DROID_INPUT_PARKING);
- p->description = pa_sprintf_malloc("Parking port");
- p->priority = 50;
- p->device = 0; /* No routing */
-
- pa_hashmap_put(am->profile_set->all_ports, p->name, p);
- } else
- pa_log_debug(" Input port %s from cache", PA_DROID_INPUT_PARKING);
-
- pa_idxset_put(am->ports, p, NULL);
-}
-
-pa_droid_mapping *pa_droid_mapping_get(pa_droid_profile_set *ps, const pa_droid_config_device *device) {
- pa_droid_mapping *am;
- pa_hashmap *map;
-
- pa_assert(ps);
- pa_assert(device);
-
- map = device->direction == PA_DIRECTION_OUTPUT ? ps->output_mappings : ps->input_mappings;
+ port = create_input_port(droid_mapping, NULL, PA_DROID_INPUT_PARKING, "Parking port");
+ /* Reset priority to half of default */
+ port->priority = DEFAULT_PRIORITY / 2;
- if ((am = pa_hashmap_get(map, device->name))) {
- pa_log_debug(" %s mapping %s from cache", pa_direction_to_string(device->direction), device->name);
- return am;
+ pa_hashmap_put(droid_mapping->profile_set->all_ports, port->name, port);
}
- pa_log_debug(" New %s mapping %s", pa_direction_to_string(device->direction), device->name);
- am = pa_xnew0(pa_droid_mapping, 1);
- am->profile_set = ps;
- am->proplist = pa_proplist_new();
- am->direction = device->direction;
- am->ports = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);;
+ pa_idxset_put(droid_mapping->ports, port, NULL);
- if (am->direction == PA_DIRECTION_OUTPUT) {
- am->name = pa_xstrdup(device->name);
- am->output = device;
- add_o_ports(am);
- } else {
- /* Use common name */
- am->name = pa_xstrdup("droid");
- /* Use all inputs as a list */
- am->inputs = device;
- add_i_ports(am);
+ /* Then add normal port */
+
+ if (!(port = pa_hashmap_get(droid_mapping->profile_set->all_ports, name))) {
+ new = true;
+ port = create_input_port(droid_mapping, device_port, name, NULL);
+ pa_hashmap_put(droid_mapping->profile_set->all_ports, port->name, port);
}
- pa_hashmap_put(map, am->name, am);
+ if (new)
+ pa_log_debug(" Mapping %s add new input port %s", droid_mapping->name, name);
+ else
+ pa_log_debug(" Mapping %s add input port %s from cache", droid_mapping->name, name);
- return am;
+ pa_idxset_put(droid_mapping->ports, port, NULL);
}
bool pa_droid_mapping_is_primary(pa_droid_mapping *am) {
pa_assert(am);
if (am->direction == PA_DIRECTION_OUTPUT) {
- pa_assert(am->output);
- return am->output->flags & AUDIO_OUTPUT_FLAG_PRIMARY;
+ pa_assert(am->mix_port);
+ return am->mix_port->flags & AUDIO_OUTPUT_FLAG_PRIMARY;
}
return true;
@@ -664,6 +581,11 @@
uint32_t idx;
int count = 0;
+ if (am->direction == PA_DIRECTION_OUTPUT && !(am->mix_port->flags & AUDIO_OUTPUT_FLAG_PRIMARY)) {
+ /* Don't create ports for other than primary sink. */
+ return 0;
+ }
+
pa_log_debug("Ports for %s%s: %s", cp ? "card " : "", am->direction == PA_DIRECTION_OUTPUT ? "output" : "input", am->name);
PA_IDXSET_FOREACH(p, am->ports, idx) {
@@ -684,7 +606,7 @@
dp->profiles = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
data = PA_DEVICE_PORT_DATA(dp);
- data->device = p->device;
+ data->device_port = p->device_port;
} else
pa_log_debug(" Port %s from cache", p->name);
@@ -721,95 +643,69 @@
add_ports(core, cp, ports, am, NULL);
}
-void pa_droid_quirk_log(pa_droid_hw_module *hw) {
+void pa_droid_options_log(pa_droid_hw_module *hw) {
uint32_t i;
pa_assert(hw);
- for (i = 0; i < sizeof(valid_quirks) / sizeof(struct droid_quirk); i++) {
- if (hw->quirks.enabled[i]) {
- pa_log_debug("Enabled quirks:");
- for (i = 0; i < sizeof(valid_quirks) / sizeof(struct droid_quirk); i++)
- if (hw->quirks.enabled[i])
- pa_log_debug(" %s", valid_quirks[i].name);
- return;
- }
+ pa_log_debug("Module options:");
+ for (i = 0; i < sizeof(valid_options) / sizeof(struct droid_option); i++) {
+ pa_log_debug(" [%s] %s", hw->options.enabled[i] ? "x" : " ", valid_options[i].name);
}
}
-static pa_droid_quirks *set_default_quirks(pa_droid_quirks *q) {
- pa_assert(q);
+static void set_options(pa_droid_options *options,
+ const audio_hw_device_t *hw_device,
+ const struct user_options *user_options) {
+ pa_assert(options);
+
+ memset(options, 0, sizeof(*options));
+
+ /* First set defaults */
- q->enabled[QUIRK_CLOSE_INPUT] = true;
- q->enabled[QUIRK_OUTPUT_FAST] = true;
- q->enabled[QUIRK_OUTPUT_DEEP_BUFFER] = true;
+ options->enabled[DM_OPTION_CLOSE_INPUT] = true;
+ options->enabled[DM_OPTION_OUTPUT_FAST] = true;
+ options->enabled[DM_OPTION_OUTPUT_DEEP_BUFFER] = true;
+ options->enabled[DM_OPTION_HW_VOLUME] = true;
+ options->enabled[DM_OPTION_OUTPUT_VOIP_RX] = true;
#if (ANDROID_VERSION_MAJOR >= 5) || defined(DROID_AUDIO_HAL_ATOI_FIX)
- q->enabled[QUIRK_INPUT_ATOI] = true;
+ options->enabled[DM_OPTION_INPUT_ATOI] = true;
#endif
-#if defined(DROID_DEVICE_ANZU) ||\
- defined(DROID_DEVICE_COCONUT) || defined(DROID_DEVICE_HAIDA) ||\
- defined(DROID_DEVICE_HALLON) || defined(DROID_DEVICE_IYOKAN) ||\
- defined(DROID_DEVICE_MANGO) || defined(DROID_DEVICE_SATSUMA) ||\
- defined(DROID_DEVICE_SMULTRON) || defined(DROID_DEVICE_URUSHI)
-#warning Using set_parameters hack, originating from previous cm10 mako.
- q->enabled[QUIRK_SET_PARAMETERS] = true;
-#endif
+ /* Then override by user defined options */
- return q;
-}
+ if (user_options) {
+ int i;
-bool pa_droid_quirk_parse(pa_droid_quirks *quirks, const char *quirks_def) {
- char *quirk = NULL;
- char *d;
- const char *state = NULL;
+ for (i = 0; i < DM_OPTION_COUNT; i++) {
+ if (user_options->options[i].set)
+ options->enabled[i] = user_options->options[i].enable;
+ }
+ }
+}
- pa_assert(quirks);
+static bool droid_options_parse(struct user_options *user_options, pa_modargs *ma) {
+ const char *value;
+ int i;
- memset(quirks, 0, sizeof(*quirks));
- set_default_quirks(quirks);
+ pa_assert(user_options);
+ pa_assert(ma);
- if (!quirks_def)
- return true;
+ memset(user_options, 0, sizeof(*user_options));
- while ((quirk = pa_split(quirks_def, ",", &state))) {
- uint32_t i;
- bool enable = false;
- bool found = false;
-
- if (strlen(quirk) < 2)
- goto error;
-
- d = quirk + 1;
-
- if (quirk[0] == '+')
- enable = true;
- else if (quirk[0] == '-')
- enable = false;
- else
- goto error;
-
- for (i = 0; i < sizeof(valid_quirks) / sizeof(struct droid_quirk); i++) {
- if (pa_streq(valid_quirks[i].name, d)) {
- quirks->enabled[valid_quirks[i].value] = enable;
- found = true;
+ for (i = 0; i < DM_OPTION_COUNT; i++) {
+ if ((value = pa_modargs_get_value(ma, valid_options[i].name, NULL))) {
+ if (pa_modargs_get_value_boolean(ma, valid_options[i].name, &user_options->options[i].enable) < 0) {
+ pa_log("Failed to parse module option %s=%s (needs boolean value).", valid_options[i].name, value);
+ return false;
+ } else {
+ user_options->options[i].set = true;
}
}
-
- if (!found)
- goto error;
-
- pa_xfree(quirk);
}
return true;
-
-error:
- pa_log("Incorrect quirk definition \"%s\" (\"%s\")", quirk ? quirk : "<null>", quirks_def);
- pa_xfree(quirk);
-
- return false;
}
static void update_sink_types(pa_droid_hw_module *hw, pa_sink *ignore_sink) {
@@ -818,6 +714,7 @@
pa_sink *low_latency_sink = NULL;
pa_sink *media_latency_sink = NULL;
pa_sink *offload_sink = NULL;
+ pa_sink *voip_sink = NULL;
pa_droid_stream *s;
uint32_t idx;
@@ -833,17 +730,20 @@
if (sink == ignore_sink)
continue;
- if (s->output->flags & AUDIO_OUTPUT_FLAG_PRIMARY)
+ if (s->mix_port->flags & AUDIO_OUTPUT_FLAG_PRIMARY)
primary_sink = sink;
- if (pa_droid_quirk(hw, QUIRK_OUTPUT_FAST) && s->output->flags & AUDIO_OUTPUT_FLAG_FAST)
+ if (pa_droid_option(hw, DM_OPTION_OUTPUT_FAST) && s->mix_port->flags & AUDIO_OUTPUT_FLAG_FAST)
low_latency_sink = sink;
- if (pa_droid_quirk(hw, QUIRK_OUTPUT_DEEP_BUFFER) && s->output->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER)
+ if (pa_droid_option(hw, DM_OPTION_OUTPUT_DEEP_BUFFER) && s->mix_port->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER)
media_latency_sink = sink;
+ if (pa_droid_option(hw, DM_OPTION_OUTPUT_VOIP_RX) && s->mix_port->flags & AUDIO_OUTPUT_FLAG_VOIP_RX)
+ voip_sink = sink;
+
#if defined(HAVE_ENUM_AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)
- if (s->output->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)
+ if (s->mix_port->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)
offload_sink = sink;
#endif
}
@@ -854,6 +754,9 @@
if (primary_sink == media_latency_sink)
media_latency_sink = NULL;
+ if (primary_sink == voip_sink)
+ voip_sink = NULL;
+
if (low_latency_sink)
pa_proplist_sets(low_latency_sink->proplist, PROP_DROID_OUTPUT_LOW_LATENCY, "true");
@@ -863,10 +766,14 @@
if (offload_sink)
pa_proplist_sets(offload_sink->proplist, PROP_DROID_OUTPUT_OFFLOAD, "true");
+ if (voip_sink)
+ pa_proplist_sets(voip_sink->proplist, PROP_DROID_OUTPUT_VOIP, "true");
+
if (primary_sink) {
pa_proplist_sets(primary_sink->proplist, PROP_DROID_OUTPUT_PRIMARY, "true");
pa_proplist_sets(primary_sink->proplist, PROP_DROID_OUTPUT_LOW_LATENCY, low_latency_sink ? "false" : "true");
pa_proplist_sets(primary_sink->proplist, PROP_DROID_OUTPUT_MEDIA_LATENCY, media_latency_sink ? "false" : "true");
+ pa_proplist_sets(primary_sink->proplist, PROP_DROID_OUTPUT_VOIP, voip_sink ? "false" : "true");
}
}
@@ -899,15 +806,15 @@
return pa_sprintf_malloc("droid-hardware-module-%s", module_id);
}
-static void quirk_audio_cal(pa_droid_hw_module *hw, uint32_t flags) {
+static void option_audio_cal(pa_droid_hw_module *hw, uint32_t flags) {
struct group *grp;
pa_assert(hw);
- if (!pa_droid_quirk(hw, QUIRK_AUDIO_CAL_WAIT))
+ if (!pa_droid_option(hw, DM_OPTION_AUDIO_CAL_WAIT))
return;
- if (access(QUIRK_AUDIO_CAL_FILE, F_OK) == 0) {
+ if (access(DM_OPTION_AUDIO_CAL_FILE, F_OK) == 0) {
if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) {
pa_log_info("Waiting for audio calibration to load.");
/* 1 second is enough, so let's double that. */
@@ -916,35 +823,35 @@
return;
}
- pa_log_info("Waiting for audio calibration to finish... (%d seconds)", QUIRK_AUDIO_CAL_WAIT_S);
+ pa_log_info("Waiting for audio calibration to finish... (%d seconds)", DM_OPTION_AUDIO_CAL_WAIT_S);
/* First wait until the calibration file appears on file system. */
- for (int i = 0; i < QUIRK_AUDIO_CAL_WAIT_S; i++) {
- pa_log_debug("%d...", QUIRK_AUDIO_CAL_WAIT_S - i);
+ for (int i = 0; i < DM_OPTION_AUDIO_CAL_WAIT_S; i++) {
+ pa_log_debug("%d...", DM_OPTION_AUDIO_CAL_WAIT_S - i);
pa_msleep(PA_MSEC_PER_SEC);
- if (access(QUIRK_AUDIO_CAL_FILE, F_OK) == 0) {
- pa_log_debug("Calibration file " QUIRK_AUDIO_CAL_FILE " appeared, wait one second more.");
+ if (access(DM_OPTION_AUDIO_CAL_FILE, F_OK) == 0) {
+ pa_log_debug("Calibration file " DM_OPTION_AUDIO_CAL_FILE " appeared, wait one second more.");
/* Then wait for a bit more. */
pa_msleep(PA_MSEC_PER_SEC);
break;
}
}
- if (access(QUIRK_AUDIO_CAL_FILE, F_OK) != 0)
+ if (access(DM_OPTION_AUDIO_CAL_FILE, F_OK) != 0)
goto fail;
- if (!(grp = getgrnam(QUIRK_AUDIO_CAL_GROUP))) {
- pa_log("couldn't get gid for " QUIRK_AUDIO_CAL_GROUP);
+ if (!(grp = getgrnam(DM_OPTION_AUDIO_CAL_GROUP))) {
+ pa_log("couldn't get gid for " DM_OPTION_AUDIO_CAL_GROUP);
goto fail;
}
- if (chown(QUIRK_AUDIO_CAL_FILE, getuid(), grp->gr_gid) < 0) {
- pa_log("chown failed for " QUIRK_AUDIO_CAL_FILE);
+ if (chown(DM_OPTION_AUDIO_CAL_FILE, getuid(), grp->gr_gid) < 0) {
+ pa_log("chown failed for " DM_OPTION_AUDIO_CAL_FILE);
goto fail;
}
- if (chmod(QUIRK_AUDIO_CAL_FILE, QUIRK_AUDIO_CAL_MODE) < 0) {
- pa_log("chmod failed for " QUIRK_AUDIO_CAL_FILE);
+ if (chmod(DM_OPTION_AUDIO_CAL_FILE, DM_OPTION_AUDIO_CAL_MODE) < 0) {
+ pa_log("chmod failed for " DM_OPTION_AUDIO_CAL_FILE);
goto fail;
}
@@ -953,10 +860,10 @@
return;
fail:
- if (access(QUIRK_AUDIO_CAL_FILE, F_OK) == 0)
- unlink(QUIRK_AUDIO_CAL_FILE);
+ if (access(DM_OPTION_AUDIO_CAL_FILE, F_OK) == 0)
+ unlink(DM_OPTION_AUDIO_CAL_FILE);
- pa_log("Audio calibration file generation failed! (" QUIRK_AUDIO_CAL_FILE " doesn't exist)");
+ pa_log("Audio calibration file generation failed! (" DM_OPTION_AUDIO_CAL_FILE " doesn't exist)");
}
static int droid_set_parameters_v1_cb(void *handle, const char *key_value_pairs) {
@@ -994,9 +901,9 @@
return key_value_pairs;
}
-static pa_droid_hw_module *droid_hw_module_open(pa_core *core, const pa_droid_config_audio *config,
- const char *module_id, const pa_droid_quirks *quirks) {
- const pa_droid_config_hw_module *module;
+static pa_droid_hw_module *droid_hw_module_open(pa_core *core, dm_config_device *config,
+ const char *module_id, const struct user_options *user_options) {
+ const dm_config_module *module;
pa_droid_hw_module *hw = NULL;
struct hw_module_t *hwmod = NULL;
audio_hw_device_t *device = NULL;
@@ -1010,9 +917,9 @@
goto fail;
}
- pa_log_info("Droid-jb2q hw module %s", VERSION);
+ pa_log_info("Droid hw module %s", VERSION);
- if (!(module = pa_droid_config_find_module(config, module_id))) {
+ if (!(module = dm_config_find_module(config, module_id))) {
pa_log("Couldn't find module with id %s", module_id);
goto fail;
}
@@ -1043,6 +950,7 @@
}
hw = pa_xnew0(pa_droid_hw_module, 1);
+ set_options(&hw->options, device, user_options);
PA_REFCNT_INIT(hw);
hw->core = core;
hw->hwmod = hwmod;
@@ -1050,16 +958,12 @@
hw->output_mutex = pa_mutex_new(true, false);
hw->input_mutex = pa_mutex_new(true, false);
hw->device = device;
- hw->config = pa_droid_config_dup(config);
- hw->enabled_module = pa_droid_config_find_module(hw->config, module_id);
+ hw->config = dm_config_dup(config);
+ hw->enabled_module = dm_config_find_module(hw->config, module_id);
hw->module_id = hw->enabled_module->name;
hw->shared_name = shared_name_get(hw->module_id);
hw->outputs = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
hw->inputs = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
- if (quirks)
- memcpy(&hw->quirks, quirks, sizeof(*quirks));
- else
- set_default_quirks(&hw->quirks);
hw->sink_put_hook_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SINK_PUT], PA_HOOK_EARLY-10,
sink_put_hook_cb, hw);
@@ -1068,10 +972,9 @@
pa_assert_se(pa_shared_set(core, hw->shared_name, hw) >= 0);
- if (pa_streq(hw->module_id, PA_DROID_PRIMARY_DEVICE)) {
- hw_primary = hw;
+ /* API for calling HAL functions from other modules. */
- /* API for calling HAL functions from other modules. */
+ if (pa_streq(hw->module_id, PA_DROID_PRIMARY_DEVICE)) {
pa_shared_set(core, DROID_HW_HANDLE_V1, hw);
pa_shared_set(core, DROID_SET_PARAMETERS_V1, droid_set_parameters_v1_cb);
pa_shared_set(core, DROID_GET_PARAMETERS_V1, droid_get_parameters_v1_cb);
@@ -1108,8 +1011,8 @@
pa_droid_hw_module *pa_droid_hw_module_get2(pa_core *core, pa_modargs *ma, const char *module_id) {
pa_droid_hw_module *hw = NULL;
- pa_droid_config_audio *config = NULL;
- pa_droid_quirks quirks;
+ dm_config_device *config = NULL;
+ struct user_options user_options;
pa_assert(core);
pa_assert(ma);
@@ -1120,23 +1023,23 @@
if ((hw = droid_hw_module_shared_get(core, module_id)))
return hw;
- /* No hw module object in shared object db, let's parse quirks and config and
+ /* No hw module object in shared object db, let's parse options and config and
* open the module now. */
- if (!pa_droid_quirk_parse(&quirks, pa_modargs_get_value(ma, "quirks", NULL)))
+ if (!droid_options_parse(&user_options, ma))
return NULL;
- if (!(config = pa_droid_config_load(ma)))
+ if (!(config = dm_config_load(ma)))
return NULL;
- hw = droid_hw_module_open(core, config, module_id, &quirks);
+ hw = droid_hw_module_open(core, config, module_id, &user_options);
- pa_droid_config_free(config);
+ dm_config_free(config);
return hw;
}
-pa_droid_hw_module *pa_droid_hw_module_get(pa_core *core, const pa_droid_config_audio *config, const char *module_id) {
+pa_droid_hw_module *pa_droid_hw_module_get(pa_core *core, dm_config_device *config, const char *module_id) {
pa_droid_hw_module *hw;
if (!(hw = droid_hw_module_shared_get(core, module_id)))
@@ -1170,12 +1073,12 @@
pa_hook_slot_free(hw->sink_unlink_hook_slot);
if (hw->config)
- pa_droid_config_free(hw->config);
+ dm_config_free(hw->config);
if (hw->device) {
- if (pa_droid_quirk(hw, QUIRK_UNLOAD_CALL_EXIT))
+ if (pa_droid_option(hw, DM_OPTION_UNLOAD_CALL_EXIT))
exit(EXIT_SUCCESS);
- else if (!pa_droid_quirk(hw, QUIRK_UNLOAD_NO_CLOSE))
+ else if (!pa_droid_option(hw, DM_OPTION_UNLOAD_NO_CLOSE))
audio_hw_device_close(hw->device);
}
@@ -1201,9 +1104,6 @@
pa_idxset_free(hw->inputs, NULL);
}
- if (hw_primary == hw)
- hw_primary = NULL;
-
pa_xfree(hw);
}
@@ -1238,14 +1138,14 @@
}
static pa_droid_stream *droid_stream_new(pa_droid_hw_module *module,
- const pa_droid_config_device *device_def) {
+ dm_config_port *mix_port) {
pa_droid_stream *s;
s = pa_xnew0(pa_droid_stream, 1);
PA_REFCNT_INIT(s);
s->module = pa_droid_hw_module_ref(module);
- s->device_def = device_def;
+ s->mix_port = mix_port;
return s;
}
@@ -1254,9 +1154,16 @@
return pa_xnew0(pa_droid_output_stream, 1);
}
-static pa_droid_input_stream *droid_input_stream_new(void) {
- pa_droid_input_stream *input = pa_xnew0(pa_droid_input_stream, 1);
+static pa_droid_input_stream *droid_input_stream_new(dm_config_port *default_mix_port,
+ const pa_sample_spec *default_sample_spec,
+ const pa_channel_map *default_channel_map) {
+ pa_droid_input_stream *input;
+
+ input = pa_xnew0(pa_droid_input_stream, 1);
input->first = true;
+ input->default_mix_port = default_mix_port;
+ input->default_sample_spec = *default_sample_spec;
+ input->default_channel_map = *default_channel_map;
return input;
}
@@ -1284,166 +1191,291 @@
return ret;
}
-static bool stream_config_fill(const pa_droid_config_device *device_def,
- audio_devices_t devices,
+static bool compatible_port(const dm_config_port *port,
+ const pa_sample_spec *sample_spec,
+ const pa_channel_map *channel_map,
+ const dm_config_profile **compatible_profile,
+ pa_sample_spec *compatible_sample_spec,
+ pa_channel_map *compatible_channel_map,
+ audio_channel_mask_t *compatible_channel_mask) {
+ const dm_config_profile *profile;
+ void *state;
+
+ pa_assert(port);
+ pa_assert(port->port_type != DM_CONFIG_TYPE_MIX);
+ pa_assert(sample_spec);
+ pa_assert(compatible_sample_spec);
+ pa_assert(compatible_channel_map);
+ pa_assert(compatible_channel_mask);
+
+ *compatible_sample_spec = *sample_spec;
+ *compatible_channel_map = *channel_map;
+
+ DM_LIST_FOREACH_DATA(profile, port->profiles, state) {
+ uint32_t format = 0;
+ bool sample_rate_compatible = false;
+ bool channel_count_compatible = false;
+ int i;
+
+ if (!pa_convert_format(profile->format, CONV_FROM_HAL, &format))
+ continue;
+
+ if (sample_spec->format != (pa_sample_format_t) format)
+ continue;
+
+ if (profile->sampling_rates[0] == 0) {
+ sample_rate_compatible = true;
+ pa_log_info("%s port \"%s\" profile has dynamic sample rate.",
+ port->port_type == DM_CONFIG_TYPE_MIX_PORT ? "Mix" : "Device", port->name);
+ } else {
+ /* Rate count is used for reverse iteration if no direct matching sample rate is found. */
+ uint32_t rate_count = 0;
+
+ for (i = 0; profile->sampling_rates[i]; i++) {
+ if (profile->sampling_rates[i] == sample_spec->rate) {
+ sample_rate_compatible = true;
+ break;
+ }
+ rate_count++;
+ }
+
+ if (!sample_rate_compatible) {
+ /* Search from highest sample rate to lowest. */
+ for (i = rate_count - 1; i >= 0; i--) {
+ if (profile->sampling_rates[i] % sample_spec->rate == 0) {
+ sample_rate_compatible = true;
+ compatible_sample_spec->rate = profile->sampling_rates[i];
+ break;
+ }
+
+ }
+ }
+
+ if (!sample_rate_compatible) {
+ for (i = 0; profile->sampling_rates[i]; i++) {
+ compatible_sample_spec->rate = profile->sampling_rates[i];
+ if (compatible_sample_spec->rate > sample_spec->rate) {
+ break;
+ }
+ }
+ }
+
+ /* Sample rate is compatible if at least one sample rate is found. */
+ sample_rate_compatible = true;
+ }
+
+ if (profile->channel_masks[0] == 0) {
+ channel_count_compatible = true;
+ *compatible_channel_mask = 0;
+ } else {
+ for (i = 0; profile->channel_masks[i]; i++) {
+ if (audio_channel_count_from_out_mask(profile->channel_masks[i]) == channel_map->channels) {
+ channel_count_compatible = true;
+ *compatible_channel_mask = profile->channel_masks[i];
+ break;
+ }
+ }
+
+ if (!channel_count_compatible) {
+ /* We support only mono and stereo anyway at the moment so just choose either.
+ * If we wanted mono and mono wasn't available above then use stereo if found,
+ * and same if we wanted stereo and stereo wasn't available then use mono if found. */
+ for (i = 0; profile->channel_masks[i]; i++) {
+ if (audio_channel_count_from_out_mask(profile->channel_masks[i]) == 2 &&
+ channel_map->channels == 1) {
+ channel_count_compatible = true;
+ pa_channel_map_init_stereo(compatible_channel_map);
+ *compatible_channel_mask = profile->channel_masks[i];
+ break;
+ } else if (audio_channel_count_from_out_mask(profile->channel_masks[i]) == 1 &&
+ channel_map->channels == 2) {
+ channel_count_compatible = true;
+ pa_channel_map_init_mono(compatible_channel_map);
+ *compatible_channel_mask = profile->channel_masks[i];
+ break;
+ }
+ }
+ }
+ }
+
+ if (sample_rate_compatible && channel_count_compatible) {
+ if (compatible_profile)
+ *compatible_profile = profile;
+
+ compatible_sample_spec->channels = compatible_channel_map->channels;
+
+ return true;
+ }
+ } /* DM_LIST_FOREACH_DATA */
+
+ return false;
+}
+
+static bool stream_config_fill(pa_droid_hw_module *hw,
+ const dm_config_port *mix_port,
+ const dm_config_port *device_port,
pa_sample_spec *sample_spec,
pa_channel_map *channel_map,
struct audio_config *config) {
audio_format_t hal_audio_format = 0;
audio_channel_mask_t hal_channel_mask = 0;
- bool voicecall_record = false;
bool output = true;
+ pa_sample_spec compatible_sample_spec;
+ pa_channel_map compatible_channel_map;
+ char tmp[64];
int i;
+ pa_assert(mix_port);
+ pa_assert(mix_port->port_type == DM_CONFIG_TYPE_MIX_PORT);
+ pa_assert(device_port);
pa_assert(sample_spec);
pa_assert(channel_map);
pa_assert(config);
-#if AUDIO_API_VERSION_MAJ >= 2
- if (devices & AUDIO_DEVICE_BIT_IN) {
- output = false;
- devices &= ~AUDIO_DEVICE_BIT_IN;
- }
-#else
- output = !(devices & AUDIO_DEVICE_IN_ALL);
-#endif
+ output = mix_port->role == DM_CONFIG_ROLE_SOURCE ? true : false;
- if (devices & AUDIO_DEVICE_IN_VOICE_CALL) {
- pa_log_debug("Fill config: Use voice call");
- voicecall_record = true;
+ if (!pa_convert_format(sample_spec->format, CONV_FROM_PA, &hal_audio_format)) {
+ pa_log_warn("Sample spec format %u not supported.", sample_spec->format);
+ goto fail;
}
- for (i = 0; i < channel_map->channels; i++) {
- bool found;
- audio_channel_mask_t c;
-
- found = output ? pa_convert_output_channel(channel_map->map[i], CONV_FROM_PA, &c)
- : pa_convert_input_channel(channel_map->map[i], CONV_FROM_PA, &c);
-
- if (!found) {
- pa_log("Failed to convert %s channel map.", output ? "output" : "input");
- goto fail;
- }
-
- hal_channel_mask |= c;
+ if (!output && pa_droid_option(hw, DM_OPTION_RECORD_VOICE_16K) && hw->state.mode == AUDIO_MODE_IN_CALL) {
+ pa_log_debug("Suggest sample rate of 16kHz for voice call input stream.");
+ sample_spec->rate = 16000;
}
- if (voicecall_record) {
- /* Only allow recording both downlink and uplink. */
-#if defined(QCOM_HARDWARE)
- pa_channel_map_init_mono(channel_map);
- sample_spec->channels = 1;
- #if (ANDROID_VERSION_MAJOR <= 4) && defined(HAVE_ENUM_AUDIO_CHANNEL_IN_VOICE_CALL_MONO)
- hal_channel_mask = AUDIO_CHANNEL_IN_VOICE_CALL_MONO;
- #else
- hal_channel_mask = AUDIO_CHANNEL_IN_MONO;
- #endif
-#elif defined(HAVE_ENUM_AUDIO_CHANNEL_IN_VOICE_UPLINK) && defined(HAVE_ENUM_AUDIO_CHANNEL_IN_VOICE_DNLINK)
- pa_channel_map_init_stereo(channel_map);
- sample_spec->channels = 2;
- hal_channel_mask = AUDIO_CHANNEL_IN_VOICE_UPLINK | AUDIO_CHANNEL_IN_VOICE_DNLINK;
-#else
+ if (output && mix_port->flags & AUDIO_OUTPUT_FLAG_VOIP_RX) {
+ pa_log_info("Override voip_rx channel map (mono) and sample rate (%d)", DROID_VOIP_RX_SAMPLE_RATE);
pa_channel_map_init_mono(channel_map);
- sample_spec->channels = 1;
- hal_channel_mask = AUDIO_CHANNEL_IN_MONO;
-#endif
- pa_log_debug("Fill config: Use %d channel(s) for voice call.", sample_spec->channels);
+ sample_spec->channels = channel_map->channels;
+ sample_spec->rate = DROID_VOIP_RX_SAMPLE_RATE;
}
- if (!pa_convert_format(sample_spec->format, CONV_FROM_PA, &hal_audio_format)) {
- pa_log_warn("Sample spec format %u not supported.", sample_spec->format);
+ if (!compatible_port(mix_port, sample_spec, channel_map,
+ NULL, &compatible_sample_spec, &compatible_channel_map, &hal_channel_mask)) {
+ pa_log("Couldn't find compatible configuration for mix port \"%s\"", mix_port->name);
goto fail;
}
- /* As input sample metrics are based on user request we need to make sure that the sample
- * format requested is actually usable with the input route. */
- if (!output) {
- const pa_droid_config_device *ddef;
- uint32_t tmp;
- const char *fmt;
- uint32_t format_found = 0;
-
- pa_log_debug("Fill config: Try to use format %s, sample rate %u",
- pa_string_convert_num_to_str(CONV_STRING_FORMAT, hal_audio_format, &fmt) ? fmt : "<unknown>",
- sample_spec->rate);
-
- SLLIST_FOREACH(ddef, device_def) {
- format_found |= ddef->formats & hal_audio_format;
-
- if (!(ddef->formats & hal_audio_format) ||
- !(ddef->devices & devices))
- continue;
-
- for (i = 0; i < AUDIO_MAX_SAMPLING_RATES && ddef->sampling_rates[i]; i++) {
- if (ddef->sampling_rates[i] == (uint32_t) -1 ||
- ddef->sampling_rates[i] == sample_spec->rate) {
- goto format_found;
- }
+ /* Dynamic channel mask, so let's just convert our pa_channel_map. */
+ if (hal_channel_mask == 0) {
+ for (i = 0; i < channel_map->channels; i++) {
+ bool found;
+ audio_channel_mask_t c;
+
+ found = output ? pa_convert_output_channel(channel_map->map[i], CONV_FROM_PA, &c)
+ : pa_convert_input_channel(channel_map->map[i], CONV_FROM_PA, &c);
+
+ if (!found) {
+ pa_log("Failed to convert %s channel map.", output ? "output" : "input");
+ goto fail;
}
- }
- if (!format_found && hal_audio_format != DEFAULT_AUDIO_FORMAT) {
- hal_audio_format = DEFAULT_AUDIO_FORMAT;
- pa_assert_se(pa_convert_format(hal_audio_format, CONV_FROM_HAL, &tmp));
- sample_spec->format = tmp;
- pa_log_debug("Fill config: Override sample format, use default %s.",
- pa_string_convert_num_to_str(CONV_STRING_FORMAT, hal_audio_format, &fmt) ? fmt : "<unknown>");
+ hal_channel_mask |= c;
}
+ }
- SLLIST_FOREACH(ddef, device_def) {
- if (!(ddef->devices & devices) ||
- !ddef->sampling_rates[0])
- continue;
+ if (!pa_sample_spec_equal(sample_spec, &compatible_sample_spec)) {
+ pa_log_debug("With mix port \"%s\" requested sample spec: %s %uch %uHz",
+ mix_port->name,
+ pa_sample_format_to_string(sample_spec->format),
+ sample_spec->channels,
+ sample_spec->rate);
- if (ddef->sampling_rates[0] == (uint32_t) -1)
- goto format_found;
+ *sample_spec = compatible_sample_spec;
+ }
- for (i = 0; i < AUDIO_MAX_SAMPLING_RATES && ddef->sampling_rates[i]; i++) {
- if (ddef->sampling_rates[i] == sample_spec->rate)
- goto format_found;
- }
+ pa_log_info("Using mix port \"%s\" with sample spec: %s %uch, %uHz",
+ mix_port->name,
+ pa_sample_format_to_string(compatible_sample_spec.format),
+ compatible_sample_spec.channels,
+ compatible_sample_spec.rate);
- /* Start from highest sample rate value */
- for (i = 0; i < AUDIO_MAX_SAMPLING_RATES && ddef->sampling_rates[i]; i++)
- ;
-
- for (i -= 1; i >= 0; i--) {
- if ((ddef->sampling_rates[i] % 11025 == 0 && sample_spec->rate % 11025 == 0) ||
- (ddef->sampling_rates[i] % 4000 == 0 && sample_spec->rate % 4000 == 0)) {
- sample_spec->rate = ddef->sampling_rates[i];
- pa_log_debug("Fill config: Override sample rate, use %u.", sample_spec->rate);
- goto format_found;
- }
- }
- }
+ if (!pa_channel_map_equal(channel_map, &compatible_channel_map)) {
+ pa_channel_map_snprint(tmp, sizeof(tmp), channel_map);
+ pa_log_debug("With mix port \"%s\" requested channel map: %s",
+ mix_port->name,
+ tmp);
- /* Format not found, fail */
- goto fail;
+ *channel_map = compatible_channel_map;
}
-format_found:
+
+ pa_channel_map_snprint(tmp, sizeof(tmp), &compatible_channel_map);
+ pa_log_info("Using mix port \"%s\" with channel map: %s",
+ mix_port->name,
+ tmp);
memset(config, 0, sizeof(*config));
- config->sample_rate = sample_spec->rate;
+ config->sample_rate = compatible_sample_spec.rate;
config->channel_mask = hal_channel_mask;
config->format = hal_audio_format;
+ *sample_spec = compatible_sample_spec;
+ *channel_map = compatible_channel_map;
+
return true;
fail:
return false;
}
+static dm_config_port *stream_select_mix_port(pa_droid_stream *stream) {
+ dm_config_port *selected_port;
+
+ pa_assert(stream);
+ pa_assert(stream->mix_port);
+ pa_assert(stream->input);
+
+ selected_port = stream->input->default_mix_port;
+
+ if (stream->input && stream->module->state.mode == AUDIO_MODE_IN_COMMUNICATION) {
+ dm_config_port *port;
+ void *state;
+
+ DM_LIST_FOREACH_DATA(port, stream->module->enabled_module->mix_ports, state) {
+ if (port->role != DM_CONFIG_ROLE_SINK)
+ continue;
+
+ if (port->flags & AUDIO_INPUT_FLAG_VOIP_TX) {
+ selected_port = port;
+ goto done;
+ }
+ }
+ }
+
+ if (stream->input && stream->module->state.mode == AUDIO_MODE_IN_CALL) {
+ dm_config_route *route;
+ dm_config_port *port;
+ void *state1, *state2;
+
+ DM_LIST_FOREACH_DATA(route, stream->module->enabled_module->routes, state1) {
+ DM_LIST_FOREACH_DATA(port, route->sources, state2) {
+ if (port->role != DM_CONFIG_ROLE_SOURCE)
+ continue;
+
+ if (port->type == AUDIO_DEVICE_IN_TELEPHONY_RX) {
+ selected_port = route->sink;
+ goto done;
+ }
+ }
+ }
+ }
+
+done:
+ pa_log_debug("Select input mix port \"%s\"", selected_port->name);
+
+ return selected_port;
+}
+
pa_droid_stream *pa_droid_open_output_stream(pa_droid_hw_module *module,
const pa_sample_spec *spec,
const pa_channel_map *map,
- const char *module_output_name,
- audio_devices_t devices) {
- const pa_droid_config_device *module_output = NULL;
- pa_droid_stream *s = NULL;
+ dm_config_port *mix_port,
+ dm_config_port *device_port) {
+ pa_droid_stream *stream = NULL;
pa_droid_output_stream *output = NULL;
pa_droid_stream *primary_stream = NULL;
int ret;
- struct audio_stream_out *stream;
pa_channel_map channel_map;
pa_sample_spec sample_spec;
struct audio_config config_out;
@@ -1451,80 +1483,78 @@
pa_assert(module);
pa_assert(spec);
pa_assert(map);
- pa_assert(module_output_name);
+ pa_assert(mix_port);
+ pa_assert(device_port);
sample_spec = *spec;
channel_map = *map;
- if (!(module_output = pa_droid_config_find_output(module->enabled_module, module_output_name))) {
- pa_log("Could not find output %s from module %s.", module_output_name, module->enabled_module->name);
+ stream = droid_stream_new(module, mix_port);
+ stream->output = output = droid_output_stream_new();
+
+ if (mix_port != dm_config_find_mix_port(module->enabled_module, mix_port->name)) {
+ pa_log("Could not find mix port \"%s\" from module %s.", mix_port->name, module->enabled_module->name);
goto fail;
}
- pa_log_info("Open output stream %s", module_output_name);
-
- if (!stream_config_fill(module_output, devices, &sample_spec, &channel_map, &config_out))
+ if (device_port != dm_config_find_device_port(mix_port, device_port->type)) {
+ pa_log("Could not find device port \"%s\" (%#010x) usable with mix port \"%s\".",
+ device_port->name, device_port->type, mix_port->name);
goto fail;
-
- if (pa_idxset_size(module->outputs) == 0)
- pa_log_debug("Set initial output device to %#010x", devices);
- else if ((primary_stream = pa_droid_hw_primary_output_stream(module))) {
- pa_log_debug("Primary output with device %#010x already open, using as initial device.",
- primary_stream->output->device);
- devices = primary_stream->output->device;
}
+ pa_log_info("Open output stream \"%s\"->\"%s\".", mix_port->name, device_port->name);
+
+ if (!stream_config_fill(module, stream->mix_port, device_port, &sample_spec, &channel_map, &config_out))
+ goto fail;
+
pa_droid_hw_module_lock(module);
ret = module->device->open_output_stream(module->device,
- ++module->stream_out_id,
- devices,
- module_output->flags,
+ ++module->stream_id,
+ device_port->type,
+ mix_port->flags,
&config_out,
- &stream
-#if AUDIO_API_VERSION_MAJ >= 3
- /* Go with empty address, should work
- * with most devices for now. */
- , ""
-#endif
- );
+ &output->stream,
+ device_port->address);
pa_droid_hw_module_unlock(module);
- if (ret < 0 || !stream) {
+ if (ret < 0 || !output->stream) {
pa_log("Failed to open output stream: %d", ret);
goto fail;
}
- quirk_audio_cal(module, module_output->flags);
+ option_audio_cal(module, mix_port->flags);
- s = droid_stream_new(module, module_output);
- s->output = output = droid_output_stream_new();
- output->stream = stream;
output->sample_spec = *spec;
output->channel_map = *map;
- output->flags = module_output->flags;
- output->device = devices;
+ stream->active_device_port = NULL;
+ stream->io_handle = module->stream_id;
- if ((output->sample_spec.rate = output->stream->common.get_sample_rate(&output->stream->common)) != spec->rate)
- pa_log_warn("Requested sample rate %u but got %u instead.", spec->rate, output->sample_spec.rate);
+ if ((output->sample_spec.rate = output->stream->common.get_sample_rate(&output->stream->common)) != sample_spec.rate)
+ pa_log_warn("Requested sample rate %u but got %u instead.", sample_spec.rate, output->sample_spec.rate);
- pa_idxset_put(module->outputs, s, NULL);
+ pa_idxset_put(module->outputs, stream, NULL);
- s->buffer_size = output->stream->common.get_buffer_size(&output->stream->common);
+ stream->buffer_size = output->stream->common.get_buffer_size(&output->stream->common);
+
+ if ((primary_stream = pa_droid_hw_primary_output_stream(module))) {
+ pa_droid_stream_set_route(primary_stream, device_port);
+ }
pa_log_info("Opened droid output stream %p with device: %u flags: %u sample rate: %u channels: %u (%u) format: %u (%u) buffer size: %zu (%" PRIu64 " usec)",
- (void *) s,
- devices,
- output->flags,
+ (void *) output->stream,
+ device_port->type,
+ stream->mix_port->flags,
output->sample_spec.rate,
output->sample_spec.channels, config_out.channel_mask,
output->sample_spec.format, config_out.format,
- s->buffer_size,
- pa_bytes_to_usec(s->buffer_size, &output->sample_spec));
+ stream->buffer_size,
+ pa_bytes_to_usec(stream->buffer_size, &output->sample_spec));
- return s;
+ return stream;
fail:
- pa_xfree(s);
+ pa_xfree(stream);
pa_xfree(output);
return NULL;
@@ -1541,15 +1571,6 @@
return "AUDIO_MODE_NORMAL";
}
-static void set_active_input(pa_droid_hw_module *hw_module, pa_droid_stream *stream) {
- pa_assert(hw_module);
-
- if (hw_module->state.active_input != stream) {
- pa_log_info("Set active input to %p", (void *) stream);
- hw_module->state.active_input = stream;
- }
-}
-
static bool config_diff(const struct audio_config *a, const struct audio_config *b,
bool *sample_rate, bool *channel_mask, bool *format) {
bool diff = false;
@@ -1633,7 +1654,7 @@
}
static void log_input_open(pa_log_level_t log_level, const char *prefix,
- audio_devices_t device,
+ const dm_config_port *device_port,
audio_source_t source,
uint32_t flags, /* audio_input_flags_t */
const pa_sample_spec *sample_spec,
@@ -1642,7 +1663,7 @@
pa_logl(log_level,
"%s input stream with device: %#010x source: %#010x flags: %#010x sample rate: %u (%u) channels: %u (%#010x) format: %u (%#010x) (return code %d)",
prefix,
- device,
+ device_port->type,
source,
flags,
sample_spec->rate,
@@ -1654,11 +1675,13 @@
return_code);
}
-static int input_stream_open(pa_droid_stream *s, bool resume_from_suspend) {
+
+static int input_stream_open(pa_droid_stream *stream, bool resume_from_suspend) {
pa_droid_hw_module *hw_module;
pa_droid_input_stream *input = NULL;
pa_channel_map channel_map;
pa_sample_spec sample_spec;
+ dm_config_port *mix_port;
size_t buffer_size;
bool try_defaults = true;
int ret = -1;
@@ -1670,47 +1693,50 @@
bool diff_channel_mask = false;
bool diff_format = false;
- pa_assert(s);
- pa_assert(s->input);
- pa_assert_se((hw_module = s->module));
+ pa_assert(stream);
+ pa_assert(stream->input);
+ pa_assert_se((hw_module = stream->module));
- if (s->input->stream) /* already open */
+ if (stream->input->stream) /* already open */
return 0;
- pa_assert(!s->module->state.active_input);
-
- input = s->input;
+ input = stream->input;
input->stream = NULL;
/* Copy our requested specs */
- sample_spec = input->req_sample_spec;
- channel_map = input->req_channel_map;
+ if (input->first) {
+ sample_spec = input->default_sample_spec;
+ channel_map = input->default_channel_map;
+ } else {
+ sample_spec = input->req_sample_spec;
+ channel_map = input->req_channel_map;
+ }
+
+ mix_port = stream_select_mix_port(stream);
- if (!stream_config_fill(s->device_def, hw_module->state.input_device, &sample_spec, &channel_map, &config_try))
+ if (!stream_config_fill(hw_module, mix_port, stream->active_device_port, &sample_spec, &channel_map, &config_try))
goto done;
- pa_droid_hw_module_lock(s->module);
+ pa_droid_hw_module_lock(stream->module);
while (true) {
config_in = config_try;
log_input_open(PA_LOG_INFO, "Trying to open",
- hw_module->state.input_device,
- hw_module->state.audio_source,
- 0, /* AUDIO_INPUT_FLAG_NONE on v3. v1 and v2 don't have input flags. */
+ stream->active_device_port,
+ input->audio_source,
+ mix_port->flags,
&sample_spec,
&config_in,
0);
ret = hw_module->device->open_input_stream(hw_module->device,
- ++hw_module->stream_in_id,
- hw_module->state.input_device,
+ ++hw_module->stream_id,
+ stream->active_device_port->type,
&config_in,
- &input->stream
-#if AUDIO_API_VERSION_MAJ >= 3
- , 0
- , "" /* Use empty address. */
- , hw_module->state.audio_source
-#endif
+ &input->stream,
+ mix_port->flags,
+ stream->active_device_port->address,
+ input->audio_source
);
if (ret < 0) {
if (config_diff(&config_in, &config_try, &diff_sample_rate, &diff_channel_mask, &diff_format)) {
@@ -1737,7 +1763,7 @@
sample_spec = input->default_sample_spec;
channel_map = input->default_channel_map;
- if (!stream_config_fill(s->device_def, hw_module->state.input_device, &sample_spec, &channel_map, &config_try))
+ if (!stream_config_fill(hw_module, mix_port, stream->active_device_port, &sample_spec, &channel_map, &config_try))
goto done;
try_defaults = false;
@@ -1763,13 +1789,13 @@
goto open_done;
}
open_done:
- pa_droid_hw_module_unlock(s->module);
+ pa_droid_hw_module_unlock(stream->module);
if (ret < 0 || !input->stream) {
log_input_open(resume_from_suspend ? PA_LOG_INFO : PA_LOG_ERROR, "Failed to open",
- hw_module->state.input_device,
- hw_module->state.audio_source,
- 0, /* AUDIO_INPUT_FLAG_NONE on v3. v1 and v2 don't have input flags. */
+ stream->active_device_port,
+ input->audio_source,
+ mix_port->flags,
&sample_spec,
&config_in,
ret);
@@ -1778,27 +1804,28 @@
}
log_input_open(PA_LOG_INFO, "Opened",
- hw_module->state.input_device,
- hw_module->state.audio_source,
- 0, /* AUDIO_INPUT_FLAG_NONE on v3. v1 and v2 don't have input flags. */
+ stream->active_device_port,
+ input->audio_source,
+ mix_port->flags,
&sample_spec,
&config_in,
ret);
+ stream->mix_port = mix_port;
input->req_sample_spec = input->sample_spec = sample_spec;
input->req_channel_map = input->channel_map = channel_map;
buffer_size = input->stream->common.get_buffer_size(&input->stream->common);
- s->buffer_size = buffer_size;
+ stream->buffer_size = buffer_size;
+ stream->io_handle = hw_module->stream_id;
/* Set input stream to standby */
- stream_standby(s);
+ stream_standby(stream);
/* As audio_source_t may not have any effect when opening the input stream
* set input parameters immediately after opening the stream. */
- input_stream_set_route(s->module, s);
+ input_stream_set_route(stream, stream->active_device_port);
- pa_log_debug("Opened input stream %p", (void *) s);
- set_active_input(s->module, s);
+ pa_log_debug("Opened input stream %p", (void *) stream);
done:
return ret;
@@ -1811,8 +1838,9 @@
if (!s->input->stream)
return;
+ audio_patch_release(s);
+
pa_mutex_lock(s->module->input_mutex);
- set_active_input(s->module, NULL);
s->input->stream->common.standby(&s->input->stream->common);
s->module->device->close_input_stream(s->module->device, s->input->stream);
s->input->stream = NULL;
@@ -1820,22 +1848,22 @@
pa_mutex_unlock(s->module->input_mutex);
}
-bool pa_droid_stream_reconfigure_input(pa_droid_stream *s,
+bool pa_droid_stream_reconfigure_input(pa_droid_stream *stream,
const pa_sample_spec *requested_sample_spec,
const pa_channel_map *requested_channel_map,
const pa_proplist *proplist) {
/* Use default audio source by default */
audio_source_t audio_source = AUDIO_SOURCE_DEFAULT;
- pa_assert(s);
- pa_assert(s->input);
+ pa_assert(stream);
+ pa_assert(stream->input);
pa_assert(requested_sample_spec);
pa_assert(requested_channel_map);
/* Copy our requested specs, so we know them when resuming from suspend
* as well. */
- s->input->req_sample_spec = *requested_sample_spec;
- s->input->req_channel_map = *requested_channel_map;
+ stream->input->req_sample_spec = *requested_sample_spec;
+ stream->input->req_channel_map = *requested_channel_map;
if (proplist) {
const char *source;
@@ -1845,16 +1873,33 @@
}
/* Update audio source */
- droid_set_audio_source(s->module, audio_source);
+ droid_set_audio_source(stream, audio_source);
+
+ input_stream_close(stream);
+
+ /* Set some sensible default for device port -> look through attached devices and
+ * select first source port. */
+ if (stream->input->first) {
+ dm_config_port *device_port;
+ void *state;
+
+ DM_LIST_FOREACH_DATA(device_port, stream->module->enabled_module->attached_devices, state) {
+ if (device_port->role == DM_CONFIG_ROLE_SOURCE) {
+ pa_log_debug("Select initial input device port \"%s\".", device_port->name);
+ stream->active_device_port = device_port;
+ break;
+ }
+ }
- input_stream_close(s);
+ pa_assert(stream->active_device_port);
+ }
- if (input_stream_open(s, false) < 0) {
- if (!s->input->first) {
- pa_log_debug("Input stream reconfigure failed, restore default values.");
- s->input->req_sample_spec = s->input->default_sample_spec;
- s->input->req_channel_map = s->input->default_channel_map;
- input_stream_open(s, false);
+ if (input_stream_open(stream, false) < 0) {
+ if (!stream->input->first) {
+ pa_log_warn("Input stream reconfigure failed, restore default values.");
+ stream->input->req_sample_spec = stream->input->default_sample_spec;
+ stream->input->req_channel_map = stream->input->default_channel_map;
+ input_stream_open(stream, false);
}
return false;
}
@@ -1862,21 +1907,21 @@
return true;
}
-bool pa_droid_stream_reconfigure_input_needed(pa_droid_stream *s,
+bool pa_droid_stream_reconfigure_input_needed(pa_droid_stream *stream,
const pa_sample_spec *requested_sample_spec,
const pa_channel_map *requested_channel_map,
const pa_proplist *proplist) {
bool reconfigure_needed = false;
- pa_assert(s);
- pa_assert(s->input);
+ pa_assert(stream);
+ pa_assert(stream->input);
- if (requested_sample_spec && !pa_sample_spec_equal(&s->input->sample_spec, requested_sample_spec)) {
+ if (requested_sample_spec && !pa_sample_spec_equal(&stream->input->sample_spec, requested_sample_spec)) {
reconfigure_needed = true;
pa_log_debug("input reconfigure needed: sample specs not equal");
}
- if (requested_channel_map && !pa_channel_map_equal(&s->input->channel_map, requested_channel_map)) {
+ if (requested_channel_map && !pa_channel_map_equal(&stream->input->channel_map, requested_channel_map)) {
reconfigure_needed = true;
pa_log_debug("input reconfigure needed: channel maps not equal");
}
@@ -1888,14 +1933,14 @@
/* If audio source is defined in source-output proplist use that instead. */
if ((source = pa_proplist_gets(proplist, EXT_PROP_AUDIO_SOURCE))) {
if (pa_string_convert_str_to_num(CONV_STRING_AUDIO_SOURCE_FANCY, source, &audio_source) &&
- s->module->state.audio_source != audio_source) {
+ stream->input->audio_source != audio_source) {
reconfigure_needed = true;
pa_log_debug("input reconfigure needed: " EXT_PROP_AUDIO_SOURCE " changes");
}
} else {
- if (pa_input_device_default_audio_source(s->module->state.input_device, &audio_source) &&
- s->module->state.audio_source != audio_source) {
+ if (pa_input_device_default_audio_source(stream->active_device_port->type, &audio_source) &&
+ stream->input->audio_source != audio_source) {
reconfigure_needed = true;
pa_log_debug("input reconfigure needed: audio source changes");
@@ -1908,32 +1953,33 @@
pa_droid_stream *pa_droid_open_input_stream(pa_droid_hw_module *hw_module,
const pa_sample_spec *default_sample_spec,
- const pa_channel_map *default_channel_map) {
+ const pa_channel_map *default_channel_map,
+ const char *mix_port_name) {
- pa_droid_stream *s = NULL;
+ pa_droid_stream *stream = NULL;
pa_droid_input_stream *input = NULL;
+ dm_config_port *mix_port;
pa_assert(hw_module);
+ pa_assert(hw_module->enabled_module);
pa_assert(default_sample_spec);
pa_assert(default_channel_map);
- if (hw_module->state.active_input) {
- pa_log("Opening input stream while there is already active input stream.");
+ if (!(mix_port = dm_config_find_mix_port(hw_module->enabled_module, mix_port_name))) {
+ pa_log("Could not find mix port \"%s\" from module \"%s\".", mix_port_name, hw_module->enabled_module->name);
return NULL;
}
- s = droid_stream_new(hw_module, hw_module->enabled_module->inputs);
- s->input = input = droid_input_stream_new();
- s->input->default_sample_spec = *default_sample_spec;
- s->input->default_channel_map = *default_channel_map;
-
- if (!pa_droid_stream_reconfigure_input(s, default_sample_spec, default_channel_map, NULL)) {
- pa_droid_stream_unref(s);
- s = NULL;
+ stream = droid_stream_new(hw_module, mix_port);
+ stream->input = input = droid_input_stream_new(mix_port, default_sample_spec, default_channel_map);
+
+ if (!pa_droid_stream_reconfigure_input(stream, default_sample_spec, default_channel_map, NULL)) {
+ pa_droid_stream_unref(stream);
+ stream = NULL;
} else
- s->input->first = false;
+ stream->input->first = false;
- return s;
+ return stream;
}
pa_droid_stream *pa_droid_stream_ref(pa_droid_stream *s) {
@@ -1979,153 +2025,179 @@
pa_assert(hw->outputs);
PA_IDXSET_FOREACH(s, hw->outputs, idx) {
- if (s->output->flags & AUDIO_OUTPUT_FLAG_PRIMARY)
+ if (s->mix_port->flags & AUDIO_OUTPUT_FLAG_PRIMARY)
return s;
}
return NULL;
}
-static int droid_output_stream_set_route(pa_droid_stream *s, audio_devices_t device) {
+static void stream_update_bt_sco(pa_droid_hw_module *hw_module, const dm_config_port *device_port) {
+ int set_bt_sco = -1;
+
+ pa_assert(hw_module);
+ pa_assert(device_port);
+
+ if (device_port->type == AUDIO_DEVICE_OUT_BLUETOOTH_SCO ||
+ device_port->type == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET ||
+ device_port->type == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT) {
+
+ if (!hw_module->bt_sco_enabled)
+ set_bt_sco = 1;
+
+ } else {
+ if (hw_module->bt_sco_enabled)
+ set_bt_sco = 0;
+ }
+
+ if (set_bt_sco != -1) {
+ hw_module->bt_sco_enabled = set_bt_sco ? true : false;
+ droid_set_parameters(hw_module, set_bt_sco ? AUDIO_PARAMETER_BT_SCO_ON : AUDIO_PARAMETER_BT_SCO_OFF);
+ }
+}
+
+static void audio_patch_release(pa_droid_stream *stream) {
+ int ret;
+
+ pa_assert(stream);
+
+ if (stream->audio_patch != AUDIO_PATCH_HANDLE_NONE) {
+ ret = stream->module->device->release_audio_patch(stream->module->device, stream->audio_patch);
+ stream->audio_patch = AUDIO_PATCH_HANDLE_NONE;
+ if (ret < 0)
+ pa_log_info("Release %s audio patch %s:%s (%d)",
+ stream->mix_port->role == DM_CONFIG_ROLE_SINK ? "output" : "input",
+ stream->mix_port->name,
+ stream->active_device_port->name,
+ -ret);
+ }
+}
+
+static int audio_patch_update_output(pa_droid_stream *stream, const dm_config_port *device_port) {
pa_droid_output_stream *output;
- pa_droid_stream *slave;
- uint32_t idx;
- char *parameters = NULL;
- int ret = 0;
+ struct audio_port_config sink, source;
+ int ret;
- pa_assert(s);
- pa_assert(s->output);
- pa_assert(s->module);
- pa_assert(s->module->output_mutex);
+ output = stream->output;
- output = s->output;
+ memset(&sink, 0, sizeof(sink));
+ memset(&source, 0, sizeof(source));
- pa_mutex_lock(s->module->output_mutex);
+ source.type = AUDIO_PORT_TYPE_MIX;
+ source.role = AUDIO_PORT_ROLE_SOURCE;
+ source.sample_rate = output->sample_spec.rate;
+ source.format = AUDIO_FORMAT_PCM_16_BIT;
+ source.ext.mix.handle = stream->io_handle;
+
+ sink.role = AUDIO_PORT_ROLE_SINK;
+ sink.type = AUDIO_PORT_TYPE_DEVICE;
+ sink.sample_rate = output->sample_spec.rate;
+ sink.format = AUDIO_FORMAT_PCM_16_BIT;
+ sink.ext.device.address[0] = '\0';
+ if (strlen(device_port->address))
+ strncpy(sink.ext.device.address, device_port->address, AUDIO_DEVICE_MAX_ADDRESS_LEN);
+ sink.ext.device.type = device_port->type;
- if (output->flags & AUDIO_OUTPUT_FLAG_PRIMARY || pa_droid_hw_primary_output_stream(s->module) == NULL) {
- int set_bt_sco = -1;
+ ret = stream->module->device->create_audio_patch(stream->module->device, 1, &source, 1, &sink, &stream->audio_patch);
+ if (ret < 0)
+ pa_log_warn("Failed to create output audio patch \"%s\"->\"%s\" (%d)", stream->mix_port->name, device_port->name, -ret);
+ else
+ pa_log_info("Created output audio patch \"%s\"->\"%s\"", stream->mix_port->name, device_port->name);
- parameters = pa_sprintf_malloc("%s=%u;", AUDIO_PARAMETER_STREAM_ROUTING, device);
+ stream->active_device_port = device_port;
- /* Set BT_SCO parameter for Bluetooth voice/voip call routes. */
- if (device != output->device &&
- (device | output->device) & (AUDIO_DEVICE_OUT_BLUETOOTH_SCO |
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET |
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT)) {
+ return ret;
+}
- set_bt_sco = (device & (AUDIO_DEVICE_OUT_BLUETOOTH_SCO |
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET |
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT)) ? 1 : 0;
- }
+static int audio_patch_update_input(pa_droid_stream *stream, const dm_config_port *device_port) {
+ pa_droid_input_stream *input;
+ struct audio_port_config sink, source;
+ int ret;
- if (set_bt_sco == 1)
- droid_set_parameters(s->module, AUDIO_PARAMETER_BT_SCO_ON);
+ input = stream->input;
- pa_log_debug("output stream %p set_parameters(%s) %#010x", (void *) s, parameters, device);
- ret = output->stream->common.set_parameters(&output->stream->common, parameters);
+ memset(&sink, 0, sizeof(sink));
+ memset(&source, 0, sizeof(source));
- if (set_bt_sco == 0)
- droid_set_parameters(s->module, AUDIO_PARAMETER_BT_SCO_OFF);
+ sink.type = AUDIO_PORT_TYPE_MIX;
+ sink.role = AUDIO_PORT_ROLE_SINK;
+ sink.sample_rate = input->sample_spec.rate;
+ sink.format = AUDIO_FORMAT_PCM_16_BIT;
+ sink.ext.mix.handle = stream->io_handle;
+
+ source.role = AUDIO_PORT_ROLE_SOURCE;
+ source.type = AUDIO_PORT_TYPE_DEVICE;
+ source.sample_rate = input->sample_spec.rate;
+ source.format = AUDIO_FORMAT_PCM_16_BIT;
+ source.ext.device.address[0] = '\0';
+ if (strlen(device_port->address))
+ strncpy(source.ext.device.address, device_port->address, AUDIO_DEVICE_MAX_ADDRESS_LEN);
+ source.ext.device.type = device_port->type;
- if (ret < 0) {
- if (ret == -ENOSYS)
- pa_log_warn("output set_parameters(%s) not allowed while stream is active", parameters);
- else
- pa_log_warn("output set_parameters(%s) failed", parameters);
- } else {
- /* Store last set output device. */
- output->device = device;
- }
- }
+ ret = stream->module->device->create_audio_patch(stream->module->device, 1, &source, 1, &sink, &stream->audio_patch);
+ if (ret < 0)
+ pa_log_warn("Failed to create input audio patch \"%s\"<-\"%s\" (%d)", stream->mix_port->name, device_port->name, -ret);
+ else
+ pa_log_info("Created input audio patch \"%s\"<-\"%s\"", stream->mix_port->name, device_port->name);
- if (output->flags & AUDIO_OUTPUT_FLAG_PRIMARY && pa_idxset_size(s->module->outputs) > 1) {
- pa_assert(parameters);
+ stream->active_device_port = device_port;
- PA_IDXSET_FOREACH(slave, s->module->outputs, idx) {
- if (slave == s)
- continue;
+ return ret;
+}
- if (pa_droid_quirk(s->module, QUIRK_STANDBY_SET_ROUTE)) {
- /* Some devices don't like to receive set_parameters() call while they
- * are in write(), even if it seems the mutexes are correctly in place.
- * Standby is another synchronization point which seems to work better. */
- slave->output->stream->common.standby(&slave->output->stream->common);
- }
+static int droid_output_stream_audio_patch_update(pa_droid_stream *primary_stream, dm_config_port *device_port) {
+ pa_droid_stream *stream;
+ uint32_t idx;
+ int ret;
- pa_log_debug("slave output stream %p set_parameters(%s)", (void *) slave, parameters);
- ret = slave->output->stream->common.set_parameters(&slave->output->stream->common, parameters);
+ pa_assert(primary_stream);
+ pa_assert(primary_stream->output);
+ pa_assert(primary_stream->mix_port);
+ pa_assert(primary_stream->mix_port->type == DM_CONFIG_TYPE_MIX);
+ pa_assert(primary_stream->mix_port->flags & AUDIO_OUTPUT_FLAG_PRIMARY);
+ pa_assert(device_port);
+ pa_assert(device_port->role == DM_CONFIG_ROLE_SINK);
+
+ PA_IDXSET_FOREACH(stream, primary_stream->module->outputs, idx) {
+ audio_patch_release(stream);
+ }
+
+ ret = audio_patch_update_output(primary_stream, device_port);
+
+ if (ret == 0) {
+ PA_IDXSET_FOREACH(stream, primary_stream->module->outputs, idx) {
+ if (primary_stream == stream)
+ continue;
- if (ret < 0) {
- if (ret == -ENOSYS)
- pa_log_warn("output set_parameters(%s) not allowed while stream is active", parameters);
- else
- pa_log_warn("output set_parameters(%s) failed", parameters);
- } else
- slave->output->device = output->device;
+ audio_patch_update_output(stream, device_port);
}
}
- pa_xfree(parameters);
-
- pa_mutex_unlock(s->module->output_mutex);
+ if (ret < 0) {
+ pa_log_warn("Failed to update output stream audio patch (%d)", -ret);
+ }
return ret;
}
-static int input_stream_set_route(pa_droid_hw_module *hw_module, pa_droid_stream *s) {
+static int input_stream_set_route(pa_droid_stream *stream, const dm_config_port *device_port) {
pa_droid_input_stream *input;
- audio_devices_t device;
- audio_source_t source;
char *parameters = NULL;
int ret = 0;
- pa_assert(hw_module);
-
- if (!s)
- s = hw_module->state.active_input;
-
- /* No active input, no need for set parameters */
- if (!s)
- goto done;
+ pa_assert(stream);
- input = s->input;
+ input = stream->input;
- /* Input stream closed, no need for set parameters */
+ /* Input stream closed, no need for routing changes */
if (!input->stream)
goto done;
- device = hw_module->state.input_device;
- source = hw_module->state.audio_source;
-#ifdef DROID_DEVICE_I9305
- device &= ~AUDIO_DEVICE_BIT_IN;
-#endif
-
- if (pa_droid_quirk(hw_module, QUIRK_INPUT_ATOI))
- parameters = pa_sprintf_malloc("%s=%d;%s=%u", AUDIO_PARAMETER_STREAM_ROUTING, (int32_t) device,
- AUDIO_PARAMETER_STREAM_INPUT_SOURCE, source);
- else
- parameters = pa_sprintf_malloc("%s=%u;%s=%u", AUDIO_PARAMETER_STREAM_ROUTING, device,
- AUDIO_PARAMETER_STREAM_INPUT_SOURCE, source);
-
- pa_log_debug("input stream %p set_parameters(%s) %#010x ; %#010x",
- (void *) s, parameters, device, source);
-
- if (pa_droid_quirk(hw_module, QUIRK_SET_PARAMETERS)) {
- pa_mutex_lock(hw_module->hw_mutex);
- ret = hw_module->device->set_parameters(hw_module->device, parameters);
- pa_mutex_unlock(hw_module->hw_mutex);
- } else {
- pa_mutex_lock(hw_module->input_mutex);
- ret = input->stream->common.set_parameters(&input->stream->common, parameters);
- pa_mutex_unlock(hw_module->input_mutex);
- }
+ audio_patch_release(stream);
+ ret = audio_patch_update_input(stream, device_port);
- if (ret < 0) {
- if (ret == -ENOSYS)
- pa_log_warn("input set_parameters(%s) not allowed while stream is active", parameters);
- else
- pa_log_warn("input set_parameters(%s) failed", parameters);
- }
+ if (ret < 0)
+ pa_log_warn("input_stream_set_route(%s) failed", device_port->name);
pa_xfree(parameters);
@@ -2133,14 +2205,21 @@
return ret;
}
-int pa_droid_stream_set_route(pa_droid_stream *s, audio_devices_t device) {
+int pa_droid_stream_set_route(pa_droid_stream *s, dm_config_port *device_port) {
pa_assert(s);
- if (s->output)
- return droid_output_stream_set_route(s, device);
- else {
- pa_droid_hw_set_input_device(s->module, device);
- return input_stream_set_route(s->module, NULL);
+ if (s->output) {
+ int ret;
+
+ if (pa_droid_stream_is_primary(s))
+ stream_update_bt_sco(s->module, device_port);
+
+ ret = droid_output_stream_audio_patch_update(s, device_port);
+
+ return ret;
+ } else {
+ pa_droid_hw_set_input_device(s, device_port);
+ return 0;
}
}
@@ -2203,7 +2282,7 @@
pa_assert(s->output || s->input);
if (s->output)
- return s->output->flags & AUDIO_OUTPUT_FLAG_PRIMARY;
+ return s->mix_port->flags & AUDIO_OUTPUT_FLAG_PRIMARY;
/* Even though earlier (< 3) HALs don't have input flags,
* input flags don't have anything similar as output stream's
@@ -2226,12 +2305,12 @@
} else {
if (suspend) {
if (s->input->stream) {
- if (pa_droid_quirk(s->module, QUIRK_CLOSE_INPUT))
+ if (pa_droid_option(s->module, DM_OPTION_CLOSE_INPUT))
input_stream_close(s);
else
return stream_standby(s);
}
- } else if (pa_droid_quirk(s->module, QUIRK_CLOSE_INPUT))
+ } else if (pa_droid_option(s->module, DM_OPTION_CLOSE_INPUT))
return input_stream_open(s, true);
}
@@ -2349,15 +2428,17 @@
pa_log_info("Set mode to %s.", audio_mode_to_string(mode));
- if (pa_droid_quirk(hw_module, QUIRK_SPEAKER_BEFORE_VOICE) &&
+ if (pa_droid_option(hw_module, DM_OPTION_SPEAKER_BEFORE_VOICE) &&
hw_module->state.mode != mode && mode == AUDIO_MODE_IN_CALL) {
pa_droid_stream *primary_output;
+ dm_config_port *device_port;
/* Set route to speaker before changing audio mode to AUDIO_MODE_IN_CALL.
* Some devices don't get routing right if the route is something else
* (like AUDIO_DEVICE_OUT_WIRED_HEADSET) before calling set_mode().*/
- if ((primary_output = pa_droid_hw_primary_output_stream(hw_module)))
- pa_droid_stream_set_route(primary_output, AUDIO_DEVICE_OUT_SPEAKER);
+ if ((primary_output = pa_droid_hw_primary_output_stream(hw_module)) &&
+ (device_port = dm_config_find_device_port(primary_output->mix_port, AUDIO_DEVICE_OUT_SPEAKER)))
+ pa_droid_stream_set_route(primary_output, device_port);
}
pa_droid_hw_module_lock(hw_module);
@@ -2367,35 +2448,41 @@
} else {
if (hw_module->state.mode != mode && mode == AUDIO_MODE_IN_CALL) {
pa_droid_stream *primary_output;
+ dm_config_port *device_port;
/* Always start call mode with earpiece. This helps some devices which cannot
* start call directly with headset and doesn't cause any harm with devices
* which can either. */
- if ((primary_output = pa_droid_hw_primary_output_stream(hw_module)))
- pa_droid_stream_set_route(primary_output, AUDIO_DEVICE_OUT_EARPIECE);
+ if ((primary_output = pa_droid_hw_primary_output_stream(hw_module)) &&
+ (device_port = dm_config_find_device_port(primary_output->mix_port, AUDIO_DEVICE_OUT_EARPIECE)))
+ pa_droid_stream_set_route(primary_output, device_port);
}
hw_module->state.mode = mode;
}
pa_droid_hw_module_unlock(hw_module);
- /* Update possible audio source. */
- pa_droid_hw_set_input_device(hw_module, hw_module->state.input_device);
-
return ret;
}
/* Return true if audio source changes */
-static bool droid_set_audio_source(pa_droid_hw_module *hw_module, audio_source_t audio_source) {
+static bool droid_set_audio_source(pa_droid_stream *stream, audio_source_t audio_source) {
audio_source_t audio_source_override = AUDIO_SOURCE_DEFAULT;
- pa_assert(hw_module);
+ pa_assert(stream);
+
+ if (audio_source == AUDIO_SOURCE_DEFAULT) {
+ if (!stream->active_device_port) {
+ /* Default to mic source if there is no active device_port. */
+ audio_source = AUDIO_SOURCE_MIC;
+ } else {
+ pa_input_device_default_audio_source(stream->active_device_port->type, &audio_source);
- if (audio_source == AUDIO_SOURCE_DEFAULT)
- pa_input_device_default_audio_source(hw_module->state.input_device, &audio_source);
+ }
+ }
/* Override audio source based on mode. */
- switch (hw_module->state.mode) {
+ switch (stream->module->state.mode) {
case AUDIO_MODE_IN_CALL:
audio_source_override = AUDIO_SOURCE_VOICE_CALL;
break;
@@ -2410,21 +2497,22 @@
if (audio_source != audio_source_override) {
const char *from = NULL, *to = NULL;
pa_string_convert_num_to_str(CONV_STRING_AUDIO_SOURCE_FANCY, audio_source, &from);
- pa_string_convert_num_to_str(CONV_STRING_AUDIO_SOURCE_FANCY, audio_source, &to);
+ pa_string_convert_num_to_str(CONV_STRING_AUDIO_SOURCE_FANCY, audio_source_override, &to);
pa_log_info("Audio mode %s, overriding audio source %s with %s",
- audio_mode_to_string(hw_module->state.mode),
+ audio_mode_to_string(stream->module->state.mode),
from ? from : "<unknown>",
to ? to : "<unknown>");
audio_source = audio_source_override;
}
- if (audio_source != hw_module->state.audio_source) {
+ if (audio_source != stream->input->audio_source) {
const char *name = NULL;
- pa_log_debug("Set global audio source to %s (%#010x)",
+ pa_log_debug("Set mix port \"%s\" audio source to %s (%#010x)",
+ stream->mix_port->name,
pa_string_convert_num_to_str(CONV_STRING_AUDIO_SOURCE_FANCY, audio_source, &name)
? name : "<unknown>",
audio_source);
- hw_module->state.audio_source = audio_source;
+ stream->input->audio_source = audio_source;
/* audio source changed */
return true;
@@ -2434,27 +2522,35 @@
return false;
}
-bool pa_droid_hw_set_input_device(pa_droid_hw_module *hw_module,
- audio_devices_t device) {
+
+bool pa_droid_hw_set_input_device(pa_droid_stream *stream,
+ dm_config_port *device_port) {
bool device_changed = false;
bool source_changed = false;
- pa_assert(hw_module);
+ pa_assert(stream);
+ pa_assert(stream->input);
+ pa_assert(device_port);
+ pa_assert(device_port->port_type == DM_CONFIG_TYPE_DEVICE_PORT);
+
+ if (!stream->active_device_port ||
+ !dm_config_port_equal(stream->active_device_port, device_port)) {
- if (hw_module->state.input_device != device) {
const char *name = NULL;
- pa_log_debug("Set global input to %s (%#010x)",
- pa_string_convert_input_device_num_to_str(device, &name)
+ pa_log_debug("Set mix port \"%s\" input to %s (%#010x, %s)",
+ stream->mix_port->name,
+ pa_string_convert_input_device_num_to_str(device_port->type, &name)
? name : "<unknown>",
- device);
- hw_module->state.input_device = device;
+ device_port->type,
+ device_port->name);
+ stream->active_device_port = device_port;
device_changed = true;
}
- source_changed = droid_set_audio_source(hw_module, hw_module->state.audio_source);
+ source_changed = droid_set_audio_source(stream, stream->input->audio_source);
- if (hw_module->state.active_input && (device_changed || source_changed))
- input_stream_set_route(hw_module, NULL);
+ if (stream->active_device_port && (device_changed || source_changed))
+ input_stream_set_route(stream, device_port);
return true;
}
@@ -2472,3 +2568,26 @@
return stream->output ? &stream->output->channel_map : &stream->input->channel_map;
}
+
+pa_modargs *pa_droid_modargs_new(const char *args, const char* const keys[]) {
+ pa_modargs *ma;
+ const char **full_keys;
+ int count;
+ int i, k;
+
+ for (count = 0; keys[count]; count++) ;
+
+ full_keys = pa_xnew0(const char *, count + DM_OPTION_COUNT + 1);
+
+ for (i = 0; keys[i]; i++)
+ full_keys[i] = keys[i];
+
+ for (k = 0; k < DM_OPTION_COUNT; k++)
+ full_keys[i++] = valid_options[k].name;
+
+ ma = pa_modargs_new(args, full_keys);
+
+ pa_xfree(full_keys);
+
+ return ma;
+}
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-14.2.100.tar.bz2/src/common/include/droid/conversion.h
^
|
@@ -2,7 +2,7 @@
#define foodroidconversionfoo
/*
- * Copyright (C) 2018 Jolla Ltd.
+ * Copyright (C) 2018-2022 Jolla Ltd.
*
* Contact: Juho Hämäläinen <juho.hamalainen@jolla.com>
*
@@ -71,8 +71,6 @@
bool pa_string_convert_flag_num_to_str(audio_output_flags_t value, const char **to_str);
bool pa_string_convert_flag_str_to_num(const char *str, audio_output_flags_t *to_value);
-char *pa_list_string_output_device(audio_devices_t devices);
-char *pa_list_string_input_device(audio_devices_t devices);
char *pa_list_string_flags(audio_output_flags_t flags);
/* Get default audio source associated with input device.
@@ -87,22 +85,22 @@
const char *str, uint32_t *dst, char **unknown_entries);
bool pa_conversion_parse_sampling_rates(const char *fn, const unsigned ln,
- const char *str, bool legacy,
+ const char *str,
uint32_t sampling_rates[AUDIO_MAX_SAMPLING_RATES]);
bool pa_conversion_parse_formats(const char *fn, const unsigned ln,
- const char *str, bool legacy,
+ const char *str,
audio_format_t *formats);
int pa_conversion_parse_output_channels(const char *fn, const unsigned ln,
- const char *str, bool legacy,
- audio_channel_mask_t *channels);
+ const char *str,
+ audio_channel_mask_t channel_masks[AUDIO_MAX_CHANNEL_MASKS]);
int pa_conversion_parse_input_channels(const char *fn, const unsigned ln,
- const char *str, bool legacy,
- audio_channel_mask_t *channels);
+ const char *str,
+ audio_channel_mask_t channel_masks[AUDIO_MAX_CHANNEL_MASKS]);
bool pa_conversion_parse_output_devices(const char *fn, const unsigned ln,
- char *str, bool legacy, bool must_recognize_all,
+ char *str, bool must_recognize_all,
audio_devices_t *devices);
bool pa_conversion_parse_input_devices(const char *fn, const unsigned ln,
- char *str, bool legacy, bool must_recognize_all,
+ char *str, bool must_recognize_all,
audio_devices_t *devices);
bool pa_conversion_parse_output_flags(const char *fn, const unsigned ln,
const char *str, audio_output_flags_t *flags);
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-14.2.100.tar.bz2/src/common/include/droid/droid-config.h
^
|
@@ -2,7 +2,7 @@
#define foodroidconfigfoo
/*
- * Copyright (C) 2018 Jolla Ltd.
+ * Copyright (C) 2018-2022 Jolla Ltd.
*
* Contact: Juho Hämäläinen <juho.hamalainen@jolla.com>
*
@@ -30,75 +30,106 @@
#include <android-config.h>
#include <hardware/audio.h>
+#include <droid/sllist.h>
#include <droid/version.h>
-typedef struct pa_droid_config_audio pa_droid_config_audio;
-typedef struct pa_droid_config_hw_module pa_droid_config_hw_module;
+#define AUDIO_MAX_SAMPLING_RATES (32)
+#define AUDIO_MAX_CHANNEL_MASKS (32)
-#define AUDIO_MAX_SAMPLING_RATES (32)
+typedef struct dm_config_global dm_config_global;
+typedef struct dm_config_port dm_config_port;
+typedef struct dm_config_route dm_config_route;
+typedef struct dm_config_module dm_config_module;
+typedef struct dm_config_device dm_config_device;
+typedef struct dm_config_profile dm_config_profile;
+
+struct dm_config_global {
+ char *key;
+ char *value;
+};
+
+struct dm_config_profile {
+ char *name;
+ audio_format_t format; /* 0 -> dynamic TODO check that this is still true */
+ uint32_t sampling_rates[AUDIO_MAX_SAMPLING_RATES]; /* sampling_rates[0] == 0 -> dynamic, otherwise 0 terminates list */
+ audio_channel_mask_t channel_masks[AUDIO_MAX_CHANNEL_MASKS]; /* channel_masks[0] == 0 -> dynamic */
+};
-typedef struct pa_droid_config_global {
- uint32_t audio_hal_version;
- audio_devices_t attached_output_devices;
- audio_devices_t default_output_device;
- audio_devices_t attached_input_devices;
-} pa_droid_config_global;
+typedef enum dm_config_role {
+ DM_CONFIG_ROLE_SINK,
+ DM_CONFIG_ROLE_SOURCE,
+} dm_config_role_t;
+
+typedef enum dm_config_type {
+ DM_CONFIG_TYPE_MIX,
+ DM_CONFIG_TYPE_DEVICE_PORT,
+ DM_CONFIG_TYPE_MIX_PORT,
+} dm_config_type_t;
-typedef struct pa_droid_config_device {
- const pa_droid_config_hw_module *module;
+struct dm_config_port {
+ dm_config_module *module;
+ /* common values */
+
+ dm_config_type_t port_type; /* either mixPort or devicePort */
char *name;
- uint32_t sampling_rates[AUDIO_MAX_SAMPLING_RATES]; /* (uint32_t) -1 -> dynamic */
- audio_channel_mask_t channel_masks; /* 0 -> dynamic */
- audio_format_t formats; /* 0 -> dynamic */
- audio_devices_t devices;
- /* Instead of using audio_output_flags_t and audio_input_flags_t
- * unify the flags as uint32_t so that we can have single struct for both
- * output and input configurations.
- * audio_input_flags_t was introduced in APIs 2 & 3, depending on adaptation,
- * so having input flags as uint32_t is simpler from input implementation
- * point of view as well. */
- uint32_t flags;
- pa_direction_t direction;
+ dm_config_role_t role;
+ dm_list *profiles; /* dm_config_profile* */
+
+ /* devicePort specific values */
+
+ audio_devices_t type;
+ char *address;
- struct pa_droid_config_device *next;
-} pa_droid_config_device;
+ /* mixPort specific values */
-struct pa_droid_config_hw_module {
- const pa_droid_config_audio *config;
+ uint32_t flags; /* audio_output_flag_t or audio_input_flag_t */
+ int max_open_count; /* 0 == not defined */
+ int max_active_count; /* 0 == not defined */
+};
+
+struct dm_config_route {
+ dm_config_type_t type;
+ dm_config_port *sink;
+ dm_list *sources; /* dm_config_port* */
+};
+
+struct dm_config_module {
+ dm_config_device *config;
char *name;
- /* If global config is not defined for module, use root global config. */
- pa_droid_config_global *global_config;
- pa_droid_config_device *outputs;
- pa_droid_config_device *inputs;
+ int version_major;
+ int version_minor;
- struct pa_droid_config_hw_module *next;
+ dm_list *attached_devices; /* dm_config_port* owned by device_ports list below */
+ dm_config_port *default_output_device; /* owned by device_ports list below */
+ dm_list *ports; /* dm_config_port* - for convenience port types are filtered to two lists below: */
+ dm_list *mix_ports; /* dm_config_port* */
+ dm_list *device_ports; /* dm_config_port* */
+ dm_list *routes; /* dm_config_route* */
};
-struct pa_droid_config_audio {
- pa_droid_config_global *global_config;
- pa_droid_config_hw_module *hw_modules;
+struct dm_config_device {
+ dm_list *global_config; /* dm_config_global* */
+ dm_list *modules; /* dm_config_module* */
};
+
/* Config parser */
-pa_droid_config_audio *pa_droid_config_load(pa_modargs *ma);
-pa_droid_config_audio *pa_droid_config_dup(const pa_droid_config_audio *config);
-void pa_droid_config_free(pa_droid_config_audio *config);
-pa_droid_config_audio *pa_parse_droid_audio_config_legacy(const char *filename);
-pa_droid_config_audio *pa_parse_droid_audio_config_xml(const char *filename);
+dm_config_device *dm_config_load(pa_modargs *ma);
+dm_config_device *dm_config_dup(const dm_config_device *config);
+void dm_config_free(dm_config_device *config);
/* autodetect config type from filename and parse */
-pa_droid_config_audio *pa_parse_droid_audio_config(const char *filename);
+dm_config_device *pa_parse_droid_audio_config(const char *filename);
+
+dm_config_module *dm_config_find_module(dm_config_device *config, const char* module_id);
+dm_config_port *dm_config_find_port(dm_config_module *module, const char* name);
+dm_config_port *dm_config_default_output_device(dm_config_module *module);
+dm_config_port *dm_config_find_device_port(dm_config_port *port, audio_devices_t device);
+char *dm_config_escape_string(const char *string);
+
+bool dm_config_port_equal(const dm_config_port *a, const dm_config_port *b);
-const pa_droid_config_hw_module *pa_droid_config_find_module(const pa_droid_config_audio *config, const char* module_id);
-const pa_droid_config_device *pa_droid_config_find_output(const pa_droid_config_hw_module *module, const char* output_name);
-const pa_droid_config_device *pa_droid_config_find_input(const pa_droid_config_hw_module *module, const char* input_name);
-
-pa_droid_config_hw_module *pa_droid_config_hw_module_new(const pa_droid_config_audio *config, const char *name);
-void pa_droid_config_hw_module_free(pa_droid_config_hw_module *hw_module);
-pa_droid_config_device *pa_droid_config_device_new(const pa_droid_config_hw_module *module,
- pa_direction_t direction,
- const char *name);
-void pa_droid_config_device_free(pa_droid_config_device *device);
+dm_config_port *dm_config_find_mix_port(dm_config_module *module, const char *name);
#endif
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-14.2.100.tar.bz2/src/common/include/droid/droid-util.h
^
|
@@ -2,7 +2,7 @@
#define foodroidutilfoo
/*
- * Copyright (C) 2013-2018 Jolla Ltd.
+ * Copyright (C) 2013-2022 Jolla Ltd.
*
* Contact: Juho Hämäläinen <juho.hamalainen@jolla.com>
*
@@ -35,10 +35,6 @@
#include <droid/version.h>
#include <droid/droid-config.h>
-#if defined(QCOM_BSP) && (AUDIO_API_VERSION_MAJ >= 3)
-#define DROID_AUDIO_HAL_USE_VSID
-#endif
-
#define PROP_DROID_DEVICES "droid.devices"
#define PROP_DROID_FLAGS "droid.flags"
#define PROP_DROID_HW_MODULE "droid.hw_module"
@@ -48,8 +44,10 @@
#define PROP_DROID_OUTPUT_LOW_LATENCY "droid.output.low_latency"
#define PROP_DROID_OUTPUT_MEDIA_LATENCY "droid.output.media_latency"
#define PROP_DROID_OUTPUT_OFFLOAD "droid.output.offload"
+#define PROP_DROID_OUTPUT_VOIP "droid.output.voip"
#define PROP_DROID_INPUT_BUILTIN "droid.input.builtin"
#define PROP_DROID_INPUT_EXTERNAL "droid.input.external"
+#define PROP_DROID_INPUT_VOIP "droid.input.voip"
#define EXT_PROP_AUDIO_SOURCE "audio.source"
@@ -60,37 +58,27 @@
typedef struct pa_droid_output_stream pa_droid_output_stream;
typedef struct pa_droid_input_stream pa_droid_input_stream;
typedef struct pa_droid_card_data pa_droid_card_data;
-typedef int (*common_set_parameters_cb_t)(pa_droid_card_data *card_data, const char *str);
-typedef struct pa_droid_quirks pa_droid_quirks;
+typedef struct pa_droid_options pa_droid_options;
-typedef enum pa_droid_hook {
- PA_DROID_HOOK_INPUT_CHANNEL_MAP_CHANGED, /* Call data: pa_droid_stream */
- PA_DROID_HOOK_INPUT_BUFFER_SIZE_CHANGED, /* Call data: pa_droid_stream */
- PA_DROID_HOOK_MAX
-} pa_droid_hook_t;
-
-enum pa_droid_quirk_type {
- QUIRK_INPUT_ATOI,
- QUIRK_SET_PARAMETERS,
- QUIRK_CLOSE_INPUT,
- QUIRK_UNLOAD_NO_CLOSE,
- QUIRK_NO_HW_VOLUME,
- QUIRK_OUTPUT_MAKE_WRITABLE,
- QUIRK_REALCALL,
- QUIRK_UNLOAD_CALL_EXIT,
- QUIRK_OUTPUT_FAST,
- QUIRK_OUTPUT_DEEP_BUFFER,
- QUIRK_AUDIO_CAL_WAIT,
- QUIRK_STANDBY_SET_ROUTE,
- QUIRK_SPEAKER_BEFORE_VOICE,
- QUIRK_SWAP_HEADPHONE_SPEAKER,
- QUIRK_OUTPUT_REMIX_TO_MONO,
- QUIRK_COUNT
+enum pa_droid_option_type {
+ DM_OPTION_INPUT_ATOI,
+ DM_OPTION_CLOSE_INPUT,
+ DM_OPTION_UNLOAD_NO_CLOSE,
+ DM_OPTION_HW_VOLUME,
+ DM_OPTION_REALCALL,
+ DM_OPTION_UNLOAD_CALL_EXIT,
+ DM_OPTION_OUTPUT_FAST,
+ DM_OPTION_OUTPUT_DEEP_BUFFER,
+ DM_OPTION_AUDIO_CAL_WAIT,
+ DM_OPTION_SPEAKER_BEFORE_VOICE,
+ DM_OPTION_OUTPUT_VOIP_RX,
+ DM_OPTION_RECORD_VOICE_16K,
+ DM_OPTION_COUNT
};
-struct pa_droid_quirks {
- bool enabled[QUIRK_COUNT];
+struct pa_droid_options {
+ bool enabled[DM_OPTION_COUNT];
};
struct pa_droid_hw_module {
@@ -99,8 +87,8 @@
pa_core *core;
char *shared_name;
- pa_droid_config_audio *config;
- const pa_droid_config_hw_module *enabled_module;
+ dm_config_device *config;
+ dm_config_module *enabled_module;
pa_mutex *hw_mutex;
pa_mutex *output_mutex;
pa_mutex *input_mutex;
@@ -110,8 +98,8 @@
const char *module_id;
- uint32_t stream_out_id;
- uint32_t stream_in_id;
+ uint32_t stream_id;
+ bool bt_sco_enabled;
pa_idxset *outputs;
pa_idxset *inputs;
@@ -120,14 +108,11 @@
pa_atomic_t active_outputs;
- pa_droid_quirks quirks;
+ pa_droid_options options;
/* Mode and input control */
struct _state {
audio_mode_t mode;
- audio_devices_t input_device;
- audio_source_t audio_source;
- pa_droid_stream *active_input;
} state;
};
@@ -135,8 +120,6 @@
struct audio_stream_out *stream;
pa_sample_spec sample_spec;
pa_channel_map channel_map;
- uint32_t flags;
- uint32_t device;
};
struct pa_droid_input_stream {
@@ -147,6 +130,12 @@
pa_channel_map channel_map;
pa_sample_spec req_sample_spec;
pa_channel_map req_channel_map;
+
+ audio_source_t audio_source;
+ dm_config_port *default_mix_port;
+ dm_config_port *input_port;
+ pa_droid_stream *active_input;
+
uint32_t flags;
uint32_t device;
bool first;
@@ -156,19 +145,21 @@
PA_REFCNT_DECLARE;
pa_droid_hw_module *module;
- const pa_droid_config_device *device_def;
+ dm_config_port *mix_port;
size_t buffer_size;
void *data;
+ audio_io_handle_t io_handle;
+ audio_patch_handle_t audio_patch;
+ const dm_config_port *active_device_port;
+
pa_droid_output_stream *output;
pa_droid_input_stream *input;
};
struct pa_droid_card_data {
void *userdata;
- /* General functions */
char *module_id;
- common_set_parameters_cb_t set_parameters;
};
@@ -178,13 +169,13 @@
typedef struct pa_droid_mapping pa_droid_mapping;
typedef struct pa_droid_port_data {
- audio_devices_t device;
+ dm_config_port *device_port;
} pa_droid_port_data;
typedef struct pa_droid_port {
pa_droid_mapping *mapping;
- audio_devices_t device;
+ dm_config_port *device_port;
char *name;
char *description;
unsigned priority;
@@ -193,9 +184,9 @@
struct pa_droid_mapping {
pa_droid_profile_set *profile_set;
- const pa_droid_config_device *output;
- /* Use all devices in one input */
- const pa_droid_config_device *inputs;
+ dm_config_module *module;
+ dm_config_port *mix_port;
+ dm_list *device_ports;
char *name;
char *description;
@@ -214,7 +205,7 @@
typedef struct pa_droid_profile {
pa_droid_profile_set *profile_set;
- const pa_droid_config_hw_module *module;
+ dm_config_module *module;
char *name;
char *description;
@@ -226,12 +217,13 @@
* hashmaps. */
pa_idxset *output_mappings;
/* Only one input */
+ pa_idxset *input_mappings;
pa_droid_mapping *input_mapping;
} pa_droid_profile;
struct pa_droid_profile_set {
- const pa_droid_config_audio *config;
+ dm_config_device *config;
pa_hashmap *all_ports;
pa_hashmap *output_mappings;
@@ -244,8 +236,8 @@
/* Open hardware module */
/* 'config' can be NULL if it is assumed that hw module with module_id already is open. */
-pa_droid_hw_module *pa_droid_hw_module_get(pa_core *core, const pa_droid_config_audio *config, const char *module_id);
-/* First try to get already open hw module and if none found parse config and quirks from modargs
+pa_droid_hw_module *pa_droid_hw_module_get(pa_core *core, dm_config_device *config, const char *module_id);
+/* First try to get already open hw module and if none found parse config and options from modargs
* and do initial open. */
pa_droid_hw_module *pa_droid_hw_module_get2(pa_core *core, pa_modargs *ma, const char *module_id);
pa_droid_hw_module *pa_droid_hw_module_ref(pa_droid_hw_module *hw);
@@ -255,11 +247,10 @@
bool pa_droid_hw_module_try_lock(pa_droid_hw_module *hw);
void pa_droid_hw_module_unlock(pa_droid_hw_module *hw);
-bool pa_droid_quirk_parse(pa_droid_quirks *quirks, const char *quirks_def);
-void pa_droid_quirk_log(pa_droid_hw_module *hw);
+void pa_droid_options_log(pa_droid_hw_module *hw);
-static inline bool pa_droid_quirk(pa_droid_hw_module *hw, enum pa_droid_quirk_type quirk) {
- return hw && hw->quirks.enabled[quirk];
+static inline bool pa_droid_option(pa_droid_hw_module *hw, enum pa_droid_option_type option) {
+ return hw && hw->options.enabled[option];
}
bool pa_droid_hw_set_mode(pa_droid_hw_module *hw_module, audio_mode_t mode);
@@ -268,14 +259,11 @@
void pa_droid_hw_mic_set_mute(pa_droid_hw_module *hw_module, bool muted);
/* Profiles */
-pa_droid_profile_set *pa_droid_profile_set_new(const pa_droid_config_hw_module *module);
-pa_droid_profile_set *pa_droid_profile_set_default_new(const pa_droid_config_hw_module *module);
+pa_droid_profile_set *pa_droid_profile_set_default_new(dm_config_module *module);
void pa_droid_profile_set_free(pa_droid_profile_set *ps);
-void pa_droid_profile_add_mapping(pa_droid_profile *p, pa_droid_mapping *am);
void pa_droid_profile_free(pa_droid_profile *p);
-pa_droid_mapping *pa_droid_mapping_get(pa_droid_profile_set *ps, const pa_droid_config_device *device);
bool pa_droid_mapping_is_primary(pa_droid_mapping *am);
/* Go through idxset containing pa_droid_mapping objects and if primary output or input
* mapping is found, return pointer to that mapping. */
@@ -303,8 +291,8 @@
pa_droid_stream *pa_droid_open_output_stream(pa_droid_hw_module *module,
const pa_sample_spec *spec,
const pa_channel_map *map,
- const char *module_output_name,
- audio_devices_t devices);
+ dm_config_port *mix_port,
+ dm_config_port *device_port);
/* Set routing to the input or output stream, with following side-effects:
* Output:
@@ -315,13 +303,14 @@
* Input:
* - buffer size or channel count may change
*/
-int pa_droid_stream_set_route(pa_droid_stream *s, audio_devices_t device);
+int pa_droid_stream_set_route(pa_droid_stream *s, dm_config_port *device_port);
/* Open input stream with currently active routing, sample_spec and channel_map
* are requests and may change when opening the stream. */
pa_droid_stream *pa_droid_open_input_stream(pa_droid_hw_module *hw_module,
const pa_sample_spec *default_sample_spec,
- const pa_channel_map *default_channel_map);
+ const pa_channel_map *default_channel_map,
+ const char *mix_port_name);
/* Test if reconfiguring of input stream is needed */
bool pa_droid_stream_reconfigure_input_needed(pa_droid_stream *s,
const pa_sample_spec *requested_sample_spec,
@@ -331,8 +320,8 @@
const pa_sample_spec *requested_sample_spec,
const pa_channel_map *requested_channel_map,
const pa_proplist *proplist);
-bool pa_droid_hw_set_input_device(pa_droid_hw_module *hw_module,
- audio_devices_t device);
+bool pa_droid_hw_set_input_device(pa_droid_stream *s,
+ dm_config_port *device_port);
const pa_sample_spec *pa_droid_stream_sample_spec(pa_droid_stream *stream);
const pa_channel_map *pa_droid_stream_channel_map(pa_droid_stream *stream);
@@ -361,6 +350,8 @@
bool pa_sink_is_droid_sink(pa_sink *sink);
bool pa_source_is_droid_source(pa_source *source);
+pa_modargs *pa_droid_modargs_new(const char *args, const char* const keys[]);
+
/* Misc */
size_t pa_droid_buffer_size_round_up(size_t buffer_size, size_t block_size);
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-14.2.100.tar.bz2/src/common/include/droid/sllist.h
^
|
@@ -2,7 +2,7 @@
#define foosllistfoo
/*
- * Copyright (C) 2018 Jolla Ltd.
+ * Copyright (C) 2018-2022 Jolla Ltd.
*
* Contact: Juho Hämäläinen <juho.hamalainen@jolla.com>
*
@@ -22,6 +22,12 @@
* USA.
*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdbool.h>
+#include <pulse/def.h>
+
#define SLLIST_APPEND(t, head, item) \
do { \
item->next = NULL; \
@@ -46,4 +52,43 @@
i = NULL; \
} while (0)
+typedef struct dm_list_entry dm_list_entry;
+typedef struct dm_list dm_list;
+
+struct dm_list_entry {
+ struct dm_list_entry *next;
+ struct dm_list_entry *prev;
+ void *data;
+};
+
+struct dm_list {
+ struct dm_list_entry *head;
+ struct dm_list_entry *tail;
+ ssize_t size;
+};
+
+dm_list *dm_list_new(void);
+void dm_list_free(dm_list *list, pa_free_cb_t free_cb);
+bool dm_list_remove(dm_list *list, dm_list_entry *entry);
+void dm_list_prepend(dm_list *list, void *data);
+void dm_list_push_back(dm_list *list, void *data);
+dm_list_entry *dm_list_last(dm_list *list);
+void *dm_list_steal_first(dm_list *list);
+ssize_t dm_list_size(dm_list *list);
+void *dm_list_first_data(dm_list *list, void **state);
+void *dm_list_next_data(dm_list *list, void **state);
+/* For example
+ * dm_list *list;
+ * void *state;
+ * my_data *data;
+ * DM_LIST_FOREACH_DATA(data, list, state) {
+ * do_something_with_my(data);
+ * }
+ */
+#define DM_LIST_FOREACH_DATA(i, list, state) \
+ for (i = dm_list_first_data(list, &(state)); state; i = dm_list_next_data(list, &(state)))
+/* Access i->data */
+#define DM_LIST_FOREACH(i, list) \
+ for (i = list->head; i; i = i->next)
+
#endif
|
[-]
[+]
|
Added |
_service:tar_git:pulseaudio-modules-droid-14.2.100.tar.bz2/src/common/include/droid/utils.h
^
|
@@ -0,0 +1,32 @@
+#ifndef foodroidcommonutilsfoo
+#define foodroidcommonutilsfoo
+
+/*
+ * Copyright (C) 2022 Jolla Ltd.
+ *
+ * Contact: Juho Hämäläinen <juho.hamalainen@jolla.com>
+ *
+ * These PulseAudio Modules are 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
+ * version 2.1 of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+void dm_replace_in_place(char **string, const char *a, const char *b);
+bool dm_strcasestr(const char *haystack, const char *needle);
+
+#endif
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-14.2.100.tar.bz2/src/common/include/droid/version.h
^
|
@@ -2,7 +2,7 @@
#define foodroidversionfoo
/*
- * Copyright (C) 2018 Jolla Ltd.
+ * Copyright (C) 2018-2022 Jolla Ltd.
*
* Contact: Juho Hämäläinen <juho.hamalainen@jolla.com>
*
@@ -34,8 +34,8 @@
#error "ANDROID_VERSION_* not defined. Did you get your headers via extract-headers.sh?"
#endif
-/* We currently support API version up-to 3.0 */
-#define DROID_API_VERSION_SUPPORT HARDWARE_DEVICE_API_VERSION(3, 0)
+/* We currently support API version up to 3.1 */
+#define DROID_API_VERSION_SUPPORT HARDWARE_DEVICE_API_VERSION(3, 1)
#if AUDIO_DEVICE_API_VERSION_CURRENT > DROID_API_VERSION_SUPPORT
#warning Compiling against higher audio device API version than currently supported!
@@ -48,4 +48,8 @@
#define AUDIO_API_VERSION_GET_MAJ(x) ((x >> 8) & 0xff)
#define AUDIO_API_VERSION_GET_MIN(x) (x & 0xff)
+#if AUDIO_API_VERSION_MAJ < 3
+#error This module only supports audio API version 3 and upwards.
+#endif
+
#endif
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-14.2.100.tar.bz2/src/common/meson.build
^
|
@@ -1,32 +1,32 @@
libdroid_util_sources = [
- 'config-parser-legacy.c',
'config-parser-xml.c',
+ 'config-parser-xml.h',
'conversion.c',
- 'droid-config.c',
'droid-util.c',
'droid-util-audio.h',
- 'droid-util-41qc.h',
+ 'droid-config.c',
+ 'sllist.c',
+ 'utils.c',
]
libdroid_util_headers = [
'include/droid/conversion.h',
'include/droid/droid-config.h',
'include/droid/droid-util.h',
+ 'include/droid/sllist.h',
+ 'include/droid/utils.h',
'include/droid/version.h',
]
libdroid_util_deps = [
droid_headers_dep,
+ expat_dep,
hybris_dep,
hybris_common_dep,
ltdl_dep,
pulsecore_dep,
]
-if get_option('xml')
- libdroid_util_deps += [expat_dep]
-endif
-
install_headers(libdroid_util_headers, subdir : 'pulsecore/modules/droid')
libdroid_util = library('droid-util',
|
[-]
[+]
|
Added |
_service:tar_git:pulseaudio-modules-droid-14.2.100.tar.bz2/src/common/sllist.c
^
|
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2022 Jolla Ltd.
+ *
+ * Contact: Juho Hämäläinen <juho.hamalainen@jolla.com>
+ *
+ * These PulseAudio Modules are 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
+ * version 2.1 of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <pulse/xmalloc.h>
+#include <pulsecore/macro.h>
+
+#include "droid/sllist.h"
+
+dm_list *dm_list_new(void) {
+ return pa_xnew0(dm_list, 1);
+}
+
+void dm_list_free(dm_list *list, pa_free_cb_t free_cb) {
+ pa_assert(list);
+
+ while (list->head) {
+ void *data = dm_list_steal_first(list);
+
+ if (free_cb)
+ free_cb(data);
+ }
+
+ pa_xfree(list);
+}
+
+bool dm_list_remove(dm_list *list, dm_list_entry *entry) {
+ dm_list_entry *i;
+ bool removed = false;
+
+ for (i = list->head; i; i = i->next) {
+ if (i == entry) {
+ removed = true;
+ if (list->head == entry)
+ list->head = entry->next;
+ if (list->tail == entry)
+ list->tail = entry->prev;
+ if (entry->next)
+ entry->next->prev = entry->prev;
+ if (entry->prev)
+ entry->prev->next = entry->next;
+ pa_xfree(entry);
+ break;
+ }
+ }
+
+ return removed;
+}
+
+void dm_list_prepend(dm_list *list, void *data) {
+ dm_list_entry *entry;
+
+ pa_assert(list);
+
+ entry = pa_xnew0(dm_list_entry, 1);
+ entry->data = data;
+
+ if (!list->tail)
+ list->tail = entry;
+
+ if (list->head) {
+ entry->next = list->head;
+ list->head->prev = entry;
+ }
+
+ list->head = entry;
+ list->size++;
+}
+
+void dm_list_push_back(dm_list *list, void *data) {
+ dm_list_entry *entry;
+
+ pa_assert(list);
+
+ entry = pa_xnew0(dm_list_entry, 1);
+ entry->data = data;
+
+ if (!list->head)
+ list->head = entry;
+
+ if (list->tail) {
+ list->tail->next = entry;
+ entry->prev = list->tail;
+ }
+
+ list->tail = entry;
+ list->size++;
+}
+
+dm_list_entry *dm_list_last(dm_list *list) {
+ pa_assert(list);
+
+ return list->tail;
+}
+
+void *dm_list_steal_first(dm_list *list) {
+ dm_list_entry *entry;
+ void *data = NULL;
+
+ pa_assert(list);
+
+ if (list->head) {
+ data = list->head->data;
+ entry = list->head;
+ if (list->head == list->tail) {
+ list->head = NULL;
+ list->tail = NULL;
+ } else {
+ list->head->next->prev = NULL;
+ list->head = list->head->next;
+ }
+ pa_xfree(entry);
+ list->size--;
+ }
+
+ return data;
+}
+
+ssize_t dm_list_size(dm_list *list) {
+ pa_assert(list);
+
+ return list->size;
+}
+
+/* For iteration */
+
+void *dm_list_first_data(dm_list *list, void **state) {
+ pa_assert(list);
+ pa_assert(state);
+
+ *state = list->head;
+
+ if (list->head)
+ return list->head->data;
+ else
+ return NULL;
+}
+
+void *dm_list_next_data(dm_list *list, void **state) {
+ dm_list_entry *entry;
+
+ pa_assert(list);
+ pa_assert(state);
+
+ entry = *state;
+ *state = entry->next;
+
+ if (entry->next)
+ return entry->next->data;
+ else
+ return NULL;
+}
|
[-]
[+]
|
Added |
_service:tar_git:pulseaudio-modules-droid-14.2.100.tar.bz2/src/common/utils.c
^
|
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 Jolla Ltd.
+ *
+ * Contact: Juho Hämäläinen <juho.hamalainen@jolla.com>
+ *
+ * These PulseAudio Modules are 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
+ * version 2.1 of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <strings.h>
+
+#include <pulsecore/core-util.h>
+#include <pulse/xmalloc.h>
+#include "droid/utils.h"
+
+void dm_replace_in_place(char **string, const char *a, const char *b) {
+ char *tmp;
+
+ pa_assert(*string);
+ pa_assert(a);
+ pa_assert(b);
+
+ tmp = pa_replace(*string, a, b);
+ pa_xfree(*string);
+ *string = tmp;
+}
+
+/* Simple strcasestr replacement. */
+bool dm_strcasestr(const char *haystack, const char *needle) {
+ size_t len_haystack, len_needle;
+
+ len_haystack = strlen(haystack);
+ len_needle = strlen(needle);
+
+ if (len_needle > len_haystack)
+ return false;
+
+ for (size_t i = 0; i < len_haystack; i++) {
+ if (len_needle > len_haystack - i)
+ return false;
+
+ if (strncasecmp(haystack + i, needle, len_needle) == 0)
+ return true;
+ }
+
+ return false;
+}
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-14.2.100.tar.bz2/src/droid/droid-sink.c
^
|
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2018 Jolla Ltd.
+ * Copyright (C) 2013-2022 Jolla Ltd.
*
* Contact: Juho Hämäläinen <juho.hamalainen@jolla.com>
*
@@ -60,6 +60,7 @@
#include "droid-sink.h"
#include <droid/droid-util.h>
#include <droid/conversion.h>
+#include <droid/sllist.h>
struct userdata {
pa_core *core;
@@ -79,19 +80,10 @@
pa_usec_t buffer_time;
pa_usec_t write_time;
pa_usec_t write_threshold;
- audio_devices_t prewrite_devices;
- bool prewrite_always;
- uint32_t prewrite_silence;
- pa_hook_slot *sink_put_hook_slot;
- pa_hook_slot *sink_unlink_hook_slot;
- pa_hook_slot *sink_port_changed_hook_slot;
- pa_sink *primary_stream_sink;
- pa_time_event *refresh_time_event;
-
- audio_devices_t primary_devices;
- audio_devices_t extra_devices;
- pa_hashmap *extra_devices_map;
- bool mix_route;
+
+ dm_config_port *active_device_port;
+ dm_config_port *override_device_port;
+ dm_list *extra_devices_stack;
bool use_hw_volume;
bool use_voice_volume;
@@ -128,95 +120,90 @@
#define DEFAULT_VOICE_CONTROL_PROPERTY_KEY "media.role"
#define DEFAULT_VOICE_CONTROL_PROPERTY_VALUE "phone"
-#define REFRESH_TIME_US ((pa_usec_t) (10 * PA_USEC_PER_SEC))
-
static void parameter_free(droid_parameter_mapping *m);
static void userdata_free(struct userdata *u);
static void set_voice_volume(struct userdata *u, pa_sink_input *i);
static void apply_volume(pa_sink *s);
static pa_sink_input *find_volume_control_sink_input(struct userdata *u);
-static void set_primary_devices(struct userdata *u, audio_devices_t devices) {
- pa_assert(u);
- pa_assert(devices);
+static bool add_extra_devices(struct userdata *u, audio_devices_t device) {
+ dm_list_entry *prev;
+ dm_config_port *device_port;
- u->primary_devices = devices;
-}
+ pa_assert(u);
+ pa_assert(u->extra_devices_stack);
-static bool add_extra_devices(struct userdata *u, audio_devices_t devices) {
- void *value;
- uint32_t count;
- bool need_update = false;
+ if (!(device_port = dm_config_find_device_port(u->active_device_port, device))) {
+ pa_log("Unknown device port %u", device);
+ return false;
+ }
- pa_assert(u);
- pa_assert(u->extra_devices_map);
- pa_assert(devices);
+ prev = dm_list_last(u->extra_devices_stack);
- if ((value = pa_hashmap_get(u->extra_devices_map, PA_UINT_TO_PTR(devices)))) {
- count = PA_PTR_TO_UINT(value);
- count++;
- pa_hashmap_remove(u->extra_devices_map, PA_UINT_TO_PTR(devices));
- pa_hashmap_put(u->extra_devices_map, PA_UINT_TO_PTR(devices), PA_UINT_TO_PTR(count));
+ dm_list_push_back(u->extra_devices_stack, device_port);
- /* added extra device already exists in hashmap, so no need to update route. */
- need_update = false;
- } else {
- pa_hashmap_put(u->extra_devices_map, PA_UINT_TO_PTR(devices), PA_UINT_TO_PTR(1));
- u->extra_devices |= devices;
- need_update = true;
+ if (prev) {
+ dm_config_port *last_port = prev->data;
+ if (dm_config_port_equal(last_port, device_port))
+ return false;
}
- return need_update;
+ u->override_device_port = device_port;
+
+ return true;
}
-static bool remove_extra_devices(struct userdata *u, audio_devices_t devices) {
- void *value;
- uint32_t count;
+static bool remove_extra_devices(struct userdata *u, audio_devices_t device) {
+ dm_config_port *device_port;
+ dm_list_entry *remove = NULL, *i = NULL;
bool need_update = false;
pa_assert(u);
- pa_assert(u->extra_devices_map);
- pa_assert(devices);
+ pa_assert(u->extra_devices_stack);
- if ((value = pa_hashmap_get(u->extra_devices_map, PA_UINT_TO_PTR(devices)))) {
- pa_hashmap_remove(u->extra_devices_map, PA_UINT_TO_PTR(devices));
- count = PA_PTR_TO_UINT(value);
- count--;
- if (count == 0) {
- u->extra_devices &= ~devices;
- need_update = true;
- } else {
- /* added extra devices still exists in hashmap, so no need to update route. */
- pa_hashmap_put(u->extra_devices_map, PA_UINT_TO_PTR(devices), PA_UINT_TO_PTR(count));
- need_update = false;
+ if (!(device_port = dm_config_find_device_port(u->active_device_port, device))) {
+ pa_log("Unknown device port %u", device);
+ return false;
+ }
+
+ DM_LIST_FOREACH(i, u->extra_devices_stack) {
+ if (dm_config_port_equal(i->data, device_port)) {
+ remove = i;
+ break;
}
}
+ if (remove && dm_list_last(u->extra_devices_stack) == remove)
+ need_update = true;
+
+ if (remove)
+ dm_list_remove(u->extra_devices_stack, remove);
+
return need_update;
}
static void clear_extra_devices(struct userdata *u) {
pa_assert(u);
- pa_assert(u->extra_devices_map);
+ pa_assert(u->extra_devices_stack);
- pa_hashmap_remove_all(u->extra_devices_map);
- u->extra_devices = 0;
+ while (dm_list_steal_first(u->extra_devices_stack));
+ u->override_device_port = NULL;
}
/* Called from main context during voice calls, and from IO context during media operation. */
static void do_routing(struct userdata *u) {
- audio_devices_t routing;
+ dm_config_port *routing = NULL;
pa_assert(u);
pa_assert(u->stream);
- if (u->use_voice_volume && u->extra_devices)
+ if (u->use_voice_volume && u->override_device_port)
clear_extra_devices(u);
- if (!u->mix_route && u->extra_devices)
- routing = u->extra_devices;
+ if (u->override_device_port)
+ routing = u->override_device_port;
else
- routing = u->primary_devices | u->extra_devices;
+ routing = u->active_device_port;
pa_droid_stream_set_route(u->stream, routing);
}
@@ -247,30 +234,6 @@
return true;
}
-static int thread_write_silence(struct userdata *u) {
- const void *p;
- ssize_t wrote;
-
- /* Drop our rendered audio and write silence to HAL. */
- pa_memblockq_drop(u->memblockq, u->buffer_size);
- u->write_time = pa_rtclock_now();
-
- /* We should be able to write everything in one go as long as memblock size
- * is multiples of buffer_size. Even if we don't write whole buffer size
- * here it's okay, as long as mute time isn't configured too strictly. */
-
- p = pa_memblock_acquire_chunk(&u->silence);
- wrote = pa_droid_stream_write(u->stream, p, u->silence.length);
- pa_memblock_release(u->silence.memblock);
-
- u->write_time = pa_rtclock_now() - u->write_time;
-
- if (wrote < 0)
- return -1;
-
- return 0;
-}
-
static int thread_write(struct userdata *u) {
pa_memchunk c;
const void *p;
@@ -284,35 +247,6 @@
u->write_time = pa_rtclock_now();
for (;;) {
- if (pa_droid_quirk(u->hw_module, QUIRK_OUTPUT_MAKE_WRITABLE) ||
- pa_droid_quirk(u->hw_module, QUIRK_OUTPUT_REMIX_TO_MONO)) {
- pa_memchunk_make_writable(&c, c.length);
-
- /* Naive implementation, only works for little-endian 16 bit samples
- * and causes volume to drop by 6dB.
- * Do mixing for speaker, headset and headphone only. */
- if (pa_droid_quirk(u->hw_module, QUIRK_OUTPUT_REMIX_TO_MONO) &&
- u->primary_devices & (AUDIO_DEVICE_OUT_SPEAKER |
- AUDIO_DEVICE_OUT_WIRED_HEADSET |
- AUDIO_DEVICE_OUT_WIRED_HEADPHONE)) {
- size_t i;
- void *dst;
-
- dst = pa_memblock_acquire_chunk(&c);
-
- for (i = 0; i < c.length; i += 4) {
- int16_t *left = dst;
- int16_t *right = dst + 2;
-
- *left = *left / 2 + *right / 2;
- *right = *left;
- dst += 4;
- }
-
- pa_memblock_release(c.memblock);
- }
- }
-
p = pa_memblock_acquire_chunk(&c);
wrote = pa_droid_stream_write(u->stream, p, c.length);
pa_memblock_release(c.memblock);
@@ -483,8 +417,6 @@
/* Called from IO context */
static int unsuspend(struct userdata *u) {
- uint32_t i;
-
pa_assert(u);
pa_assert(u->sink);
@@ -495,13 +427,6 @@
apply_volume(u->sink);
- if (u->prewrite_silence &&
- (u->primary_devices | u->extra_devices) & u->prewrite_devices &&
- (u->prewrite_always || pa_droid_output_stream_any_active(u->stream) == 0)) {
- for (i = 0; i < u->prewrite_silence; i++)
- thread_write_silence(u);
- }
-
pa_droid_stream_suspend(u->stream, false);
return 0;
@@ -577,7 +502,7 @@
data = PA_DEVICE_PORT_DATA(p);
- if (!data->device) {
+ if (!data->device_port) {
/* If there is no device defined, just return 0 to say everything is ok.
* Then next port change can be whatever sink port, even the one enabled
* before parking. */
@@ -585,9 +510,9 @@
return 0;
}
- pa_log_debug("Sink set port %u", data->device);
+ pa_log_debug("Sink set port %#010x (%s)", data->device_port->type, data->device_port->name);
- set_primary_devices(u, data->device);
+ u->active_device_port = data->device_port;
do_routing(u);
return 0;
@@ -662,9 +587,9 @@
u->use_hw_volume = (ret == 0);
if (u->use_hw_volume &&
#if defined(HAVE_ENUM_AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)
- !(u->stream->output->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
+ !(u->stream->mix_port->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
#endif
- pa_droid_quirk(u->hw_module, QUIRK_NO_HW_VOLUME)) {
+ !pa_droid_option(u->hw_module, DM_OPTION_HW_VOLUME)) {
pa_log_info("Forcing software volume control with %s", u->sink->name);
u->use_hw_volume = false;
} else {
@@ -678,7 +603,7 @@
}
}
-static void set_sink_name(pa_modargs *ma, pa_sink_new_data *data, const char *module_id) {
+static void set_sink_name(pa_modargs *ma, pa_sink_new_data *data, pa_droid_mapping *am, const char *name) {
const char *tmp;
pa_assert(ma);
@@ -689,13 +614,14 @@
data->namereg_fail = true;
pa_proplist_sets(data->proplist, PA_PROP_DEVICE_DESCRIPTION, "Droid sink");
} else {
- char *tt;
- pa_assert(module_id);
- tt = pa_sprintf_malloc("sink.%s", module_id);
- pa_sink_new_data_set_name(data, tt);
- pa_xfree(tt);
+ char *full_name;
+ pa_assert(name);
+ pa_assert(am);
+ full_name = pa_sprintf_malloc("sink.%s", name);
+ pa_sink_new_data_set_name(data, full_name);
+ pa_xfree(full_name);
data->namereg_fail = false;
- pa_proplist_setf(data->proplist, PA_PROP_DEVICE_DESCRIPTION, "Droid sink %s", module_id);
+ pa_proplist_setf(data->proplist, PA_PROP_DEVICE_DESCRIPTION, "Droid sink %s", am->name);
}
}
@@ -815,7 +741,7 @@
if (parse_device_list(dev_str, &devices) && devices) {
- pa_log_debug("Add extra route %s (%u).", dev_str, devices);
+ pa_log_debug("%s: Add extra route %s (%u).", u->sink->name, dev_str, devices);
/* if this device was not routed to previously post routing change */
if (add_extra_devices(u, devices))
@@ -911,180 +837,6 @@
return PA_HOOK_OK;
}
-static pa_hook_result_t sink_port_changed_hook_cb(pa_core *c, pa_sink *sink, struct userdata *u) {
- pa_device_port *port;
-
- pa_assert(c);
- pa_assert(sink);
- pa_assert(u);
-
- if (sink != u->primary_stream_sink)
- return PA_HOOK_OK;
-
- port = sink->active_port;
- pa_log_info("Set slave sink port to %s", port->name);
- pa_sink_set_port(u->sink, port->name, false);
-
- return PA_HOOK_OK;
-}
-
-static void unset_primary_stream_sink(struct userdata *u) {
- pa_assert(u);
- pa_assert(u->primary_stream_sink);
- pa_assert(u->sink_port_changed_hook_slot);
-
- pa_hook_slot_free(u->sink_port_changed_hook_slot);
- u->sink_port_changed_hook_slot = NULL;
- u->primary_stream_sink = NULL;
-}
-
-static pa_hook_result_t sink_unlink_hook_cb(pa_core *c, pa_sink *sink, struct userdata *u) {
- pa_assert(c);
- pa_assert(sink);
- pa_assert(u);
-
- if (sink != u->primary_stream_sink)
- return PA_HOOK_OK;
-
- pa_log_info("Primary stream sink disappeared.");
- unset_primary_stream_sink(u);
-
- return PA_HOOK_OK;
-}
-
-static pa_hook_result_t sink_put_hook_cb(pa_core *c, pa_sink *sink, struct userdata *u) {
- struct userdata *sink_u;
-
- pa_assert(c);
- pa_assert(sink);
- pa_assert(u);
-
- if (!pa_sink_is_droid_sink(sink))
- return PA_HOOK_OK;
-
- sink_u = sink->userdata;
-
- if (!pa_droid_stream_is_primary(sink_u->stream))
- return PA_HOOK_OK;
-
- u->primary_stream_sink = sink;
-
- pa_assert(!u->sink_port_changed_hook_slot);
- u->sink_port_changed_hook_slot = pa_hook_connect(&u->core->hooks[PA_CORE_HOOK_SINK_PORT_CHANGED], PA_HOOK_NORMAL,
- (pa_hook_cb_t) sink_port_changed_hook_cb, u);
-
- pa_log_info("Primary stream sink setup for slave.");
-
- sink_port_changed_hook_cb(c, sink, u);
-
- return PA_HOOK_OK;
-}
-
-static void setup_track_primary(struct userdata *u) {
- pa_sink *sink;
- struct userdata *sink_u;
- uint32_t idx;
-
- pa_assert(u);
-
- u->sink_put_hook_slot = pa_hook_connect(&u->core->hooks[PA_CORE_HOOK_SINK_PUT], PA_HOOK_NORMAL,
- (pa_hook_cb_t) sink_put_hook_cb, u);
- u->sink_unlink_hook_slot = pa_hook_connect(&u->core->hooks[PA_CORE_HOOK_SINK_UNLINK], PA_HOOK_NORMAL,
- (pa_hook_cb_t) sink_unlink_hook_cb, u);
-
- PA_IDXSET_FOREACH(sink, u->core->sinks, idx) {
- if (pa_sink_is_droid_sink(sink)) {
- sink_u = sink->userdata;
- if (pa_droid_stream_is_primary(sink_u->stream)) {
- sink_put_hook_cb(u->core, sink, u);
- break;
- }
- }
- }
-}
-
-static bool parse_prewrite_on_resume(struct userdata *u, const char *prewrite_resume, const char *name) {
- const char *state = NULL;
- char *entry = NULL;
- char *devices, *stream, *value;
- uint32_t devices_len, devices_index, value_index, entry_len;
- uint32_t b;
-
- pa_assert(u);
- pa_assert(prewrite_resume);
- pa_assert(name);
-
- /* Argument is string of for example "deep_buffer=AUDIO_DEVICE_OUT_SPEAKER:1,primary=FOO:5" */
-
- while ((entry = pa_split(prewrite_resume, ",", &state))) {
- audio_devices_t prewrite_devices = 0;
- bool prewrite_always = false;
- char *tmp;
-
- entry_len = strlen(entry);
- devices_index = strcspn(entry, "=");
-
- if (devices_index == 0 || devices_index >= entry_len - 1)
- goto error;
-
- entry[devices_index] = '\0';
- devices = entry + devices_index + 1;
- stream = entry;
-
- devices_len = strlen(devices);
- value_index = strcspn(devices, ":");
-
- if (value_index == 0 || value_index >= devices_len - 1)
- goto error;
-
- devices[value_index] = '\0';
- value = devices + value_index + 1;
-
- if (!parse_device_list(devices, &prewrite_devices))
- goto error;
-
- if ((tmp = strstr(value, "/always"))) {
- prewrite_always = true;
- *tmp = '\0';
- }
-
- if (strlen(value) == 0 || pa_atou(value, &b) < 0)
- goto error;
-
- if (pa_streq(stream, name)) {
- pa_log_info("Using requested prewrite%s size for %s: %zu (%u * %zu).",
- prewrite_always ? "_always" : "",
- name, u->buffer_size * b, b, u->buffer_size);
- u->prewrite_devices = prewrite_devices;
- u->prewrite_always = prewrite_always;
- u->prewrite_silence = b;
- pa_xfree(entry);
- return true;
- }
-
- pa_xfree(entry);
- }
-
-return true;
-
-error:
- pa_xfree(entry);
- return false;
-}
-
-static void refresh_time_cb(pa_mainloop_api *a, pa_time_event *e, const struct timeval *t, void *userdata) {
- struct userdata *u = userdata;
-
- pa_assert(u->refresh_time_event);
- pa_assert(u->refresh_time_event == e);
-
- u->core->mainloop->time_free(u->refresh_time_event);
- u->refresh_time_event = NULL;
-
- /* Re-apply whatever route currently is active to HAL. */
- do_routing(u);
-}
-
pa_sink *pa_droid_sink_new(pa_module *m,
pa_modargs *ma,
const char *driver,
@@ -1094,29 +846,27 @@
pa_card *card) {
struct userdata *u = NULL;
- const pa_droid_config_device *output = NULL;
+ dm_config_port *mix_port = NULL;
+ dm_config_port *device_port = NULL;
bool deferred_volume = false;
char *thread_name = NULL;
pa_sink_new_data data;
const char *module_id = NULL;
- const char *tmp;
char *list = NULL;
uint32_t alternate_sample_rate;
const char *format;
- audio_devices_t dev_out;
pa_sample_spec sample_spec;
pa_channel_map channel_map;
bool namereg_fail = false;
pa_usec_t latency;
uint32_t sink_buffer = 0;
- const char *prewrite_resume = NULL;
- bool mix_route = false;
+ char *sink_name = NULL;
pa_assert(m);
pa_assert(ma);
pa_assert(driver);
- pa_log_info("Create new droid-sink-jb2q");
+ pa_log_info("Create new droid-sink");
deferred_volume = m->core->deferred_volume;
if (pa_modargs_get_value_boolean(ma, "deferred_volume", &deferred_volume) < 0) {
@@ -1125,8 +875,8 @@
}
if (card && am) {
- output = am->output;
- module_id = output->module->name;
+ mix_port = am->mix_port;
+ module_id = mix_port->name;
} else
module_id = pa_modargs_get_value(ma, "module_id", DEFAULT_MODULE_ID);
@@ -1135,18 +885,22 @@
/* First parse both sample spec and channel map, then see if sink_* override some
* of the values. */
- if (pa_modargs_get_sample_spec_and_channel_map(ma, &sample_spec, &channel_map, PA_CHANNEL_MAP_AIFF) < 0) {
- pa_log("Failed to parse sink sample specification and channel map.");
+
+ if (pa_modargs_get_sample_spec(ma, &sample_spec) < 0) {
+ pa_log("Failed to parse sink sample specification.");
goto fail;
}
- if (pa_modargs_get_value(ma, "sink_channel_map", NULL)) {
- if (pa_modargs_get_channel_map(ma, "sink_channel_map", &channel_map) < 0) {
- pa_log("Failed to parse sink channel map.");
- goto fail;
- }
+ if (pa_modargs_get_channel_map(ma, NULL, &channel_map) < 0) {
+ pa_log("Failed to parse sink channel map.");
+ goto fail;
+ }
+
+ /* Possible overrides. */
- sample_spec.channels = channel_map.channels;
+ if (pa_modargs_get_channel_map(ma, "sink_channel_map", &channel_map) < 0) {
+ pa_log("Failed to parse sink channel map.");
+ goto fail;
}
if ((format = pa_modargs_get_value(ma, "sink_format", NULL))) {
@@ -1156,6 +910,11 @@
}
}
+ if (pa_modargs_get_value_u32(ma, "rate", &sample_spec.rate) < 0) {
+ pa_log("Failed to parse sink samplerate");
+ goto fail;
+ }
+
if (pa_modargs_get_value_u32(ma, "sink_rate", &sample_spec.rate) < 0) {
pa_log("Failed to parse sink samplerate");
goto fail;
@@ -1177,11 +936,6 @@
goto fail;
}
- if (pa_modargs_get_value_boolean(ma, "sink_mix_route", &mix_route) < 0) {
- pa_log("Failed to parse sink_mix_route, expects boolean argument.");
- goto fail;
- }
-
u = pa_xnew0(struct userdata, 1);
u->core = m->core;
u->module = m;
@@ -1193,8 +947,7 @@
NULL, (pa_free_cb_t) parameter_free);
u->voice_property_key = pa_xstrdup(pa_modargs_get_value(ma, "voice_property_key", DEFAULT_VOICE_CONTROL_PROPERTY_KEY));
u->voice_property_value = pa_xstrdup(pa_modargs_get_value(ma, "voice_property_value", DEFAULT_VOICE_CONTROL_PROPERTY_VALUE));
- u->extra_devices_map = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
- u->mix_route = mix_route;
+ u->extra_devices_stack = dm_list_new();
if (card_data) {
u->card_data = card_data;
@@ -1208,34 +961,25 @@
goto fail;
}
- if (!(output = pa_droid_config_find_output(u->hw_module->enabled_module, output_name))) {
- pa_log("Could not find output %s from module %s.", output_name, u->hw_module->enabled_module->name);
- goto fail;
- }
-
/* Sink wasn't created from inside card module, so we'll need to open
* hw module ourself. */
if (!(u->hw_module = pa_droid_hw_module_get2(u->core, ma, module_id)))
goto fail;
- }
-
- /* Default routing */
- dev_out = output->module->global_config ? output->module->global_config->default_output_device
- : u->hw_module->config->global_config->default_output_device;
-
- if ((tmp = pa_modargs_get_value(ma, "output_devices", NULL))) {
- audio_devices_t tmp_dev;
-
- if (parse_device_list(tmp, &tmp_dev) && tmp_dev)
- dev_out = tmp_dev;
- pa_log_debug("Set initial devices %s", tmp);
+ if (!(mix_port = dm_config_find_port(u->hw_module->enabled_module, output_name)) ||
+ mix_port->port_type != DM_CONFIG_TYPE_MIX_PORT) {
+ pa_log("Could not find output %s from module %s.", output_name, u->hw_module->enabled_module->name);
+ goto fail;
+ }
}
- flags = output->flags;
+ pa_assert(mix_port);
- u->stream = pa_droid_open_output_stream(u->hw_module, &sample_spec, &channel_map, output->name, dev_out);
+ /* Start with default output device */
+ device_port = dm_config_default_output_device(mix_port->module);
+
+ u->stream = pa_droid_open_output_stream(u->hw_module, &sample_spec, &channel_map, mix_port, device_port);
if (!u->stream) {
pa_log("Failed to open output stream.");
@@ -1249,25 +993,19 @@
} else
pa_log_info("Using buffer size %zu.", u->buffer_size);
- if ((prewrite_resume = pa_modargs_get_value(ma, "prewrite_on_resume", NULL))) {
- if (!parse_prewrite_on_resume(u, prewrite_resume, output->name)) {
- pa_log("Failed to parse prewrite_on_resume (%s)", prewrite_resume);
- goto fail;
- }
- }
-
u->buffer_time = pa_bytes_to_usec(u->buffer_size, &u->stream->output->sample_spec);
u->write_threshold = u->buffer_time - u->buffer_time / 6;
pa_silence_memchunk_get(&u->core->silence_cache, u->core->mempool, &u->silence, &u->stream->output->sample_spec, u->buffer_size);
- u->memblockq = pa_memblockq_new("droid-sink-jb2q", 0, u->buffer_size, u->buffer_size, &u->stream->output->sample_spec, 1, 0, 0, &u->silence);
+ u->memblockq = pa_memblockq_new("droid-sink", 0, u->buffer_size, u->buffer_size, &u->stream->output->sample_spec, 1, 0, 0, &u->silence);
pa_sink_new_data_init(&data);
data.driver = driver;
data.module = m;
data.card = card;
- set_sink_name(ma, &data, output->name);
+ sink_name = dm_config_escape_string(module_id);
+ set_sink_name(ma, &data, am, sink_name);
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_CLASS, "sound");
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_API, PROP_DROID_API_STRING);
@@ -1287,15 +1025,6 @@
pa_sink_new_data_set_channel_map(&data, &u->stream->output->channel_map);
pa_sink_new_data_set_alternate_sample_rate(&data, alternate_sample_rate);
- /*
- if (!(list = pa_list_string_output_device(dev_out))) {
- pa_log("Couldn't format device list string.");
- goto fail;
- }
- pa_proplist_sets(data.proplist, PROP_DROID_DEVICES, list);
- pa_xfree(list);
- */
-
if (flags) {
if (!(list = pa_list_string_flags(flags))) {
pa_log("Couldn't format flag list string.");
@@ -1323,15 +1052,13 @@
u->sink->parent.process_msg = sink_process_msg;
u->sink->set_state_in_io_thread = sink_set_state_in_io_thread_cb;
- u->sink->set_port = sink_set_port_cb;
-
pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
pa_sink_set_rtpoll(u->sink, u->rtpoll);
/* Rewind internal memblockq */
pa_sink_set_max_rewind(u->sink, 0);
- thread_name = pa_sprintf_malloc("droid-sink-jb2q-%s", output->name);
+ thread_name = pa_sprintf_malloc("droid-sink-%s", sink_name);
if (!(u->thread = pa_thread_new(thread_name, thread_func, u))) {
pa_log("Failed to create thread.");
goto fail;
@@ -1348,31 +1075,34 @@
if (u->sink->active_port)
sink_set_port_cb(u->sink, u->sink->active_port);
- /* Hooks to track appearance and disappearance of sink-inputs. */
- /* Hook a little bit earlier and later than module-role-ducking. */
- u->sink_input_put_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], PA_HOOK_LATE+10,
- (pa_hook_cb_t) sink_input_put_hook_cb, u);
- u->sink_input_unlink_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK], PA_HOOK_EARLY-10,
- (pa_hook_cb_t) sink_input_unlink_hook_cb, u);
- u->sink_proplist_changed_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_PROPLIST_CHANGED], PA_HOOK_EARLY,
- (pa_hook_cb_t) sink_proplist_changed_hook_cb, u);
+ if (pa_droid_stream_is_primary(u->stream)) {
+ /* Hooks to track appearance and disappearance of sink-inputs.
+ * Hook a little bit earlier and later than module-role-ducking.
+ * Used only in primary sink. */
+ u->sink_input_put_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], PA_HOOK_LATE+10,
+ (pa_hook_cb_t) sink_input_put_hook_cb, u);
+ u->sink_input_unlink_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK], PA_HOOK_EARLY-10,
+ (pa_hook_cb_t) sink_input_unlink_hook_cb, u);
+ u->sink_proplist_changed_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_PROPLIST_CHANGED], PA_HOOK_EARLY,
+ (pa_hook_cb_t) sink_proplist_changed_hook_cb, u);
- update_volumes(u);
+ /* Port changes are done only in primary sink. */
+ u->sink->set_port = sink_set_port_cb;
+ }
- if (!pa_droid_stream_is_primary(u->stream))
- setup_track_primary(u);
+ update_volumes(u);
pa_droid_stream_suspend(u->stream, false);
pa_droid_stream_set_data(u->stream, u->sink);
pa_sink_put(u->sink);
- if (pa_droid_quirk(u->hw_module, QUIRK_SWAP_HEADPHONE_SPEAKER) && pa_droid_stream_is_primary(u->stream))
- u->refresh_time_event = pa_core_rttime_new(u->core, pa_rtclock_now() + REFRESH_TIME_US, refresh_time_cb, u);
+ pa_xfree(sink_name);
return u->sink;
fail:
pa_xfree(thread_name);
+ pa_xfree(sink_name);
if (u)
userdata_free(u);
@@ -1399,21 +1129,6 @@
static void userdata_free(struct userdata *u) {
- if (u->refresh_time_event)
- u->core->mainloop->time_free(u->refresh_time_event);
-
- if (u->primary_stream_sink)
- unset_primary_stream_sink(u);
-
- if (u->sink_put_hook_slot)
- pa_hook_slot_free(u->sink_put_hook_slot);
-
- if (u->sink_unlink_hook_slot)
- pa_hook_slot_free(u->sink_unlink_hook_slot);
-
- if (u->sink_port_changed_hook_slot)
- pa_hook_slot_free(u->sink_port_changed_hook_slot);
-
if (u->sink)
pa_sink_unlink(u->sink);
@@ -1459,8 +1174,8 @@
if (u->voice_property_value)
pa_xfree(u->voice_property_value);
- if (u->extra_devices_map)
- pa_hashmap_free(u->extra_devices_map);
+ if (u->extra_devices_stack)
+ dm_list_free(u->extra_devices_stack, NULL);
pa_xfree(u);
}
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-14.2.100.tar.bz2/src/droid/droid-source.c
^
|
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2018 Jolla Ltd.
+ * Copyright (C) 2013-2022 Jolla Ltd.
*
* Contact: Juho Hämäläinen <juho.hamalainen@jolla.com>
*
@@ -69,7 +69,6 @@
pa_rtpoll *rtpoll;
pa_memchunk memchunk;
- audio_devices_t primary_devices;
size_t source_buffer_size;
size_t buffer_size;
@@ -95,60 +94,13 @@
const pa_sample_spec *reconfigure_sample_spec,
const pa_channel_map *reconfigure_channel_map,
const pa_proplist *proplist,
- audio_devices_t update_device);
+ dm_config_port *update_device_port);
/* Our droid source may be left in a state of not having an input stream
* if reconfiguration fails and fallback to previously active values fails
* as well. In this case just avoid using the stream but don't die. */
#define assert_stream(x, action) if (!x) do { pa_log_warn("Assert " #x " failed."); action; } while(0)
-static int do_routing(struct userdata *u, audio_devices_t devices) {
- int ret;
- audio_devices_t old_device;
-
- pa_assert(u);
- assert_stream(u->stream, return 0);
-
- if (u->primary_devices == devices)
- pa_log_debug("Refresh active device routing.");
-
- old_device = u->primary_devices;
- u->primary_devices = devices;
-
- ret = pa_droid_stream_set_route(u->stream, devices);
-
- if (ret < 0)
- u->primary_devices = old_device;
-
- return ret;
-}
-
-static bool parse_device_list(const char *str, audio_devices_t *dst) {
- pa_assert(str);
- pa_assert(dst);
-
- char *dev;
- const char *state = NULL;
-
- *dst = 0;
-
- while ((dev = pa_split(str, "|", &state))) {
- audio_devices_t d;
-
- if (!pa_string_convert_input_device_str_to_num(dev, &d)) {
- pa_log_warn("Unknown device %s", dev);
- pa_xfree(dev);
- return false;
- }
-
- *dst |= d;
-
- pa_xfree(dev);
- }
-
- return true;
-}
-
static int thread_read(struct userdata *u) {
void *p;
ssize_t readd;
@@ -335,7 +287,7 @@
data = PA_DEVICE_PORT_DATA(p);
- if (!data->device) {
+ if (!data->device_port) {
/* If there is no device defined, just return 0 to say everything is ok.
* Then next port change can be whatever source port, even the one enabled
* before parking. */
@@ -343,12 +295,12 @@
return 0;
}
- pa_log_debug("Source set port %#010x", data->device);
+ pa_log_debug("Source set port %#010x (%s)", data->device_port->type, data->device_port->name);
if (!PA_SOURCE_IS_OPENED(u->source->state))
- do_routing(u, data->device);
+ pa_droid_stream_set_route(u->stream, data->device_port);
else
- source_reconfigure(u, NULL, NULL, NULL, data->device);
+ source_reconfigure(u, NULL, NULL, NULL, data->device_port);
return 0;
}
@@ -431,7 +383,7 @@
const pa_sample_spec *reconfigure_sample_spec,
const pa_channel_map *reconfigure_channel_map,
const pa_proplist *proplist,
- audio_devices_t update_device) {
+ dm_config_port *update_device_port) {
pa_channel_map old_channel_map;
pa_sample_spec old_sample_spec;
pa_channel_map new_channel_map;
@@ -452,8 +404,8 @@
new_channel_map = reconfigure_channel_map ? *reconfigure_channel_map : old_channel_map;
new_sample_spec = reconfigure_sample_spec ? *reconfigure_sample_spec : old_sample_spec;
- if (update_device)
- do_routing(u, update_device);
+ if (update_device_port)
+ pa_droid_stream_set_route(u->stream, update_device_port);
if (pa_droid_stream_reconfigure_input(u->stream, &new_sample_spec, &new_channel_map, proplist))
pa_log_info("Source reconfigured.");
@@ -505,10 +457,10 @@
pa_droid_stream_sample_spec(primary_output),
pa_droid_stream_channel_map(primary_output),
new_data->proplist,
- 0);
+ NULL);
} else
- source_reconfigure(u, &new_data->sample_spec, &new_data->channel_map, new_data->proplist, 0);
+ source_reconfigure(u, &new_data->sample_spec, &new_data->channel_map, new_data->proplist, NULL);
return PA_HOOK_OK;
}
@@ -533,7 +485,7 @@
&so->channel_map,
so->proplist)) {
pa_log_info("Source-output disconnected and our source needs to be reconfigured.");
- source_reconfigure(u, &so->sample_spec, &so->channel_map, so->proplist, 0);
+ source_reconfigure(u, &so->sample_spec, &so->channel_map, so->proplist, NULL);
}
}
@@ -547,7 +499,6 @@
pa_source *pa_droid_source_new(pa_module *m,
pa_modargs *ma,
const char *driver,
- audio_devices_t device,
pa_droid_card_data *card_data,
pa_droid_mapping *am,
pa_card *card) {
@@ -556,9 +507,7 @@
char *thread_name = NULL;
pa_source_new_data data;
const char *module_id = NULL;
- const char *tmp;
uint32_t alternate_sample_rate;
- audio_devices_t dev_in;
pa_sample_spec sample_spec;
pa_channel_map channel_map;
const char *format;
@@ -569,11 +518,11 @@
pa_assert(ma);
pa_assert(driver);
- pa_log_info("Create new droid-source-jb2q");
+ pa_log_info("Create new droid-source");
/* When running under card use hw module name for source by default. */
if (am)
- module_id = am->inputs->module->name;
+ module_id = am->mix_port->name;
else
module_id = pa_modargs_get_value(ma, "module_id", DEFAULT_MODULE_ID);
@@ -644,28 +593,7 @@
goto fail;
}
- /* Default routing */
- if (device)
- dev_in = device;
- else {
- /* FIXME So while setting routing through stream with HALv2 API fails, creation of stream
- * requires HALv2 style device to work properly. So until that oddity is resolved we always
- * set AUDIO_DEVICE_IN_BUILTIN_MIC as initial device here. */
- pa_log_info("FIXME: Setting AUDIO_DEVICE_IN_BUILTIN_MIC as initial device.");
- pa_assert_se(pa_string_convert_input_device_str_to_num("AUDIO_DEVICE_IN_BUILTIN_MIC", &dev_in));
-
- if ((tmp = pa_modargs_get_value(ma, "input_devices", NULL))) {
- audio_devices_t tmp_dev;
-
- if (parse_device_list(tmp, &tmp_dev) && tmp_dev)
- dev_in = tmp_dev;
-
- pa_log_debug("Set initial devices %s", tmp);
- }
- }
-
- pa_droid_hw_set_input_device(u->hw_module, dev_in);
- u->stream = pa_droid_open_input_stream(u->hw_module, &sample_spec, &channel_map);
+ u->stream = pa_droid_open_input_stream(u->hw_module, &sample_spec, &channel_map, am->mix_port->name);
if (!u->stream) {
pa_log("Failed to open input stream.");
@@ -731,7 +659,7 @@
/* Disable rewind for droid source */
pa_source_set_max_rewind(u->source, 0);
- thread_name = pa_sprintf_malloc("droid-source-jb2q-%s", module_id);
+ thread_name = pa_sprintf_malloc("droid-source-%s", module_id);
if (!(u->thread = pa_thread_new(thread_name, thread_func, u))) {
pa_log("Failed to create thread.");
goto fail;
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-14.2.100.tar.bz2/src/droid/droid-source.h
^
|
@@ -2,7 +2,7 @@
#define foodroidsourcefoo
/*
- * Copyright (C) 2013-2018 Jolla Ltd.
+ * Copyright (C) 2013-2022 Jolla Ltd.
*
* Contact: Juho Hämäläinen <juho.hamalainen@jolla.com>
*
@@ -43,11 +43,9 @@
#include <droid/droid-util.h>
-/* If device is non-zero, it will override whatever is set in modargs for input device. */
pa_source *pa_droid_source_new(pa_module *m,
pa_modargs *ma,
const char *driver,
- audio_devices_t device,
pa_droid_card_data *card_data,
pa_droid_mapping *am,
pa_card *card);
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-14.2.100.tar.bz2/src/droid/meson.build
^
|
@@ -2,6 +2,7 @@
['droid-sink.c', 'droid-sink.h'],
dependencies : libdroid_util_dep,
pic : true,
+ include_directories : configinc,
install : true,
install_dir : modlibexecdir,
install_rpath : rpath_dirs,
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-14.2.100.tar.bz2/src/droid/module-droid-card.c
^
|
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2018 Jolla Ltd.
+ * Copyright (C) 2013-2022 Jolla Ltd.
*
* Contact: Juho Hämäläinen <juho.hamalainen@jolla.com>
*
@@ -61,11 +61,12 @@
#include <droid/droid-util.h>
#include <droid/sllist.h>
+#include <droid/utils.h>
#include "droid-sink.h"
#include "droid-source.h"
PA_MODULE_AUTHOR("Juho Hämäläinen");
-PA_MODULE_DESCRIPTION("Droid card jb2q");
+PA_MODULE_DESCRIPTION("Droid card");
PA_MODULE_VERSION(PACKAGE_VERSION);
PA_MODULE_USAGE(
"card_name=<name for the card> "
@@ -73,16 +74,13 @@
"source_name=<name for the source> "
"namereg_fail=<when false attempt to synthesise new names if they are already taken> "
"rate=<sample rate> "
- "output_flags=<flags for sink> "
"module_id=<which droid hw module to load, default primary> "
"voice_source_routing=<always true, parameter left for compatibility> "
"deferred_volume=<synchronize software and hardware volume changes to avoid momentary jumps?> "
"config=<location for droid audio configuration> "
"voice_property_key=<proplist key searched for sink-input that should control voice call volume> "
"voice_property_value=<proplist value for the key for voice control sink-input> "
- "default_profile=<boolean. create default profile for primary module or not. defaults to true> "
- "merge_inputs=<unused, always true> "
- "quirks=<comma separated list of quirks to enable/disable>"
+ "options=<comma separated list of options to enable/disable>"
);
static const char* const valid_modargs[] = {
@@ -97,26 +95,18 @@
"sink_rate",
"sink_format",
"sink_channel_map",
- "sink_mix_route",
"source_rate",
"source_format",
"source_channel_map",
- "output_flags",
"module_id",
"voice_source_routing",
"sink_buffer",
"source_buffer",
"deferred_volume",
- "mute_routing_before",
- "mute_routing_after",
- "prewrite_on_resume",
"config",
"voice_property_key",
"voice_property_value",
- "default_profile",
- "combine",
- "merge_inputs",
- "quirks",
+ /* DM_OPTIONS */
NULL,
};
@@ -171,7 +161,7 @@
struct virtual_profile virtual;
};
-#ifdef DROID_AUDIO_HAL_USE_VSID
+#ifdef DROID_AUDIO_HAL_DEBUG_VSID
/* From hal/voice_extn/voice_extn.c */
#define AUDIO_PARAMETER_KEY_VSID "vsid"
@@ -215,7 +205,7 @@
static bool voicecall_voicemmode1_vsid_profile_event_cb(struct userdata *u, pa_droid_profile *p, bool enabling);
static bool voicecall_voicemmode2_vsid_profile_event_cb(struct userdata *u, pa_droid_profile *p, bool enabling);
-#endif /* DROID_AUDIO_HAL_USE_VSID */
+#endif /* DROID_AUDIO_HAL_DEBUG_VSID */
static void add_disabled_profile(pa_hashmap *profiles) {
pa_card_profile *cp;
@@ -268,16 +258,6 @@
return cp;
}
-static int set_parameters_cb(pa_droid_card_data *card_data, const char *str) {
- struct userdata *u;
-
- pa_assert(card_data);
- pa_assert_se((u = card_data->userdata));
- pa_assert(str);
-
- return pa_droid_set_parameters(u->hw_module, str);
-}
-
static void set_card_name(pa_modargs *ma, pa_card_new_data *data, const char *module_id) {
const char *tmp;
char *name;
@@ -299,16 +279,57 @@
}
static bool output_enabled(struct userdata *u, pa_droid_mapping *am) {
+ bool enabled = false;
+
pa_assert(u);
pa_assert(am);
- if (!pa_droid_quirk(u->hw_module, QUIRK_OUTPUT_FAST) && am->output->flags & AUDIO_OUTPUT_FLAG_FAST)
- return false;
- if (!pa_droid_quirk(u->hw_module, QUIRK_OUTPUT_DEEP_BUFFER) && am->output->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER)
- return false;
+ if (am->mix_port->flags & AUDIO_OUTPUT_FLAG_PRIMARY)
+ enabled = true;
- return true;
+ else if (am->mix_port->flags & AUDIO_OUTPUT_FLAG_RAW)
+ enabled = false;
+
+ else if (pa_droid_option(u->hw_module, DM_OPTION_OUTPUT_FAST) && am->mix_port->flags & AUDIO_OUTPUT_FLAG_FAST)
+ enabled = true;
+
+ else if (pa_droid_option(u->hw_module, DM_OPTION_OUTPUT_DEEP_BUFFER) && am->mix_port->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER)
+ enabled = true;
+
+ pa_log_debug("Output mix port \"%s\" %s", am->name, enabled ? "enabled" : "disabled");
+
+ return enabled;
+}
+
+static bool input_enabled(struct userdata *u, pa_droid_mapping *am) {
+ bool enabled = false;
+
+ pa_assert(u);
+ pa_assert(am);
+
+ /* Look for primary mix port as the one used for creating droid-source. */
+ if (dm_strcasestr(am->name, "primary"))
+ enabled = true;
+
+ pa_log_debug("Input mix port \"%s\" %s", am->name, enabled ? "enabled" : "disabled");
+
+ return enabled;
+}
+
+static uint32_t max_channels_for_mix_port(dm_config_port *mix_port, uint32_t previous_max_channels) {
+ uint32_t max_channels = 0;
+ dm_config_profile *profile;
+ void *state;
+
+ DM_LIST_FOREACH_DATA(profile, mix_port->profiles, state) {
+ for (int i = 0; profile->channel_masks[i]; i++) {
+ max_channels = audio_channel_count_from_out_mask(profile->channel_masks[i]) > max_channels
+ ? audio_channel_count_from_out_mask(profile->channel_masks[i]) : max_channels;
+ }
+ }
+
+ return max_channels > previous_max_channels ? max_channels : previous_max_channels;
}
static void add_profile(struct userdata *u, pa_hashmap *h, pa_hashmap *ports, pa_droid_profile *ap) {
@@ -329,26 +350,23 @@
cp->available = PA_AVAILABLE_YES;
cp->priority = ap->priority;
+ /* Output mappings */
+
max_channels = 0;
PA_IDXSET_FOREACH(am, ap->output_mappings, idx) {
- if (!output_enabled(u, am))
- continue;
-
cp->n_sinks++;
pa_droid_add_card_ports(cp, ports, am, u->core);
- max_channels = popcount(am->output->channel_masks) > max_channels
- ? popcount(am->output->channel_masks) : max_channels;
+ max_channels = max_channels_for_mix_port(am->mix_port, max_channels);
}
cp->max_sink_channels = max_channels;
+ /* Input mappings */
+
max_channels = 0;
- if ((am = ap->input_mapping)) {
- const pa_droid_config_device *input;
+ PA_IDXSET_FOREACH(am, ap->input_mappings, idx) {
cp->n_sources++;
pa_droid_add_card_ports(cp, ports, am, u->core);
- SLLIST_FOREACH(input, am->inputs)
- max_channels = popcount(input->channel_masks) > max_channels
- ? popcount(input->channel_masks) : max_channels;
+ max_channels = max_channels_for_mix_port(am->mix_port, max_channels);
}
cp->max_source_channels = max_channels;
@@ -394,8 +412,13 @@
}
}
- if (d->droid_profile && (am = d->droid_profile->input_mapping)) {
- am->source = pa_droid_source_new(u->module, u->modargs, __FILE__, (audio_devices_t) 0, &u->card_data, am, u->card);
+ if (d->droid_profile && pa_idxset_size(d->droid_profile->input_mappings) > 0) {
+ PA_IDXSET_FOREACH(am, d->droid_profile->input_mappings, idx) {
+ if (!input_enabled(u, am))
+ continue;
+
+ am->source = pa_droid_source_new(u->module, u->modargs, __FILE__, &u->card_data, am, u->card);
+ }
}
}
@@ -447,19 +470,51 @@
if (enabling) {
pa_droid_sink_set_voice_control(am_output->sink, true);
- if (pa_droid_quirk(u->hw_module, QUIRK_REALCALL))
+ if (pa_droid_option(u->hw_module, DM_OPTION_REALCALL))
pa_droid_set_parameters(u->hw_module, VENDOR_EXT_REALCALL_ON);
} else {
pa_droid_sink_set_voice_control(am_output->sink, false);
- if (pa_droid_quirk(u->hw_module, QUIRK_REALCALL))
+ if (pa_droid_option(u->hw_module, DM_OPTION_REALCALL))
pa_droid_set_parameters(u->hw_module, VENDOR_EXT_REALCALL_OFF);
}
return true;
}
-#ifdef DROID_AUDIO_HAL_USE_VSID
+static bool in_communication_profile_event_cb(struct userdata *u, pa_droid_profile *p, bool enabling) {
+ pa_droid_profile *dp;
+
+ pa_assert(u);
+ pa_assert(u->real_profile);
+
+ dp = card_get_droid_profile(u->real_profile);
+
+ if (pa_idxset_size(dp->output_mappings) > 0) {
+ pa_droid_mapping *am;
+ uint32_t idx;
+
+ PA_IDXSET_FOREACH(am, dp->output_mappings, idx) {
+
+ if (am->mix_port->flags & AUDIO_OUTPUT_FLAG_VOIP_RX) {
+ if (enabling && !am->sink) {
+ pa_log_info("in communication: enable VOIP sink");
+ am->sink = pa_droid_sink_new(u->module, u->modargs, __FILE__, &u->card_data, 0, am, u->card);
+ } else if (!enabling && am->sink) {
+ /* Don't rescue sink-inputs. */
+ pa_log_info("in communication: disable VOIP sink");
+ pa_droid_sink_free(am->sink);
+ am->sink = NULL;
+ }
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+#ifdef DROID_AUDIO_HAL_DEBUG_VSID
static bool voicecall_vsid(struct userdata *u, pa_droid_profile *p, uint32_t vsid, bool enabling)
{
char *setparam;
@@ -508,7 +563,7 @@
{
return voicecall_vsid(u, p, VOICEMMODE2_VSID, enabling);
}
-#endif /* DROID_AUDIO_HAL_USE_VSID */
+#endif /* DROID_AUDIO_HAL_DEBUG_VSID */
static void virtual_event(struct userdata *u, struct profile_data *profile, bool enabling) {
pa_assert(u);
@@ -691,13 +746,18 @@
}
}
- if (next->droid_profile && (am = next->droid_profile->input_mapping)) {
- if (!am->source)
- am->source = pa_droid_source_new(u->module, u->modargs, __FILE__, (audio_devices_t) 0, &u->card_data, am, u->card);
-
- if (source_outputs && am->source) {
- pa_source_move_all_finish(am->source, source_outputs, false);
- source_outputs = NULL;
+ if (next->droid_profile && pa_idxset_size(next->droid_profile->input_mappings) > 0) {
+ PA_IDXSET_FOREACH(am, next->droid_profile->input_mappings, idx) {
+ if (!input_enabled(u, am))
+ continue;
+
+ if (!am->source)
+ am->source = pa_droid_source_new(u->module, u->modargs, __FILE__, &u->card_data, am, u->card);
+
+ if (source_outputs && am->source) {
+ pa_source_move_all_finish(am->source, source_outputs, false);
+ source_outputs = NULL;
+ }
}
}
@@ -724,23 +784,17 @@
pa_card_new_data data;
const char *module_id;
bool namereg_fail = false;
- bool default_profile = true;
pa_card_profile *voicecall = NULL;
pa_assert(m);
- pa_log_info("Create new droid-card-jb2q");
+ pa_log_info("Create new droid-card");
- if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
+ if (!(ma = pa_droid_modargs_new(m->argument, valid_modargs))) {
pa_log("Failed to parse module arguments.");
goto fail;
}
- if (pa_modargs_get_value_boolean(ma, "default_profile", &default_profile) < 0) {
- pa_log("Failed to parse default_profile argument. Expects boolean value");
- goto fail;
- }
-
u = pa_xnew0(struct userdata, 1);
u->core = m->core;
m->userdata = u;
@@ -750,16 +804,12 @@
if (!(u->hw_module = pa_droid_hw_module_get2(u->core, ma, module_id)))
goto fail;
- pa_droid_quirk_log(u->hw_module);
+ pa_droid_options_log(u->hw_module);
- u->card_data.set_parameters = set_parameters_cb;
u->card_data.module_id = pa_xstrdup(module_id);
u->card_data.userdata = u;
- if (default_profile)
- u->profile_set = pa_droid_profile_set_default_new(u->hw_module->enabled_module);
- else
- u->profile_set = pa_droid_profile_set_new(u->hw_module->enabled_module);
+ u->profile_set = pa_droid_profile_set_default_new(u->hw_module->enabled_module);
pa_card_new_data_init(&data);
data.driver = __FILE__;
@@ -795,19 +845,18 @@
AUDIO_MODE_IN_CALL, NULL,
PA_AVAILABLE_YES, voicecall, data.profiles);
add_virtual_profile(u, COMMUNICATION_PROFILE_NAME, COMMUNICATION_PROFILE_DESC,
- AUDIO_MODE_IN_COMMUNICATION, NULL,
+ AUDIO_MODE_IN_COMMUNICATION, in_communication_profile_event_cb,
PA_AVAILABLE_YES, NULL, data.profiles);
add_virtual_profile(u, RINGTONE_PROFILE_NAME, RINGTONE_PROFILE_DESC,
AUDIO_MODE_RINGTONE, NULL,
PA_AVAILABLE_YES, NULL, data.profiles);
-#ifdef DROID_AUDIO_HAL_USE_VSID
+#ifdef DROID_AUDIO_HAL_DEBUG_VSID
add_virtual_profile(u, VOICE_SESSION_VOICE1_PROFILE_NAME, VOICE_SESSION_VOICE1_PROFILE_DESC,
AUDIO_MODE_IN_CALL, voicecall_voice1_vsid_profile_event_cb,
PA_AVAILABLE_YES, voicecall, data.profiles);
add_virtual_profile(u, VOICE_SESSION_VOICE2_PROFILE_NAME, VOICE_SESSION_VOICE2_PROFILE_DESC,
AUDIO_MODE_IN_CALL, voicecall_voice2_vsid_profile_event_cb,
PA_AVAILABLE_YES, voicecall, data.profiles);
- /* TODO: Probably enabled state needs to be determined dynamically for VOLTE and friends. */
add_virtual_profile(u, VOICE_SESSION_VOLTE_PROFILE_NAME, VOICE_SESSION_VOLTE_PROFILE_DESC,
AUDIO_MODE_IN_CALL, voicecall_volte_vsid_profile_event_cb,
PA_AVAILABLE_YES, voicecall, data.profiles);
@@ -823,7 +872,7 @@
add_virtual_profile(u, VOICE_SESSION_VOICEMMODE2_PROFILE_NAME, VOICE_SESSION_VOICEMMODE2_PROFILE_DESC,
AUDIO_MODE_IN_CALL, voicecall_voicemmode2_vsid_profile_event_cb,
PA_AVAILABLE_YES, voicecall, data.profiles);
-#endif /* DROID_AUDIO_HAL_USE_VSID */
+#endif /* DROID_AUDIO_HAL_DEBUG_VSID */
add_disabled_profile(data.profiles);
@@ -871,7 +920,6 @@
if (u->card && u->card->sources)
pa_idxset_remove_all(u->card->sources, (pa_free_cb_t) pa_droid_source_free);
-
if (u->card)
pa_card_free(u->card);
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-14.2.100.tar.bz2/src/droid/module-droid-sink.c
^
|
@@ -42,7 +42,7 @@
#include "droid-sink.h"
PA_MODULE_AUTHOR("Juho Hämäläinen");
-PA_MODULE_DESCRIPTION("Droid sink jb2q");
+PA_MODULE_DESCRIPTION("Droid sink");
PA_MODULE_USAGE("master_sink=<sink to connect to> "
"sink_name=<name of created sink>");
PA_MODULE_VERSION(PACKAGE_VERSION);
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-14.2.100.tar.bz2/src/droid/module-droid-source.c
^
|
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2018 Jolla Ltd.
+ * Copyright (C) 2013-2022 Jolla Ltd.
*
* Contact: Juho Hämäläinen <juho.hamalainen@jolla.com>
*
@@ -41,7 +41,7 @@
#include "droid-source.h"
PA_MODULE_AUTHOR("Juho Hämäläinen");
-PA_MODULE_DESCRIPTION("Droid source jb2q");
+PA_MODULE_DESCRIPTION("Droid source");
PA_MODULE_USAGE("master_source=<source to connect to> "
"source_name=<name of created source>");
PA_MODULE_VERSION(PACKAGE_VERSION);
@@ -83,7 +83,7 @@
goto fail;
}
- if (!(m->userdata = pa_droid_source_new(m, ma, __FILE__, (audio_devices_t) 0, NULL, NULL, NULL)))
+ if (!(m->userdata = pa_droid_source_new(m, ma, __FILE__, NULL, NULL, NULL)))
goto fail;
pa_modargs_free(ma);
|
[-]
[+]
|
Deleted |
_service:tar_git:pulseaudio-modules-droid-jb2q-14.2.101.tar.bz2/src/common/config-parser-legacy.c
^
|
@@ -1,436 +0,0 @@
-/*
- * Copyright (C) 2018 Jolla Ltd.
- *
- * Contact: Juho Hämäläinen <juho.hamalainen@jolla.com>
- *
- * These PulseAudio Modules are 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
- * version 2.1 of the License.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
- * USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <stdbool.h>
-#include <pulsecore/macro.h>
-#include <pulsecore/core-util.h>
-#include <pulsecore/core-error.h>
-#include <pulsecore/log.h>
-#include <pulse/xmalloc.h>
-
-#include <hardware_legacy/audio_policy_conf.h>
-
-#include "droid/version.h"
-#include "droid/droid-config.h"
-#include "droid/conversion.h"
-#include "droid/sllist.h"
-
-/* Section defining custom global configuration variables. */
-#define GLOBAL_CONFIG_EXT_TAG "custom_properties"
-
-#define GAIN_TAG_PREFIX "gain_"
-
-#define MAX_LINE_LENGTH (1024)
-#define WHITESPACE "\n\r \t"
-
-static void log_parse_error(const char *fn, const unsigned ln, const char *section, const char *v) {
- pa_log("[%s:%u] failed to parse line in section %s: unknown section (%s)", fn, ln, section, v);
-}
-
-pa_droid_config_audio *pa_parse_droid_audio_config_legacy(const char *filename) {
- pa_droid_config_audio *config = NULL;
- FILE *f;
- unsigned n = 0;
- bool ret = true;
- char *full_line = NULL;
- uint32_t hw_module_count = 0;
-
- enum config_loc {
- IN_ROOT = 0,
- IN_GLOBAL = 1,
- IN_GLOBAL_EXT = 2,
- IN_HW_MODULES = 3,
- IN_MODULE = 4,
- IN_OUTPUT_INPUT = 5,
- IN_CONFIG = 6,
- IN_MODULE_GLOBAL = 10,
- IN_DEVICES = 20,
- IN_DEVICES_DEVICE = 21,
- IN_GAINS = 22,
- IN_GAIN_N = 23
- } loc = IN_ROOT;
-
- bool in_output = true;
-
- pa_droid_config_hw_module *module = NULL;
- pa_droid_config_device *output = NULL;
- pa_droid_config_device *input = NULL;
-
- pa_assert(filename);
-
- f = fopen(filename, "r");
-
- if (!f) {
- pa_log_info("Failed to open config file (%s): %s", filename, pa_cstrerror(errno));
- ret = false;
- goto finish;
- }
-
- config = pa_xnew0(pa_droid_config_audio, 1);
- config->global_config = pa_xnew0(pa_droid_config_global, 1);
-
- pa_lock_fd(fileno(f), 1);
-
- full_line = pa_xmalloc0(sizeof(char) * MAX_LINE_LENGTH);
-
- while (!feof(f)) {
- char *ln, *d, *v, *value;
-
- if (!fgets(full_line, MAX_LINE_LENGTH, f))
- break;
-
- n++;
-
- pa_strip_nl(full_line);
-
- if (!*full_line)
- continue;
-
- ln = full_line + strspn(full_line, WHITESPACE);
-
- if (ln[0] == '#')
- continue;
-
- v = ln;
- d = v + strcspn(v, WHITESPACE);
-
- value = d + strspn(d, WHITESPACE);
- d[0] = '\0';
- d = value + strcspn(value, WHITESPACE);
- d[0] = '\0';
-
- /* Enter section */
- if (pa_streq(value, "{")) {
-
- if (!*v) {
- pa_log("[%s:%u] failed to parse line - too few words", filename, n);
- goto finish;
- }
-
- switch (loc) {
- case IN_ROOT:
- if (pa_streq(v, GLOBAL_CONFIG_TAG)) {
- loc = IN_GLOBAL;
- }
- else if (pa_streq(v, AUDIO_HW_MODULE_TAG))
- loc = IN_HW_MODULES;
- else {
- log_parse_error(filename, n, "<root>", v);
- ret = false;
- goto finish;
- }
- break;
-
- case IN_GLOBAL:
- if (pa_streq(v, GLOBAL_CONFIG_EXT_TAG))
- loc = IN_GLOBAL_EXT;
- else {
- log_parse_error(filename, n, GLOBAL_CONFIG_TAG, v);
- ret = false;
- goto finish;
- }
- break;
-
- case IN_HW_MODULES:
- pa_assert(!module);
-
- module = pa_droid_config_hw_module_new(config, v);
- SLLIST_APPEND(pa_droid_config_hw_module, config->hw_modules, module);
- hw_module_count++;
- loc = IN_MODULE;
- pa_log_debug("config: New module: %s", module->name);
- break;
-
- case IN_MODULE:
- pa_assert(module);
-
- if (pa_streq(v, OUTPUTS_TAG)) {
- loc = IN_OUTPUT_INPUT;
- in_output = true;
- } else if (pa_streq(v, INPUTS_TAG)) {
- loc = IN_OUTPUT_INPUT;
- in_output = false;
- } else if (pa_streq(v, GLOBAL_CONFIG_TAG)) {
- loc = IN_MODULE_GLOBAL;
- } else if (pa_streq(v, DEVICES_TAG)) {
- loc = IN_DEVICES;
- } else {
- log_parse_error(filename, n, module->name, v);
- ret = false;
- goto finish;
- }
- break;
-
- case IN_OUTPUT_INPUT:
- pa_assert(module);
-
- if (in_output) {
- output = pa_droid_config_device_new(module, PA_DIRECTION_OUTPUT, v);
- SLLIST_APPEND(pa_droid_config_device, module->outputs, output);
- loc = IN_CONFIG;
- pa_log_debug("config: %s: New output: %s", module->name, output->name);
- } else {
- input = pa_droid_config_device_new(module, PA_DIRECTION_INPUT, v);
- SLLIST_APPEND(pa_droid_config_device, module->inputs, input);
- loc = IN_CONFIG;
- pa_log_debug("config: %s: New input: %s", module->name, input->name);
- }
- break;
-
- case IN_DEVICES:
- /* TODO Missing implementation of parsing the module/devices section.
- * As of now there is no need for the information, fix this when that
- * changes. */
- loc = IN_DEVICES_DEVICE;
- break;
-
- case IN_DEVICES_DEVICE:
- if (pa_streq(v, GAINS_TAG))
- loc = IN_GAINS;
- else {
- log_parse_error(filename, n, DEVICES_TAG, v);
- ret = false;
- goto finish;
- }
- break;
-
- case IN_GAINS:
- /* TODO Missing implementation of parsing the gain_n section.
- * As of now there is no need for the information, fix this when that
- * changes. */
- if (pa_startswith(v, GAIN_TAG_PREFIX))
- loc = IN_GAIN_N;
- else {
- log_parse_error(filename, n, GAINS_TAG, v);
- ret = false;
- goto finish;
- }
- break;
-
- case IN_CONFIG:
- if (pa_streq(v, GAINS_TAG)) {
- loc = IN_GAINS;
- } else {
- log_parse_error(filename, n, in_output ? output->name : input->name, v);
- ret = false;
- goto finish;
- }
- break;
-
- default:
- pa_log("[%s:%u] failed to parse line: unknown section (%s)", filename, n, v);
- ret = false;
- goto finish;
- }
-
- continue;
- }
-
- /* Exit section */
- if (pa_streq(v, "}")) {
- switch (loc) {
- case IN_ROOT:
- pa_log("[%s:%u] failed to parse line - extra closing bracket", filename, n);
- ret = false;
- goto finish;
-
- case IN_HW_MODULES:
- /* fall through */
- case IN_GLOBAL:
- loc = IN_ROOT;
- break;
-
- case IN_MODULE:
- module = NULL;
- loc = IN_HW_MODULES;
- break;
-
- case IN_DEVICES:
- /* fall through */
- case IN_MODULE_GLOBAL:
- loc = IN_MODULE;
- break;
-
- case IN_GAINS:
- if (output || input)
- loc = IN_CONFIG;
- else
- loc = IN_DEVICES_DEVICE;
- break;
-
- case IN_OUTPUT_INPUT:
- if (in_output)
- output = NULL;
- else
- input = NULL;
- /* fall through */
- case IN_GAIN_N:
- /* fall through */
- case IN_DEVICES_DEVICE:
- /* fall through */
- case IN_CONFIG:
- /* fall through */
- case IN_GLOBAL_EXT:
- loc--;
- break;
- }
-
- continue;
- }
-
- /* Parsing of values */
- if (loc == IN_GLOBAL ||
- loc == IN_GLOBAL_EXT ||
- loc == IN_MODULE_GLOBAL ||
- loc == IN_CONFIG ||
- loc == IN_DEVICES_DEVICE ||
- loc == IN_GAIN_N) {
-
- bool success = false;
-
- if (loc == IN_GLOBAL || loc == IN_MODULE_GLOBAL) {
- pa_droid_config_global *global_config = NULL;
-
- if (loc == IN_MODULE_GLOBAL) {
- pa_assert(module);
- if (!module->global_config)
- module->global_config = pa_xnew0(pa_droid_config_global, 1);
- global_config = module->global_config;
- } else
- global_config = config->global_config;
-
- pa_assert(global_config);
-
- /* Parse global configuration */
-
- if (pa_streq(v, ATTACHED_OUTPUT_DEVICES_TAG))
- success = pa_conversion_parse_output_devices(filename, n, value, true, true,
- &global_config->attached_output_devices);
- else if (pa_streq(v, DEFAULT_OUTPUT_DEVICE_TAG))
- success = pa_conversion_parse_output_devices(filename, n, value, true, true,
- &global_config->default_output_device);
- else if (pa_streq(v, ATTACHED_INPUT_DEVICES_TAG))
- success = pa_conversion_parse_input_devices(filename, n, value, true, false,
- &global_config->attached_input_devices);
- else if (pa_streq(v, AUDIO_HAL_VERSION_TAG))
- success = pa_conversion_parse_version(filename, n, value,
- &global_config->audio_hal_version);
-#ifdef SPEAKER_DRC_ENABLED_TAG
- // SPEAKER_DRC_ENABLED_TAG is only from Android v4.4
- else if (pa_streq(v, SPEAKER_DRC_ENABLED_TAG))
- /* TODO - Add support for dynamic range control */
- success = true; /* Do not fail while parsing speaker_drc_enabled entry */
-#endif
- else {
- pa_log("[%s:%u] failed to parse line - unknown config entry %s", filename, n, v);
- success = false;
- }
-
- } else if (loc == IN_GLOBAL_EXT) {
-
- /* Parse custom global configuration
- * For now just log all custom variables, don't do
- * anything with the values.
- * TODO: Store custom values somehow */
-
- pa_log_debug("[%s:%u] TODO custom variable: %s = %s", filename, n, v, value);
- success = true;
-
- } else if (loc == IN_CONFIG) {
-
- /* Parse per-output or per-input configuration */
-
- if ((in_output && !output) || (!in_output && !input)) {
- pa_log("[%s:%u] failed to parse line", filename, n);
- ret = false;
- goto finish;
- }
-
- if (pa_streq(v, SAMPLING_RATES_TAG))
- success = pa_conversion_parse_sampling_rates(filename, n, value, true,
- in_output ? output->sampling_rates : input->sampling_rates);
- else if (pa_streq(v, FORMATS_TAG))
- success = pa_conversion_parse_formats(filename, n, value, true,
- in_output ? &output->formats : &input->formats);
- else if (pa_streq(v, CHANNELS_TAG)) {
- if (in_output)
- success = pa_conversion_parse_output_channels(filename, n, value, true, &output->channel_masks) > 0;
- else
- success = pa_conversion_parse_input_channels(filename, n, value, true, &input->channel_masks) > 0;
- } else if (pa_streq(v, DEVICES_TAG)) {
- if (in_output)
- success = pa_conversion_parse_output_devices(filename, n, value, true, false, &output->devices);
- else
- success = pa_conversion_parse_input_devices(filename, n, value, true, false, &input->devices);
- } else if (pa_streq(v, FLAGS_TAG)) {
- if (in_output)
- success = pa_conversion_parse_output_flags(filename, n, value, &output->flags);
- else {
-#if AUDIO_API_VERSION_MAJ >= 3
- success = pa_conversion_parse_input_flags(filename, n, value, &input->flags);
-#else
- pa_log("[%s:%u] failed to parse line - output flags inside input definition", filename, n);
- success = false;
-#endif
- }
- } else {
- pa_log("[%s:%u] failed to parse line - unknown config entry %s", filename, n, v);
- success = false;
- }
-
- } else if (loc == IN_DEVICES_DEVICE) {
- /* TODO Missing implementation of parsing the module/devices section.
- * As of now there is no need for the information, fix this when that
- * changes. */
- success = true;
- } else if (loc == IN_GAIN_N) {
- /* TODO Missing implementation of parsing the gain_n section.
- * As of now there is no need for the information, fix this when that
- * changes. */
- success = true;
- } else
- pa_assert_not_reached();
-
- if (!success) {
- ret = false;
- goto finish;
- }
- }
- }
-
- pa_log_info("Parsed config file (%s): %u modules.", filename, hw_module_count);
-
-finish:
- if (f) {
- pa_lock_fd(fileno(f), 0);
- fclose(f);
- }
-
- pa_xfree(full_line);
-
- if (!ret)
- pa_droid_config_free(config), config = NULL;
-
- return config;
-}
|
[-]
[+]
|
Deleted |
_service:tar_git:pulseaudio-modules-droid-jb2q-14.2.101.tar.bz2/src/common/droid-util-41qc.h
^
|
@@ -1,307 +0,0 @@
-/*
- * Copyright (C) 2013 Jolla Ltd.
- *
- * Contact: Juho Hämäläinen <juho.hamalainen@jolla.com>
- *
- * These PulseAudio Modules are 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
- * version 2.1 of the License.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
- * USA.
- */
-
-#ifndef _ANDROID_UTIL_V412_H_
-#define _ANDROID_UTIL_V412_H_
-
-#include <hardware/audio.h>
-#include <hardware_legacy/audio_policy_conf.h>
-
-#include <pulse/channelmap.h>
-
-// PulseAudio value - Android value
-
-uint32_t conversion_table_output_channel[][2] = {
- { PA_CHANNEL_POSITION_MONO, AUDIO_CHANNEL_OUT_MONO },
- { PA_CHANNEL_POSITION_FRONT_LEFT, AUDIO_CHANNEL_OUT_FRONT_LEFT },
- { PA_CHANNEL_POSITION_FRONT_RIGHT, AUDIO_CHANNEL_OUT_FRONT_RIGHT},
- { PA_CHANNEL_POSITION_FRONT_CENTER, AUDIO_CHANNEL_OUT_FRONT_CENTER },
- { PA_CHANNEL_POSITION_SUBWOOFER, AUDIO_CHANNEL_OUT_LOW_FREQUENCY },
- { PA_CHANNEL_POSITION_REAR_LEFT, AUDIO_CHANNEL_OUT_BACK_LEFT },
- { PA_CHANNEL_POSITION_REAR_RIGHT, AUDIO_CHANNEL_OUT_BACK_RIGHT },
- { PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER },
- { PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER },
- { PA_CHANNEL_POSITION_REAR_CENTER, AUDIO_CHANNEL_OUT_BACK_CENTER },
- { PA_CHANNEL_POSITION_SIDE_LEFT, AUDIO_CHANNEL_OUT_SIDE_LEFT },
- { PA_CHANNEL_POSITION_SIDE_RIGHT, AUDIO_CHANNEL_OUT_SIDE_RIGHT },
- { PA_CHANNEL_POSITION_TOP_CENTER, AUDIO_CHANNEL_OUT_TOP_CENTER },
- { PA_CHANNEL_POSITION_TOP_FRONT_LEFT, AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT },
- { PA_CHANNEL_POSITION_TOP_FRONT_CENTER, AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER },
- { PA_CHANNEL_POSITION_TOP_FRONT_RIGHT, AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT },
- { PA_CHANNEL_POSITION_TOP_REAR_LEFT, AUDIO_CHANNEL_OUT_TOP_BACK_LEFT },
- { PA_CHANNEL_POSITION_TOP_REAR_CENTER, AUDIO_CHANNEL_OUT_TOP_BACK_CENTER },
- { PA_CHANNEL_POSITION_TOP_REAR_RIGHT, AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT }
-};
-
-uint32_t conversion_table_input_channel[][2] = {
- { PA_CHANNEL_POSITION_MONO, AUDIO_CHANNEL_IN_MONO },
- { PA_CHANNEL_POSITION_FRONT_LEFT, AUDIO_CHANNEL_IN_LEFT },
- { PA_CHANNEL_POSITION_FRONT_RIGHT, AUDIO_CHANNEL_IN_RIGHT},
- { PA_CHANNEL_POSITION_FRONT_CENTER, AUDIO_CHANNEL_IN_FRONT },
- { PA_CHANNEL_POSITION_REAR_CENTER, AUDIO_CHANNEL_IN_BACK },
- /* Following are missing suitable counterparts on PulseAudio side. */
- { AUDIO_CHANNEL_IN_LEFT_PROCESSED, AUDIO_CHANNEL_IN_LEFT_PROCESSED },
- { AUDIO_CHANNEL_IN_RIGHT_PROCESSED, AUDIO_CHANNEL_IN_RIGHT_PROCESSED },
- { AUDIO_CHANNEL_IN_FRONT_PROCESSED, AUDIO_CHANNEL_IN_FRONT_PROCESSED },
- { AUDIO_CHANNEL_IN_BACK_PROCESSED, AUDIO_CHANNEL_IN_BACK_PROCESSED },
- { AUDIO_CHANNEL_IN_PRESSURE, AUDIO_CHANNEL_IN_PRESSURE },
- { AUDIO_CHANNEL_IN_X_AXIS, AUDIO_CHANNEL_IN_X_AXIS },
- { AUDIO_CHANNEL_IN_Y_AXIS, AUDIO_CHANNEL_IN_Y_AXIS },
- { AUDIO_CHANNEL_IN_Z_AXIS, AUDIO_CHANNEL_IN_Z_AXIS },
- { AUDIO_CHANNEL_IN_VOICE_UPLINK, AUDIO_CHANNEL_IN_VOICE_UPLINK },
- { AUDIO_CHANNEL_IN_VOICE_DNLINK, AUDIO_CHANNEL_IN_VOICE_DNLINK }
-};
-
-uint32_t conversion_table_format[][2] = {
- { PA_SAMPLE_U8, AUDIO_FORMAT_PCM_8_BIT },
- { PA_SAMPLE_S16LE, AUDIO_FORMAT_PCM_16_BIT },
- { PA_SAMPLE_S32LE, AUDIO_FORMAT_PCM_32_BIT },
- { PA_SAMPLE_S24LE, AUDIO_FORMAT_PCM_8_24_BIT }
-};
-
-uint32_t conversion_table_default_audio_source[][2] = {
- { AUDIO_DEVICE_IN_ALL, AUDIO_SOURCE_DEFAULT }
-};
-
-struct string_conversion {
- uint32_t value;
- const char *str;
-};
-
-#if defined(STRING_ENTRY) || defined(STRING_ENTRY)
-#error STRING_ENTRY already defined somewhere, fix this lib.
-#endif
-#define STRING_ENTRY(str) { str, #str }
-/* Output devices */
-struct string_conversion string_conversion_table_output_device[] = {
- STRING_ENTRY(AUDIO_DEVICE_OUT_EARPIECE),
- STRING_ENTRY(AUDIO_DEVICE_OUT_SPEAKER),
- STRING_ENTRY(AUDIO_DEVICE_OUT_WIRED_HEADSET),
- STRING_ENTRY(AUDIO_DEVICE_OUT_WIRED_HEADPHONE),
- STRING_ENTRY(AUDIO_DEVICE_OUT_BLUETOOTH_SCO),
- STRING_ENTRY(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET),
- STRING_ENTRY(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT),
- STRING_ENTRY(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP),
- STRING_ENTRY(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES),
- STRING_ENTRY(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER),
- STRING_ENTRY(AUDIO_DEVICE_OUT_AUX_DIGITAL),
- STRING_ENTRY(AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET),
- STRING_ENTRY(AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET),
- STRING_ENTRY(AUDIO_DEVICE_OUT_USB_ACCESSORY),
- STRING_ENTRY(AUDIO_DEVICE_OUT_USB_DEVICE),
- STRING_ENTRY(AUDIO_DEVICE_OUT_FM),
- STRING_ENTRY(AUDIO_DEVICE_OUT_FM_TX),
- STRING_ENTRY(AUDIO_DEVICE_OUT_ANC_HEADSET),
- STRING_ENTRY(AUDIO_DEVICE_OUT_ANC_HEADPHONE),
- STRING_ENTRY(AUDIO_DEVICE_OUT_PROXY),
- STRING_ENTRY(AUDIO_DEVICE_OUT_ALL),
- STRING_ENTRY(AUDIO_DEVICE_OUT_ALL_A2DP),
- STRING_ENTRY(AUDIO_DEVICE_OUT_ALL_SCO),
- STRING_ENTRY(AUDIO_DEVICE_OUT_ALL_USB),
- { 0, NULL }
-};
-
-struct string_conversion string_conversion_table_output_device_fancy[] = {
- { AUDIO_DEVICE_OUT_EARPIECE, "output-earpiece" },
- { AUDIO_DEVICE_OUT_SPEAKER, "output-speaker" },
- { AUDIO_DEVICE_OUT_SPEAKER
- | AUDIO_DEVICE_OUT_WIRED_HEADPHONE, "output-speaker+wired_headphone" },
- { AUDIO_DEVICE_OUT_WIRED_HEADSET, "output-wired_headset" },
- { AUDIO_DEVICE_OUT_WIRED_HEADPHONE, "output-wired_headphone" },
- { AUDIO_DEVICE_OUT_BLUETOOTH_SCO, "output-bluetooth_sco" },
- { AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET, "output-sco_headset" },
- { AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT, "output-sco_carkit" },
- { AUDIO_DEVICE_OUT_BLUETOOTH_A2DP, "output-a2dp" },
- { AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES, "output-a2dp_headphones" },
- { AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER, "output-a2dp_speaker" },
- { AUDIO_DEVICE_OUT_AUX_DIGITAL, "output-aux_digital" },
- { AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET, "output-analog_dock_headset" },
- { AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET, "output-digital_dock_headset" },
- { AUDIO_DEVICE_OUT_USB_ACCESSORY, "output-usb_accessory" },
- { AUDIO_DEVICE_OUT_USB_DEVICE, "output-usb_device" },
- { AUDIO_DEVICE_OUT_FM, "output-fm" },
- { AUDIO_DEVICE_OUT_FM_TX, "output-fm_tx" },
- { AUDIO_DEVICE_OUT_ANC_HEADSET, "output-anc_headset" },
- { AUDIO_DEVICE_OUT_ANC_HEADPHONE, "output-anc_headphone" },
- { AUDIO_DEVICE_OUT_PROXY, "output-proxy" },
- { 0, NULL }
-};
-
-/* Input devices */
-struct string_conversion string_conversion_table_input_device[] = {
- STRING_ENTRY(AUDIO_DEVICE_IN_COMMUNICATION),
- STRING_ENTRY(AUDIO_DEVICE_IN_AMBIENT),
- STRING_ENTRY(AUDIO_DEVICE_IN_BUILTIN_MIC),
- STRING_ENTRY(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET),
- STRING_ENTRY(AUDIO_DEVICE_IN_WIRED_HEADSET),
- STRING_ENTRY(AUDIO_DEVICE_IN_AUX_DIGITAL),
- STRING_ENTRY(AUDIO_DEVICE_IN_VOICE_CALL),
- STRING_ENTRY(AUDIO_DEVICE_IN_BACK_MIC),
- STRING_ENTRY(AUDIO_DEVICE_IN_ANC_HEADSET),
- STRING_ENTRY(AUDIO_DEVICE_IN_FM_RX),
- STRING_ENTRY(AUDIO_DEVICE_IN_FM_RX_A2DP),
- STRING_ENTRY(AUDIO_DEVICE_IN_PROXY),
- STRING_ENTRY(AUDIO_DEVICE_IN_DEFAULT),
- /* Combination entries consisting of multiple devices defined above.
- * These don't require counterpart in string_conversion_table_input_device_fancy. */
- STRING_ENTRY(AUDIO_DEVICE_IN_ALL),
- STRING_ENTRY(AUDIO_DEVICE_IN_ALL_SCO),
- { 0, NULL }
-};
-
-struct string_conversion string_conversion_table_input_device_fancy[] = {
- { AUDIO_DEVICE_IN_COMMUNICATION, "input-communication" },
- { AUDIO_DEVICE_IN_AMBIENT, "input-ambient" },
- { AUDIO_DEVICE_IN_BUILTIN_MIC, "input-builtin_mic" },
- { AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, "input-bluetooth_sco_headset" },
- { AUDIO_DEVICE_IN_WIRED_HEADSET, "input-wired_headset" },
- { AUDIO_DEVICE_IN_AUX_DIGITAL, "input-aux_digital" },
- { AUDIO_DEVICE_IN_VOICE_CALL, "input-voice_call" },
- { AUDIO_DEVICE_IN_BACK_MIC, "input-back_mic" },
- { AUDIO_DEVICE_IN_ANC_HEADSET, "input-anc_headset" },
- { AUDIO_DEVICE_IN_FM_RX, "input-fm_rx" },
- { AUDIO_DEVICE_IN_FM_RX_A2DP, "input-fm_rx_a2dp" },
- { AUDIO_DEVICE_IN_PROXY, "input-in_proxy" },
- { AUDIO_DEVICE_IN_DEFAULT, "input-default" },
- { 0, NULL }
-};
-
-struct string_conversion string_conversion_table_audio_source_fancy[] = {
- { AUDIO_SOURCE_DEFAULT, "default" },
- { AUDIO_SOURCE_MIC, "mic" },
- { AUDIO_SOURCE_VOICE_UPLINK, "voice uplink" },
- { AUDIO_SOURCE_VOICE_DOWNLINK, "voice downlink" },
- { AUDIO_SOURCE_VOICE_CALL, "voice call" },
- { AUDIO_SOURCE_CAMCORDER, "camcorder" },
- { AUDIO_SOURCE_VOICE_RECOGNITION, "voice recognition" },
- { AUDIO_SOURCE_VOICE_COMMUNICATION, "voice communication" },
- { AUDIO_SOURCE_FM_RX, "fm rx" },
- { AUDIO_SOURCE_FM_RX_A2DP, "fm rx a2dp" },
- { (uint32_t)-1, NULL }
-};
-
-/* Flags */
-struct string_conversion string_conversion_table_output_flag[] = {
- STRING_ENTRY(AUDIO_OUTPUT_FLAG_NONE),
- STRING_ENTRY(AUDIO_OUTPUT_FLAG_DIRECT),
- STRING_ENTRY(AUDIO_OUTPUT_FLAG_PRIMARY),
- STRING_ENTRY(AUDIO_OUTPUT_FLAG_FAST),
- STRING_ENTRY(AUDIO_OUTPUT_FLAG_DEEP_BUFFER),
- /* Qualcomm flags */
- STRING_ENTRY(AUDIO_OUTPUT_FLAG_LPA),
- STRING_ENTRY(AUDIO_OUTPUT_FLAG_TUNNEL),
- STRING_ENTRY(AUDIO_OUTPUT_FLAG_VOIP_RX),
- { 0, NULL }
-};
-
-struct string_conversion string_conversion_table_input_flag[] = {
- { 0, NULL }
-};
-
-/* Channels */
-struct string_conversion string_conversion_table_output_channels[] = {
- STRING_ENTRY(AUDIO_CHANNEL_OUT_FRONT_LEFT),
- STRING_ENTRY(AUDIO_CHANNEL_OUT_FRONT_RIGHT),
- STRING_ENTRY(AUDIO_CHANNEL_OUT_FRONT_CENTER),
- STRING_ENTRY(AUDIO_CHANNEL_OUT_LOW_FREQUENCY),
- STRING_ENTRY(AUDIO_CHANNEL_OUT_BACK_LEFT),
- STRING_ENTRY(AUDIO_CHANNEL_OUT_BACK_RIGHT),
- STRING_ENTRY(AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER),
- STRING_ENTRY(AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER),
- STRING_ENTRY(AUDIO_CHANNEL_OUT_BACK_CENTER),
- STRING_ENTRY(AUDIO_CHANNEL_OUT_SIDE_LEFT),
- STRING_ENTRY(AUDIO_CHANNEL_OUT_SIDE_RIGHT),
- STRING_ENTRY(AUDIO_CHANNEL_OUT_TOP_CENTER),
- STRING_ENTRY(AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT),
- STRING_ENTRY(AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER),
- STRING_ENTRY(AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT),
- STRING_ENTRY(AUDIO_CHANNEL_OUT_TOP_BACK_LEFT),
- STRING_ENTRY(AUDIO_CHANNEL_OUT_TOP_BACK_CENTER),
- STRING_ENTRY(AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT),
- STRING_ENTRY(AUDIO_CHANNEL_OUT_MONO),
- STRING_ENTRY(AUDIO_CHANNEL_OUT_STEREO),
- STRING_ENTRY(AUDIO_CHANNEL_OUT_QUAD),
- STRING_ENTRY(AUDIO_CHANNEL_OUT_SURROUND),
- STRING_ENTRY(AUDIO_CHANNEL_OUT_5POINT1),
- STRING_ENTRY(AUDIO_CHANNEL_OUT_7POINT1),
- STRING_ENTRY(AUDIO_CHANNEL_OUT_ALL),
- { 0, NULL }
-};
-struct string_conversion string_conversion_table_input_channels[] = {
- STRING_ENTRY(AUDIO_CHANNEL_IN_LEFT),
- STRING_ENTRY(AUDIO_CHANNEL_IN_RIGHT),
- STRING_ENTRY(AUDIO_CHANNEL_IN_FRONT),
- STRING_ENTRY(AUDIO_CHANNEL_IN_BACK),
- STRING_ENTRY(AUDIO_CHANNEL_IN_LEFT_PROCESSED),
- STRING_ENTRY(AUDIO_CHANNEL_IN_RIGHT_PROCESSED),
- STRING_ENTRY(AUDIO_CHANNEL_IN_FRONT_PROCESSED),
- STRING_ENTRY(AUDIO_CHANNEL_IN_BACK_PROCESSED),
- STRING_ENTRY(AUDIO_CHANNEL_IN_PRESSURE),
- STRING_ENTRY(AUDIO_CHANNEL_IN_X_AXIS),
- STRING_ENTRY(AUDIO_CHANNEL_IN_Y_AXIS),
- STRING_ENTRY(AUDIO_CHANNEL_IN_Z_AXIS),
- STRING_ENTRY(AUDIO_CHANNEL_IN_VOICE_UPLINK),
- STRING_ENTRY(AUDIO_CHANNEL_IN_VOICE_DNLINK),
- STRING_ENTRY(AUDIO_CHANNEL_IN_MONO),
- STRING_ENTRY(AUDIO_CHANNEL_IN_STEREO),
- STRING_ENTRY(AUDIO_CHANNEL_IN_5POINT1),
- STRING_ENTRY(AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO),
- STRING_ENTRY(AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO),
- STRING_ENTRY(AUDIO_CHANNEL_IN_VOICE_CALL_MONO),
- STRING_ENTRY(AUDIO_CHANNEL_IN_ALL),
- { 0, NULL }
-};
-
-/* Formats */
-struct string_conversion string_conversion_table_format[] = {
- STRING_ENTRY(AUDIO_FORMAT_DEFAULT),
- STRING_ENTRY(AUDIO_FORMAT_PCM),
- STRING_ENTRY(AUDIO_FORMAT_MP3),
- STRING_ENTRY(AUDIO_FORMAT_AMR_NB),
- STRING_ENTRY(AUDIO_FORMAT_AMR_WB),
- STRING_ENTRY(AUDIO_FORMAT_AAC),
- STRING_ENTRY(AUDIO_FORMAT_HE_AAC_V1),
- STRING_ENTRY(AUDIO_FORMAT_HE_AAC_V2),
- STRING_ENTRY(AUDIO_FORMAT_VORBIS),
- STRING_ENTRY(AUDIO_FORMAT_EVRC),
- STRING_ENTRY(AUDIO_FORMAT_QCELP),
- STRING_ENTRY(AUDIO_FORMAT_AC3),
- STRING_ENTRY(AUDIO_FORMAT_AC3_PLUS),
- STRING_ENTRY(AUDIO_FORMAT_DTS),
- STRING_ENTRY(AUDIO_FORMAT_WMA),
- STRING_ENTRY(AUDIO_FORMAT_WMA_PRO),
- STRING_ENTRY(AUDIO_FORMAT_AAC_ADIF),
- STRING_ENTRY(AUDIO_FORMAT_EVRCB),
- STRING_ENTRY(AUDIO_FORMAT_EVRCWB),
- STRING_ENTRY(AUDIO_FORMAT_EAC3),
- STRING_ENTRY(AUDIO_FORMAT_DTS_LBR),
- STRING_ENTRY(AUDIO_FORMAT_AMR_WB_PLUS),
- /* Currently we support only PCM formats, but keep all formats
- * here so audio_policy.conf can be parsed. */
- STRING_ENTRY(AUDIO_FORMAT_PCM_16_BIT),
- STRING_ENTRY(AUDIO_FORMAT_PCM_8_BIT),
- STRING_ENTRY(AUDIO_FORMAT_PCM_32_BIT),
- STRING_ENTRY(AUDIO_FORMAT_PCM_8_24_BIT),
- { 0, NULL }
-};
-#undef STRING_ENTRY
-
-#endif
|