Compare commits

...
Sign in to create a new pull request.

570 commits

Author SHA1 Message Date
Penelope Gwen
c0e8232a36 version bump 2026-03-29 18:17:19 -07:00
Penelope Gwen
18e6cd030e correct config file paths 2026-03-29 18:00:33 -07:00
Penelope Gwen
e689a5abc9 add config files 2026-03-29 14:10:35 -07:00
Adam Boardman
974ae573ad Various upstream (sfos) fixes and avoid an assert on internal structure confusion caused by move to new upstream Pulseaudio that appears to do things differently, this will probably need revisiting 2023-05-05 10:16:14 +01:00
Adam Boardman
f28da7fddf Build fixes post numbering fix 2023-05-04 15:35:11 +01:00
Adam Boardman
caf6773723 Updated version number 2023-04-23 10:02:48 +01:00
Adam Boardman
5c0ca5b077 Update changelog and possible build fixes 2023-04-04 16:05:33 +01:00
Adam Boardman
f1fb79c3e0 Merge remote-tracking branch 'upstream/bookworm' into bookworm 2023-04-04 15:10:10 +01:00
Eugenio Paolantonio (g7)
112843b765 [skip ci] [ci] Use the checkout step provided by the droidian-buildd orb
Signed-off-by: Eugenio Paolantonio (g7) <me@medesimo.eu>
2023-01-07 01:43:51 +01:00
Eugenio Paolantonio (g7)
10599fe519 [skip ci] Replace Drone with CircleCI
Signed-off-by: Eugenio Paolantonio (g7) <me@medesimo.eu>
2022-10-09 13:26:56 +02:00
Eugenio Paolantonio (g7)
85813e293a [packaging] Provide the virtual packages pulseaudio-modules-droid-apispecific{,-dev}
Signed-off-by: Eugenio Paolantonio (g7) <me@medesimo.eu>
2022-03-06 20:57:49 +01:00
Eugenio Paolantonio (g7)
145e49611a [packaging] Move to the -modern variant
Signed-off-by: Eugenio Paolantonio (g7) <me@medesimo.eu>
2022-02-28 00:59:48 +01:00
Eugenio Paolantonio (g7)
d3253e5175 Merge tag 'upstream/14.2.97' into feature/bookworm/upgrade-14.2.97-modern 2022-02-28 00:57:12 +01:00
Juho Hämäläinen
cef8f78746 Bump packaging version. 2022-02-25 13:11:05 +02:00
Juho Hämäläinen
04b14b8aac
Merge pull request #114 from jusa/cal_wait
Enable audio_cal_wait properly.
2022-02-25 13:10:20 +02:00
Juho Hämäläinen
0adc96eb56 common: Whitespace fix. 2022-02-25 13:05:27 +02:00
Juho Hämäläinen
47a043d8dc common: Enable audio_cal_wait properly.
Actual call to the function was missing.

[common] Enable audio_cal_wait properly. JB#55832
2022-02-25 13:05:10 +02:00
Juho Hämäläinen
a995948689 Bump packaging version. 2022-02-24 15:36:40 +02:00
Juho Hämäläinen
c4be583fbf
Merge pull request #113 from jusa/droid11
Update implementation for Android 11, drop old support.
2022-02-24 15:35:18 +02:00
Juho Hämäläinen
51d85423d5 common: Force mono 16kHz with AUDIO_OUTPUT_FLAG_VOIP_RX. 2022-02-24 15:05:08 +02:00
Juho Hämäläinen
ffe02f26b1 packaging: Update spec.
[pulseaudio-modules-droid] Update implementation for Android 11. Fixes JB#55832
2022-02-24 15:05:08 +02:00
Juho Hämäläinen
8b1bc6cbce packaging: Remove old sbj spec. 2022-02-24 15:05:08 +02:00
Juho Hämäläinen
1c1d82dfb9 README: Update content. 2022-02-24 15:05:06 +02:00
Juho Hämäläinen
5c53ef736f build: Update build flags. 2022-02-24 14:48:12 +02:00
Juho Hämäläinen
77b1e60df0 common: Always flag voip rx if enabled. 2022-02-24 14:48:12 +02:00
Juho Hämäläinen
385ccb8e4c options: voip rx is always enabled 2022-02-24 14:48:12 +02:00
Juho Hämäläinen
a37363a46c card: Create voip_rx sink in communication profile. 2022-02-24 14:48:12 +02:00
Juho Hämäläinen
e0d66cf4ad card: Update card with new common. 2022-02-24 14:48:12 +02:00
Juho Hämäläinen
2d1a50d450 card: Use VSID profiles only for debugging. 2022-02-24 14:48:12 +02:00
Juho Hämäläinen
c895311db5 source: Update source with new common. 2022-02-24 14:48:12 +02:00
Juho Hämäläinen
5238bfd192 sink: Update sink with new common. 2022-02-24 14:48:12 +02:00
Juho Hämäläinen
d4a8167c11 common: Update version requirements. 2022-02-24 14:48:12 +02:00
Juho Hämäläinen
b08cc4d219 common: Implement stream handling using device and mix ports. 2022-02-24 14:48:12 +02:00
Juho Hämäläinen
0b1221a047 card: Remove set_parameters callback. 2022-02-24 14:48:12 +02:00
Juho Hämäläinen
9ffca4ecd5 common: Remove set_parameters callback from card data. 2022-02-24 14:48:12 +02:00
Juho Hämäläinen
c359126658 common: Remove unused enums. 2022-02-24 14:48:12 +02:00
Juho Hämäläinen
73f93f1967 common: Remove _VSID define. 2022-02-24 14:48:12 +02:00
Juho Hämäläinen
5d4a5af1f5 common: Rename quirks to options and use normal modargs for parsing. 2022-02-24 14:48:10 +02:00
Juho Hämäläinen
532f6c55bf common: Update audio enum header.
Use current droid version 11 as base.
2022-02-24 09:08:28 +02:00
Juho Hämäläinen
1ac75ed3b0 common: Remove legacy from converter, parse channels as values. 2022-02-24 09:08:26 +02:00
Juho Hämäläinen
c02f917ebb common: Parser uses new config structures. 2022-02-24 09:08:21 +02:00
Juho Hämäläinen
4ca8716bd1 common: Use replace in place from utils in parser. 2022-02-24 09:08:21 +02:00
Juho Hämäläinen
67eeb83105 common: Parser supports new xml attributes. 2022-02-24 09:08:21 +02:00
Juho Hämäläinen
9e4c6fa8f1 common: Update config structures.
Match xml format style.
2022-02-24 09:08:17 +02:00
Juho Hämäläinen
40c320bc07 common: Add two string utility functions. 2022-02-24 09:08:14 +02:00
Juho Hämäläinen
eefdb31f57 common: Simple list implementation. 2022-02-24 09:08:11 +02:00
Juho Hämäläinen
b4fb20eafe common: Always use expat implementation for parser. 2022-02-23 10:27:49 +02:00
Juho Hämäläinen
fdd22b6949 common: Remove legacy conversion header. 2022-02-23 10:22:22 +02:00
Juho Hämäläinen
17fcb9e074 common: Remove legacy parser. 2022-02-23 10:21:03 +02:00
Juho Hämäläinen
1e992b6954 build: Update flag checks for current version. 2022-02-23 09:23:27 +02:00
Juho Hämäläinen
1daab94724 build: Expat is mandatory. 2022-02-23 09:23:03 +02:00
Juho Hämäläinen
0898217179 Bump packaging version. 2022-02-21 09:34:20 +02:00
Juho Hämäläinen
dbc7d678bb
Merge pull request #112 from jusa/new-api
New API for calling HAL functions.
2022-02-21 09:31:03 +02:00
Juho Hämäläinen
ef56dd4964 README: Add section about pa_shared based API. 2022-02-18 15:45:32 +02:00
Juho Hämäläinen
1cc2a0822e common: New API for calling HAL functions.
New pa_shared based API for calling HAL functions so that other modules
needing these functions don't need to link with libdroid.

[common] New API for calling HAL functions. JB#55832
2022-02-18 15:45:32 +02:00
Juho Hämäläinen
8df3961333
Merge pull request #111 from g7/for-upstream/mer-hybris/no-channels
common: Handle profiles with no supported channels
2022-02-18 15:10:19 +02:00
Eugenio Paolantonio (g7)
b23e20db5c common: Handle profiles with no supported channels
When a profile doesn't have any supported channels, pa_conversion_parse_*_channels
returns false even though the parsing itself succeeded.
This in turn makes the parsing to be aborted altogether.

Handle this case by properly ignoring the profile.

This commit changes the pa_conversion_parse_*_channels functions so that
they return the channel count, or -1 if the parsing has been unsuccessful.

[common] Handle profiles with no supported channels

Signed-off-by: Eugenio Paolantonio (g7) <me@medesimo.eu>
2022-02-18 13:15:21 +01:00
Eugenio Paolantonio (g7)
0886d509fc Merge tag 'upstream/14.2.93' into feature/bookworm/upgrade-14.2.93 2022-01-30 19:10:35 +01:00
Eugenio Paolantonio (g7)
80015ede82 [pulseaudio-modules-droid] Move to bookworm
Signed-off-by: Eugenio Paolantonio (g7) <me@medesimo.eu>
2021-12-08 16:19:04 +01:00
Juho Hämäläinen
9c6842e7d9 Bump packaging version. 2021-10-08 15:43:09 +03:00
Juho Hämäläinen
0d739ca587
Merge pull request #109 from jusa/jb55711
Use more generic stream property for audio source.
2021-10-08 15:42:31 +03:00
Juho Hämäläinen
1781dab3b8 common: Use more generic stream property for audio source.
[common] Use more generic stream property for audio source. JB#55711
2021-10-08 15:20:58 +03:00
Juho Hämäläinen
98d2c7358a Bump packaging version. 2021-10-08 08:32:35 +03:00
Juho Hämäläinen
11a09b005d
Merge pull request #108 from jusa/jb55711
Enable custom audio sources with input streams.
2021-10-08 08:31:12 +03:00
Juho Hämäläinen
d9e2ddfd72 common: Fix segfault with adaptations which assume empty adress is not NULL.
Some adaptations don't check for NULL before using the address which
leads to a crash. Let's just use empty string for address.

[common] Fix segfault with adaptations which assume empty adress is not NULL. Fixes JB#55831
2021-10-08 08:30:12 +03:00
Juho Hämäläinen
baecfc7cdd source: Use source-output proplist when reconfiguring input stream.
Use updated functions from common which utilize proplist when reconfiguring
input stream.

[source] Use source-output proplist when reconfiguring input stream. JB#55711
2021-10-07 12:06:31 +03:00
Juho Hämäläinen
2d7ee841ed common: Allow custom audio source based on property.
When reconfiguring input stream set custom audio source if one
is defined in droid.input.source property. Allowed values are
audio source fancy names listed in
string_conversion_table_audio_source_fancy.

[common] Allow custom audio source based on property. JB#55711
2021-10-07 12:04:52 +03:00
Juho Hämäläinen
4103c31aec common: Add generic converter for fancy audio sources.
[common] Add generic converter for fancy audio sources.
2021-10-07 12:00:59 +03:00
Adam Boardman
a5477e617b Build fix 2021-06-30 19:14:32 +01:00
Adam Boardman
130edc502b Merge remote-tracking branch 'upstream/master' into bullseye 2021-06-18 20:48:34 +01:00
Juho Hämäläinen
8283bbe5c9 Bump packaging version. 2021-05-06 13:11:14 +03:00
Juho Hämäläinen
42af5e85c5
Merge pull request #107 from jusa/jb53992
Add quirks standby_set_route and speaker_before_voice.
2021-05-06 13:10:28 +03:00
Juho Hämäläinen
a676accf88 common: Add quirk speaker_before_voice.
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().

[common] Add quirk speaker_before_voice. JB#53992
2021-05-05 16:05:36 +03:00
Juho Hämäläinen
446ac62a6e common: Add 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.

[common] Add quirk standby_set_route. JB#53992
2021-05-05 16:02:51 +03:00
Adam Boardman
930e65658c Fix for presense detection of headset plugging which only reports presence/absense of the microphone part, relates to gemian/gemian#7 2021-05-02 17:06:46 +01:00
Juho Hämäläinen
edec25347e Bump packaging version. 2021-04-22 15:40:52 +03:00
Juho Hämäläinen
8f936ba66f
Merge pull request #104 from jusa/bt_sco
Set BT_SCO parameter for Bluetooth routes.
2021-04-22 15:39:48 +03:00
Juho Hämäläinen
5be0189b91 common: Set BT_SCO parameter for Bluetooth routes.
Some adaptations need parameter BT_SCO set before enabling Bluetooth
HFP/HSP routes. It should be fine to set this parameter for adaptations
which don't need it as they would just ignore a parameter that is
unknown.

[common] Set BT_SCO parameter for Bluetooth routes. Fixes JB#53996
2021-04-21 22:59:19 +03:00
Juho Hämäläinen
38b07e6d45 Bump packaging version. 2021-03-25 21:43:13 +02:00
Juho Hämäläinen
eac4b34d39
Merge pull request #103 from jusa/volume_control
Avoid segfault when voice call starts with deferred volume.
2021-03-25 21:42:14 +02:00
Juho Hämäläinen
3f1cc042bc sink: Avoid segfault when voice call starts with deferred volume.
Calling pa_sink_set_write_volume_callback() from main
thread changes a callback pointer in pa_sink which is
accessed from io thread.

When audio is playing and voice call starts there is a
window where the callback is changed to NULL while io
thread is using it, causing a segfault.

[sink] Avoid segfault when voice call starts with deferred volume. JB#53687
2021-03-25 13:52:56 +02:00
Eugenio Paolantonio (g7)
c6da10943a [ci] Updated to match new name [CI SKIP]
Signed-off-by: Eugenio Paolantonio (g7) <me@medesimo.eu>
2021-03-24 00:39:36 +01:00
Juho Hämäläinen
b310103c0f Bump packaging version. 2021-03-23 18:11:06 +02:00
Juho Hämäläinen
898aacd38e
Merge pull request #102 from jusa/volume_control
Improvements to volume control.
2021-03-23 18:09:28 +02:00
Juho Hämäläinen
4414037c47 sink: Add option to prewrite silence always.
In some cases silence prewrite needs to be done even if the target
device is already active. In this case new "/always" modifier can
be used to enable prewriting always. For example:

prewrite_on_resume=deep_buffer=AUDIO_DEVICE_OUT_SPEAKER:2/always

[sink] Add option to prewrite silence always. JB#53590
2021-03-23 18:08:41 +02:00
Juho Hämäläinen
c9c66b4750 sink: Apply channel average volume to stream.
HAL implementations expect identical volume for both channels
anyway.

[sink] Apply channel average volume to stream. JB#53590
2021-03-23 18:08:02 +02:00
Juho Hämäläinen
65483884ae sink: Enable deferred volume for hw volume control.
Make sure volume changes are applied in between writing to hardware
to avoid volume glitches. As the writing is blocking we cannot synchronize
the changes from main thread easily so better to apply the changes
when nothing is written.

[sink] Enable deferred volume for hw volume control. JB#53590
2021-03-23 18:08:02 +02:00
Juho Hämäläinen
6ef0459669
Merge pull request #101 from jusa/cal
Add quirk for audio calibration.
2021-03-23 18:06:48 +02:00
Juho Hämäläinen
f01f0a53a7 source: Get hw module with new function in stand alone mode.
[source] Get hw module with new function in stand alone mode.
2021-03-18 11:54:12 +02:00
Juho Hämäläinen
997a9c87de sink: Get hw module with new function in stand alone mode.
[sink] Get hw module with new function in stand alone mode.
2021-03-18 11:53:53 +02:00
Juho Hämäläinen
0cd9a16bee README.md: Markdown formatting fixes. 2021-03-18 11:44:57 +02:00
Juho Hämäläinen
45badd1a75 README.md: Rename from README. 2021-03-18 11:44:57 +02:00
Juho Hämäläinen
cb40bac4c5 README: Add notes about audio_cal_wait quirk. 2021-03-18 11:44:57 +02:00
Juho Hämäläinen
b7cbd0ef3d source: Fix format specifiers. 2021-03-18 11:44:57 +02:00
Juho Hämäläinen
9cad56c426 sink: Fix format specifiers. 2021-03-18 11:44:57 +02:00
Juho Hämäläinen
9517a067de common: Fix format specifiers. 2021-03-18 11:44:57 +02:00
Juho Hämäläinen
9282a566c8 common: Add quirk audio_cal_wait.
If there is a device which runs threaded audio calibration after hw
module open we need to wait for a while after opening the first output
stream.

Also when the calibration is already done and we are starting we again
need to wait for a while for the calibration loading to finish.

[common] Add quirk audio_cal_wait. JB#52328
2021-03-18 11:44:54 +02:00
Juho Hämäläinen
7bb06f6a30 card: Parse quirks while loading hw module.
Parse quirks while loading hw module using new pa_droid_hw_module_get2().

[card] Parse quirks while loading hw module. JB#52328
2021-03-18 11:44:09 +02:00
Juho Hämäläinen
501d881534 common: Refactor quirks parsing.
Right now quirks can be used only after hw module is created.
In order to have quirks in the hw module loading phase as well
we need to have a mechanism to have quirk parsing earlier.

[common] Refactor quirks parsing. JB#52328
2021-03-18 11:44:03 +02:00
Eugenio Paolantonio (g7)
74c17e4dab [packaging] pulseaudio-modules-droid-dev: fix dependency on pulseaudio-modules-droid
Signed-off-by: Eugenio Paolantonio (g7) <me@medesimo.eu>
2021-03-13 19:18:47 +01:00
r3vn
88d0b2954a [ci] build using Drone CI 2021-03-02 23:50:32 +01:00
r3vn
3ab49846d2 Merge remote-tracking branch 'mer-hybris/master' into feature/bullseye/14.2.88 2021-03-02 23:49:27 +01:00
Matti Lehtimäki
2f14557d02
Merge pull request #99 from jusa/pa14.2
Update for PulseAudio 14.2.
2021-03-01 14:01:04 +02:00
Juho Hämäläinen
db423101e8 build: Stop using symdef headers for modules.
New simpler macro method does the trick now.
2021-03-01 13:58:22 +02:00
Juho Hämäläinen
5ff7642ca7 source: Remove code needed for versions below 12.
We are moving from 12.2 to 14.2, those are only versions we need to build
against.
2021-03-01 13:58:22 +02:00
Juho Hämäläinen
bbc921b9e5 sink: Remove code needed for versions below 12.
We are moving from 12.2 to 14.2, those are only versions we need to build
against.
2021-03-01 13:58:22 +02:00
Juho Hämäläinen
52711026c2 modules: Add missing include for pa_thread_make_realtime().
[modules] Add missing include. JB#47666
2021-03-01 13:58:22 +02:00
Matti Lehtimäki
7c8862acc4
Merge pull request #100 from mer-hybris/includedir
packaging: Support new droid-devel header location.
2021-02-26 18:20:56 +02:00
Matti Lehtimäki
59203f085e packaging: Support new droid-devel header location.
[packaging] Support new droid-devel header location. JB#51449
2021-02-26 15:07:52 +02:00
Ratchanan Srirattanamet
995913eaf3 add libevdev-dev as a build dependency 2021-01-14 14:07:19 +00:00
Ratchanan Srirattanamet
11697f2cc1 card: read headphone availability from input device
Recent Android devices start to provide headphone availability via input
device instead of h2w switch. This renders droid-extcon useless.

This commit introduce droid-extevdev, a simple code that will read
headphone availability from the input device, using libevdev as an
abstraction layer. This means the code now depends on libevdev (but it
can be made optional later on if needed).

This should make headphone availability works on newer Android devices
without having to resort to h2w kernel driver.
2021-01-14 14:07:19 +00:00
Ratchanan Srirattanamet
e84166816b Add virtual_voice_stream
Adding option to create voice virtual stream when voicecall is active
2021-01-14 14:07:19 +00:00
Alfred Neumayer
a784a5a8fa src: Add h2w detection code from pulseaudio-packaging
This applies changes from pulseaudio-packaging for detecting
headset & headphones via the h2w virtual switch file and udev.

Compared to pulseaudio-packaging this now forces udev as a requirement
rather than providing a compile-time switch.
2021-01-14 14:07:19 +00:00
NeKit
efea2f5e7f New upstream release 12.2.84 2021-01-14 14:07:19 +00:00
NeKit
a3d9a12b94 Add libexpat1-dev as build dependency (for XML config parsing) 2021-01-14 14:07:19 +00:00
TheKit
7090354d13 Branch packaging for Gemian 2021-01-14 14:07:19 +00:00
Jonah Brüchert
d991352f66 Detect pulseaudio version from the system, don't assume it's always the same as the droid module's one 2021-01-14 14:07:19 +00:00
Marius Gripsgard
2bd9ba3f7e Fix pkgconf for debian based systems.
Since debian based systems uses lib/{arch}/ as libdir and /usr/lib/pulse-* for modules this causes -L to search for -ldroid-utils in lib/{arch}/
2021-01-14 14:07:19 +00:00
Jonah Brüchert
69a12761d6 Fix pulseaudio droid module version 2021-01-14 14:07:19 +00:00
Jonah Brüchert
6d2dacec5b Release 12.2.79-2 2021-01-14 14:07:19 +00:00
Jonah Brüchert
83acc45987 Fix generating the pkgconfig files with proper pathes 2021-01-14 14:07:19 +00:00
Jonah Brüchert
9b4a813680 Release new upstream version 12.2.79-1 2021-01-14 14:07:19 +00:00
Jonah Brüchert
5024ba675d Release 12.2.78-1 2021-01-14 14:07:19 +00:00
Jonah Brüchert
da247905d2 New upstream release 12.2.78-1 2021-01-14 14:07:19 +00:00
Jonah Brüchert
a49e117ff7 New upstream release 11.1.76 2021-01-14 14:07:19 +00:00
Jonah Brüchert
209537d75f New upstream release 11.1.75 2021-01-14 14:07:19 +00:00
Jonah Brüchert
e9de637e3a Update Vcs information 2021-01-14 14:07:19 +00:00
Jonah Brüchert
beecdf67e9 Move .gitlab-ci.yml into debian folder 2021-01-14 14:07:19 +00:00
Jonah Brüchert
0d69581452 New upstream release (11.1.74) 2021-01-14 14:07:19 +00:00
Jonah Brüchert
c6f5ed1bed Make sure we install to the correct module path 2021-01-14 14:07:19 +00:00
Jonah Brüchert
44e9b517e6 Add GitLab ci configuration 2021-01-14 14:07:19 +00:00
JBBgameich
3b47553add New upstrem release (11.1.73) 2021-01-14 14:07:19 +00:00
JBBgameich
cbbaf3ab42 New upstream release 2021-01-14 14:07:19 +00:00
JBBgameich
6b1debc680 New upstream release 2021-01-14 14:07:19 +00:00
Bhushan Shah
e5f6f476a3 Revert "rules: Use $(overridden_command)"
This reverts commit 95860ffe29.
2021-01-14 14:07:19 +00:00
JBBgameich
268d4a1230 Remove unused parts according to lintian 2021-01-14 14:07:19 +00:00
JBBgameich
7d3f3cdc78 Run wrap-and-sort 2021-01-14 14:07:19 +00:00
JBBgameich
1707b34059 Update git repository url 2021-01-14 14:07:19 +00:00
JBBgameich
31aa7777d6 rules: Use $(overridden_command) 2021-01-14 14:07:19 +00:00
JBBgameich
407371a656 pulseaudio-module-droid-dev: update dependency name 2021-01-14 14:07:19 +00:00
JBBgameich
c0584f6dff Add workaround for proper path detection 2021-01-14 14:07:19 +00:00
JBBgameich
2d43babb6a New upstream release 11.1.68 2021-01-14 14:07:19 +00:00
JBBgameich
3ab10f1e45 Fix rules 2021-01-14 14:07:19 +00:00
JBBgameich
4568e2cf84 Rename to pulseaudio-module-droid 2021-01-14 14:07:19 +00:00
JBBgameich
15efaa50ff Remove fail-missing 2021-01-14 14:07:19 +00:00
JBBgameich
7003fef295 Fix clean step 2021-01-14 14:07:19 +00:00
JBBgameich
6ce6d707d5 Fix dependency name 2021-01-14 14:07:19 +00:00
JBBgameich
5348730a70 Add basic copyright 2021-01-14 14:07:19 +00:00
JBBgameich
050fd80a16 Initial commit 2021-01-14 14:07:18 +00:00
r3vn
fe0f517719 [packaging] fix missing files 2020-11-02 16:05:09 +01:00
r3vn
2ccbf14739 Merge branch 'upstream' into feature/bullseye/12.2.86 2020-10-30 00:11:03 +01:00
Juho Hämäläinen
22be43a324 Bump packaging version.
And remove Group from spec files.
2020-10-21 13:22:45 +03:00
Juho Hämäläinen
91e9bcbbe7
Merge pull request #98 from jusa/xml-includes
Support includes in module elements with xml configuration.
2020-10-21 13:19:41 +03:00
Juho Hämäläinen
b540528aab parser-xml: Support module includes in configuration files.
[parser-xml] Support module includes in configuration files. Fixes JB#51666
2020-10-21 07:56:25 +03:00
Juho Hämäläinen
d885b86121 parser-xml: Pass root element in parse_file().
Instead of setting it directly to struct parser_data. Also remove
unused root from the struct.
2020-10-20 11:12:11 +03:00
r3vn
7052e809f9 [packaging] fixed package name 2020-10-13 00:31:20 +02:00
Eugenio Paolantonio (g7)
2f5ddab8f4 [packaging] Build-depend on pulseaudio-pulsecore-dev
Signed-off-by: Eugenio Paolantonio (g7) <me@medesimo.eu>
2020-10-11 00:24:48 +02:00
r3vn
08afdc0932 build using travis-ci 2020-10-09 23:17:10 +02:00
Simonas Leleiva
dd83f69d87 Bump packaging version.
Signed-off-by: Simonas Leleiva <simonas.leleiva@jolla.com>
2020-06-22 16:18:54 +02:00
Simonas Leleiva
e46b8c7b0e
Merge pull request #97 from mer-hybris/64bit
Fix for 64bit
2020-06-22 15:17:12 +01:00
Simonas Leleiva
d8faa4a703 packaging: Fix for 64bit
[packaging] Fix for 64bit. JB#50285

Signed-off-by: Simonas Leleiva <simonas.leleiva@jolla.com>
2020-06-22 09:54:49 +02:00
Ratchanan Srirattanamet
bc67f05782 add libevdev-dev as a build dependency 2020-06-03 15:01:49 +02:00
Ratchanan Srirattanamet
5cab2af137 card: read headphone availability from input device
Recent Android devices start to provide headphone availability via input
device instead of h2w switch. This renders droid-extcon useless.

This commit introduce droid-extevdev, a simple code that will read
headphone availability from the input device, using libevdev as an
abstraction layer. This means the code now depends on libevdev (but it
can be made optional later on if needed).

This should make headphone availability works on newer Android devices
without having to resort to h2w kernel driver.
2020-06-03 13:51:08 +02:00
Ratchanan Srirattanamet
81504b9ec4 Add virtual_voice_stream
Adding option to create voice virtual stream when voicecall is active
2020-06-03 13:49:09 +02:00
Alfred Neumayer
0730b77e39 src: Add h2w detection code from pulseaudio-packaging
This applies changes from pulseaudio-packaging for detecting
headset & headphones via the h2w virtual switch file and udev.

Compared to pulseaudio-packaging this now forces udev as a requirement
rather than providing a compile-time switch.
2020-06-03 13:49:09 +02:00
NeKit
e5ba918cdb New upstream release 12.2.84 2020-06-03 01:55:32 +02:00
NeKit
0e120cf797 Merge remote-tracking branch 'mer/master' into buster 2020-06-03 01:54:22 +02:00
Juho Hämäläinen
72d4e0aaca Bump packaging version. 2019-12-10 10:48:34 +02:00
Juho Hämäläinen
dcb0b67f67
Merge pull request #96 from jusa/jb47194
Improve audio mode changes.
2019-12-10 10:47:19 +02:00
Juho Hämäläinen
08c4558f15 common: Always set earpiece routing after enabling voice call mode.
Mode change is applied only after next set_parameters call with route
is made. Usually it's ok to switch to whatever route after mode switch
but some devices don't like it and we end up with silent audio. To work
around these devices always set earpiece as the initial route after
mode change. Correct route is then applied later when other parts of
the system decide what the route should be.

[common] Always set earpiece routing after enabling voice call mode. Fixes JB#47194
2019-12-09 13:48:23 +02:00
Juho Hämäläinen
976a6cf58c card: Park profiles correctly when switching between virtual profiles.
Virtual profiles don't have output or input mappings so calling park_profile()
for one is no-op. To correctly park the sink and source ports we need to call
park_profiles() for the last active real profile.

[card] Park profiles correctly when switching between virtual profiles. JB#47194
2019-12-09 13:44:31 +02:00
Juho Hämäläinen
b36b2431fb common: Remove unused variables. 2019-12-09 13:33:04 +02:00
NeKit
fa0e8a5535 Add libexpat1-dev as build dependency (for XML config parsing) 2019-11-20 00:24:54 +01:00
Juho Hämäläinen
90ca699176 Bump packaging version. 2019-11-19 15:47:29 +02:00
Juho Hämäläinen
25abbb4388
Merge pull request #95 from jusa/input-fixes
Input fixes
2019-11-19 15:46:09 +02:00
Juho Hämäläinen
ca93e01a91 README: Add description for two new quirks. 2019-11-19 15:21:29 +02:00
Juho Hämäläinen
8ed068f68b card: Don't create fast or deep buffer sinks if disabled by quirks. 2019-11-19 15:21:29 +02:00
Juho Hämäläinen
6986d9bf06 common: Add two new quirks and set them enabled by default.
When the quirks are enabled everything works the same as before. Setting
them disabled will affect the behaviour.

[common] Add quirks for FAST and DEEP_BUFFER sinks. JB#48097
2019-11-19 15:21:25 +02:00
Juho Hämäläinen
bfd377a109 common: Check for right pointers in asserts. 2019-11-19 15:21:25 +02:00
Juho Hämäläinen
9d5226d841 parser-xml: Refactor element list frees. 2019-11-19 15:21:25 +02:00
Juho Hämäläinen
9936dfa44f parser-xml: Store profiles correctly for mix and device ports.
[parser-xml] Store profiles correctly for mix and device ports.
2019-11-19 15:21:25 +02:00
Juho Hämäläinen
0e60d133c6 source: Don't cast function pointers. 2019-11-19 15:21:25 +02:00
Juho Hämäläinen
0af48ffd73 source: Reconfigure source to last connected source-output.
When source-output is disconnected from our source reconfigure
to previously connected source-output if applicable.
2019-11-19 15:21:25 +02:00
Juho Hämäläinen
5aeee81b49 source: Reconfigure source if port is changed while source is running.
To ensure proper stream configuration with updated routing
reconfigure running stream on port change.
2019-11-19 15:21:25 +02:00
Juho Hämäläinen
de0d98e6d5 source: Add a workaround for fm-radio loopback.
Refactor reconfiguring part a bit and add a workaround for fm-radio
loopback. As the loopback module is instantiated without defined sink
or source, it uses as default really silly values. But since our source
is reconfiguring itself to whatever is requested things get a bit
hairy. To ensure good values for the source in case of loopback module
connection use metrics from our primary output stream.

[source] Add a workaround for fm-radio loopback. JB#48080
2019-11-19 15:20:47 +02:00
Juho Hämäläinen
44e7b1479d source: Have input stream in correct state after startup. 2019-11-19 15:20:47 +02:00
Juho Hämäläinen
124139f5b9 common: Try opening input stream with defaults before giving up.
[common] Revert to default values if input stream reconfigure fails.
2019-11-19 15:20:14 +02:00
Juho Hämäläinen
a46a5c91a1 common: Use device definition with config fill function. 2019-11-19 15:20:14 +02:00
Juho Hämäläinen
3192069095 common: Store initial input stream metrics as defaults.
And if reconfiguration fails restore defaults instead of
previously used values.
2019-11-19 15:20:14 +02:00
Juho Hämäläinen
a2eb4143ef common: Apply input route immediately after creating input stream.
With some adaptations audio_source_t does not have any effect when
opening the input stream. To ensure proper routing we need to set
input parameters immediately after opening the stream just in case.
2019-11-19 15:20:14 +02:00
Juho Hämäläinen
7b531dfff9 common: Improve stream config fill function for input streams.
We need to be more careful with input streams as due to dynamic
source reconfiguring it may be that bizarre combinations are requested.
Try to make sure that sane combination is actually requested when
opening the input stream.
2019-11-19 15:20:14 +02:00
Juho Hämäläinen
c7a62db215 common: Use device definition when creating output stream. 2019-11-19 15:20:14 +02:00
Juho Hämäläinen
8bc33cfb25 sink: Use device definition regardless of operation mode.
Use device definition for needed info for both standalone mode
and when run under droid card.
2019-11-19 15:20:14 +02:00
Juho Hämäläinen
1151993324 common: Store device definition to droid stream. 2019-11-19 15:20:14 +02:00
Juho Hämäläinen
4afa908867 common: Make primary output stream lookup function public. 2019-11-19 15:20:14 +02:00
Juho Hämäläinen
24e3661259 config: Lookup output or input modules by name. 2019-11-19 15:20:14 +02:00
Juho Hämäläinen
82b46a9ec4 conversion: Add generic string lookup. 2019-11-19 15:20:14 +02:00
Juho Hämäläinen
fcb720b6a3 source: Use reconfigure instead of freeing and re-creating stream.
[source] Reconfigure stream instead of freeing and re-creating.
2019-11-19 15:19:45 +02:00
Juho Hämäläinen
caead9d18c common: Allow reconfiguring input stream.
Instead of needing to free the input stream completely to
reconfigure its metrics allow reconfiguring in-place. Rollback
to previous good values on failure.
2019-11-18 15:52:54 +02:00
Juho Hämäläinen
39fdb85b13 common: Use correct pointer when logging input stream. 2019-11-15 16:28:53 +02:00
Juho Hämäläinen
3ba217920b common: Log input device names when setting new value. 2019-11-15 16:28:53 +02:00
Juho Hämäläinen
1866de8e8d common: Refactor input stream closing a bit. 2019-11-15 16:28:53 +02:00
Juho Hämäläinen
1f6e402f82 common: Refactor stream standby calls. 2019-11-15 16:28:48 +02:00
TheKit
1787c87407 Branch packaging for Gemian 2019-11-13 22:29:18 +01:00
Jonah Brüchert
58d1e45090 Detect pulseaudio version from the system, don't assume it's always the same as the droid module's one 2019-11-13 13:12:02 +01:00
Marius Gripsgard
c5cca5314f Fix pkgconf for debian based systems.
Since debian based systems uses lib/{arch}/ as libdir and /usr/lib/pulse-* for modules this causes -L to search for -ldroid-utils in lib/{arch}/
2019-11-13 13:10:06 +01:00
TheKit
5edb6d17e8 Merge remote-tracking branch 'debian-pm/master' 2019-11-13 13:05:53 +01:00
Juho Hämäläinen
6b9b141ac8 modules: Log when creating.
Easier to spot the log of single entity.
2019-11-13 10:57:43 +02:00
Jonah Brüchert
b5972a7dcc
Fix pulseaudio droid module version 2019-11-12 12:35:59 +01:00
Jonah Brüchert
940476a773
Release 12.2.79-2 2019-11-12 12:06:58 +01:00
Jonah Brüchert
2b9ac12840
Fix generating the pkgconfig files with proper pathes 2019-11-12 12:05:02 +01:00
Juho Hämäläinen
a574c42d7c Bump packaging version. 2019-11-11 09:59:30 +02:00
Juho Hämäläinen
9363d97953
Merge pull request #94 from mer-hybris/jb48080
common: Add missing configuration file search locations.
2019-11-11 09:58:09 +02:00
Matti Lehtimäki
11ea0a60bd common: Add missing configuration file search locations.
[common] Add missing configuration file search locations. JB#48080
2019-11-11 14:47:20 +07:00
Juho Hämäläinen
3ee8e16ad3 Bump packaging version. 2019-10-09 15:02:54 +03:00
Juho Hämäläinen
d10db89b9f Merge branch 'license' 2019-10-09 11:39:22 +03:00
MikeSalmela
033ad34ca6 license: Fix license in spec.
[license] Fix license in spec. JB#45486
2019-10-09 11:28:48 +03:00
Juho Hämäläinen
efb1bcf8cc Merge branch 'pulse-13-compat' 2019-10-09 11:18:26 +03:00
Alexey Min
21b3c42db7 modules: Fix compatibility with PulseAudio 13.0.
There were some API changes:
 - 878ef44079
 - 6665b466d2

Leading to:
 Error relocating /usr/lib/pulse-13.0/modules/libdroid-sink.so: pa_make_realtime: symbol not found
 Error relocating /usr/lib/pulse-13.0/modules/libdroid-source.so: pa_make_realtime: symbol not found
 Error relocating /usr/lib/pulse-13.0/modules/libdroid-source.so: pa_source_get_state: symbol not found

Fixes are:
 - include <pulse/util.h>, replace pa_make_realtime -> pa_thread_make_realtime
 - replace pa_source_get_state(X) -> X->state
 - replace pa_sink_get_state(X) -> X->state

[modules] Fix compatibility with PulseAudio 13.0. JB#47666
2019-10-09 11:18:21 +03:00
Juho Hämäläinen
97a0c98f84 README: Update keepalive state. 2019-10-09 11:18:08 +03:00
Juho Hämäläinen
e099a0884e packaging: Add require for pulseaudio-module-keepalive. 2019-10-09 10:58:15 +03:00
Juho Hämäläinen
48a96e89ce packaging: No more keepalive, nothing needs D-Bus. 2019-10-09 10:56:52 +03:00
Juho Hämäläinen
89cdbb8be7 build: Nothing needs D-Bus. 2019-10-09 10:56:52 +03:00
Juho Hämäläinen
c16bfaa1ce keepalive: Remove module.
[keepalive] Module relocated to its own package. JB#47579

Module relocated to its own package pulseaudio-module-keepalive.
2019-10-09 10:56:19 +03:00
Juho Hämäläinen
adebe47929 Bump packaging version. 2019-10-08 14:23:16 +03:00
Juho Hämäläinen
772b9ca3f1
Merge pull request #92 from jusa/input
Rewrite input stream handling.
2019-10-08 14:22:21 +03:00
Juho Hämäläinen
9d5daf5f87 modules: No point in supporting anything older than PulseAudio 10. 2019-10-08 13:23:53 +03:00
Juho Hämäläinen
ea451e9879 common: Recognize some more input flags. 2019-10-08 13:07:21 +03:00
Juho Hämäläinen
97e2ec2e11 build: Check for some more input flags. 2019-10-08 13:07:02 +03:00
Juho Hämäläinen
95c37782c3 source: Use mic control functions from common. 2019-10-07 17:12:30 +03:00
Juho Hämäläinen
1d47383623 README: Add description of reconfiguring droid source. 2019-10-07 11:33:46 +03:00
Juho Hämäläinen
9f27eaed6a card: Allow selecting whatever module when not using default profile. 2019-10-07 11:33:46 +03:00
Juho Hämäläinen
c6b8807fac common: Fix creating old-style profiles.
At some point in history creating old-style profiles got broken,
resulting in segfault when enabling.
2019-10-07 11:33:46 +03:00
Juho Hämäläinen
ba839c52f4 common: Don't create extra profiles with default profile.
We don't need the extra profiles for anything in normal use,
they are just a way to debug profile and hal module handling.
Debugging can still be achieved by using module profiles,
for example with profile=primary
2019-10-07 11:33:46 +03:00
Juho Hämäläinen
1ce36525e0 card: Fix some unused variable warnings. 2019-10-07 11:33:46 +03:00
Juho Hämäläinen
841fa93a03 source: Try to function even if stream reconfiguration fails.
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.
2019-10-07 11:33:46 +03:00
Juho Hämäläinen
367a587453 source: Format debug log line better. 2019-10-07 11:33:46 +03:00
Juho Hämäläinen
0708ad905d source: Remove obsolete comment. 2019-10-07 11:33:46 +03:00
Juho Hämäläinen
70b624d663 source: Implement dynamic source.
When new source-output is connecting to our droid source
we check if its sample specification or channel map differ
from currently configured source. If they differ close the
input stream and try to open with the new values. If opening
new input stream fails retry opening with previously used
values.

When there already is one or more connected source-outputs
and a new one connects, source is always reconfigured based
on the latest connecting source-output. Already connected
source-outputs will then reattach so that if need be they
will use resampler to get what they originally requested.

[modules-droid] Source is reconfigured dynamically based on input. Fixes JB#47579
2019-10-07 11:33:33 +03:00
Jonah Brüchert
6803ef07e7
Release new upstream version 12.2.79-1 2019-10-06 15:23:59 +02:00
Juho Hämäläinen
185fb1add0 source: Tag this source always as both builtin and external. 2019-10-03 17:04:27 +03:00
Juho Hämäläinen
4d5c17bed0 source: Set real sample spec and channel map values. 2019-10-03 17:04:27 +03:00
Juho Hämäläinen
f69afe38c6 source: Use new function for opening input stream. 2019-10-03 17:04:27 +03:00
Juho Hämäläinen
57b1848dbf card: Use set mode function from common. 2019-10-03 17:04:27 +03:00
Juho Hämäläinen
c93ea363b2 common: Reimplement mode change and input stream routing. 2019-10-03 17:04:27 +03:00
Juho Hämäläinen
fc250744f4 common: Pre-increment output id. 2019-10-03 17:04:27 +03:00
Juho Hämäläinen
b1cf9bfcdc common: Input stream is always primary.
There can be only one.
2019-10-03 17:04:27 +03:00
Juho Hämäläinen
2bbeb30522 common: Rewrite input stream opening. 2019-10-03 17:04:25 +03:00
Juho Hämäläinen
2a7dba4d5c common: Add microphone mute control to common lib. 2019-10-03 16:47:59 +03:00
Juho Hämäläinen
98b7553bc8 common: Add helpers for getting current stream metrics. 2019-10-03 16:45:51 +03:00
Juho Hämäläinen
87e36be31e source: Remove droid hooks and resampler code.
Part of rewriting input handling.
2019-10-03 11:36:40 +03:00
Juho Hämäläinen
26bf0ee2ca common: Remove droid hooks.
Part of rewriting input handling.
2019-10-03 11:36:11 +03:00
Juho Hämäläinen
5a47cc2c56 card: There can be only one source at maximum. 2019-10-03 11:29:35 +03:00
Juho Hämäläinen
24bcbbd373 source: Use modified device struct. 2019-10-03 11:28:26 +03:00
Juho Hämäläinen
cd3465b2f2 common: Always use only one input.
Android by design only allows one input at a time so previous
adaptations where we could record to input sources at the same
time was a coincidence. Line the implementation with how the
input handling is defined.

[common] Always use only one input. JB#45496
2019-10-03 11:28:07 +03:00
Juho Hämäläinen
09c3cca84e
Merge pull request #91 from jusa/voicemmode
Refactor virtual profiles and add voicemmode 1 and 2 profiles.
2019-08-09 13:49:37 +03:00
Juho Hämäläinen
f7850df526 card: Improve virtual profiles implementation.
Previously only one profile could extend previous one, with new
implementation one virtual profile can have as many extensions as is
needed. But only two levels of virtual profiles is supported, that
is virtual1->virtual1-exetension.
2019-08-09 10:17:16 +03:00
Juho Hämäläinen
77de8c289a card: Enable voicecall-record profile always with voicecall. 2019-08-09 10:17:16 +03:00
Juho Hämäläinen
3df73147d9 card: Add voicemmode 1 and 2 for debugging purposes.
Add virtual profiles voicecall-voicemmode1 and voicecall-voicemmode2 for
debugging purposes to droid card.

[card] Add voicemmode 1 and 2 virtual profiles. JB#46805
2019-08-09 10:16:32 +03:00
Juho Hämäläinen
96c4e2ea97 Bump packaging version. 2019-05-15 11:46:47 +03:00
Juho Hämäläinen
3a195e0929
Merge pull request #88 from jusa/dev
Fix segfaults with bad input in xml parser and refactor conversion header a bit.
2019-05-15 11:39:23 +03:00
Juho Hämäläinen
0861b3beff xml-parser: Don't allocate unhandled element data. 2019-05-14 17:16:30 +03:00
Juho Hämäläinen
abf4c9037b README: Update enum check example. 2019-05-13 11:54:03 +03:00
Juho Hämäläinen
1e41bf5a45 source: Make sure proper silence byte is used.
Most of the time 0 is right but there are (uncommon) cases
when it is not.

[source] Use format specific silence byte when needed.
2019-05-13 10:11:46 +03:00
Juho Hämäläinen
f032e4a37b common: Use entry macros instead of ifdeffing. 2019-05-13 10:11:46 +03:00
Juho Hämäläinen
13b3ed1a75 build: Generate entry macros as well. 2019-05-13 10:11:46 +03:00
Juho Hämäläinen
0fdfef668d build: Use correct channel input channel names. 2019-05-13 10:11:46 +03:00
Juho Hämäläinen
ab883c792b module-droid-source: Add config as valid module argument. 2019-05-13 10:11:46 +03:00
Juho Hämäläinen
a9566c26b3 module-droid-sink: Add config as valid module argument. 2019-05-13 10:11:46 +03:00
Juho Hämäläinen
73bf39a07a droid-sink: Don't free config twice. 2019-05-13 10:11:46 +03:00
Juho Hämäläinen
07df5e6953 xml-parser: Avoid segfault if root node is not defined.
[xml-parser] Behave better with badly formatted input.
2019-05-13 10:11:29 +03:00
Jonah Brüchert
ec3260a88f
Release 12.2.78-1 2019-04-25 22:37:48 +02:00
Jonah Brüchert
a61a670284
New upstream release 12.2.78-1 2019-04-25 22:37:32 +02:00
Juho Hämäläinen
b4414fb5a1 Bump packaging version. 2019-04-04 11:54:38 +03:00
Juho Hämäläinen
4a558ba35f
Merge pull request #87 from jusa/jb44329
droid-sink droid-source: Return from process_msg only on error.
2019-04-04 11:53:30 +03:00
Juho Hämäläinen
f652f1f52a droid-sink droid-source: Return from process_msg only on error.
When updating the implementation to support PulseAudio 12.2 the handling
of sink/source process msg function with older PulseAudio versions
incorrectly returns always, when that should only be done in case of
error.

[modules-droid] Update sink/source state correctly with PulseAudio 11.1. JB#44329
2019-04-04 11:11:52 +03:00
Juho Hämäläinen
b1ce02b3d6
Merge pull request #86 from jusa/pa12.2
Update to support PulseAudio 12.2.
2019-03-22 13:23:24 +02:00
Juho Hämäläinen
8ff57cbc0d packaging: Bump module version.
[modules-droid] Update to support PulseAudio 12.2. JB#42201
2019-03-22 10:41:50 +02:00
Juho Hämäläinen
c3c456db8b droid-source: Update state setting to PulseAudio 12.2 style. 2019-03-22 10:41:50 +02:00
Juho Hämäläinen
3210023c94 droid-sink: Update state setting to PulseAudio 12.2 style. 2019-03-22 10:41:48 +02:00
Jonah Brüchert
ad620b712a
New upstream release 11.1.76 2018-12-03 21:39:37 +01:00
Juho Hämäläinen
b00bc7c3ea Bump packaging version. 2018-11-15 16:15:51 +02:00
Juho Hämäläinen
2e3e5c8977
Merge pull request #85 from jusa/jb43836
Fix voicecall recording on Jolla1.
2018-11-15 16:15:00 +02:00
Juho Hämäläinen
aa28d5935d [sbj] Add missing define to fix voicecall recording. Fixes JB#43836
When refactoring code for XML configuration parsing QCOM_HARDWARE define
was lost on Jolla1. This broke at least voicecall recording.
2018-11-15 15:34:20 +02:00
Jonah Brüchert
8ef0e32e18
New upstream release 11.1.75 2018-11-13 21:18:48 +01:00
Jonah Brüchert
05a5925baf
Update Vcs information 2018-11-02 19:14:50 +01:00
Juho Hämäläinen
781d8fa842 Bump packaging version. 2018-11-01 14:51:19 +02:00
Juho Hämäläinen
281c000b04
Merge pull request #84 from jusa/xml_parser
Be less strict about module element parsing.
2018-11-01 14:49:16 +02:00
Juho Hämäläinen
9f5da93e9c [xml-parser] Be less strict in parsing module attributes. JB#42564
We are not yet using any of the information in module element anywhere
anyway.
2018-11-01 14:41:39 +02:00
Jonah Brüchert
f293111905
Move .gitlab-ci.yml into debian folder 2018-10-24 18:17:10 +02:00
Jonah Brüchert
addd9f1adc
New upstream release (11.1.74) 2018-10-13 20:53:09 +02:00
Jonah Brüchert
6355803c66
Make sure we install to the correct module path 2018-10-13 20:52:37 +02:00
Jonah Brüchert
ed595dec5b
Add GitLab ci configuration 2018-10-07 00:52:19 +02:00
Juho Hämäläinen
c60108b799
Merge pull request #83 from jusa/jb43235
Add unload_call_exit quirk.
2018-10-05 11:26:49 +03:00
Juho Hämäläinen
d8a3c42f06 [README] Add description for unload_call_exit quirk. 2018-10-05 11:05:08 +03:00
Juho Hämäläinen
c502e04d6f [source] Free config after use. 2018-10-05 11:05:08 +03:00
Juho Hämäläinen
ee53393fff [sink] Free config after use. 2018-10-05 11:05:08 +03:00
Juho Hämäläinen
e486eeaaee [card] Free config after use. 2018-10-05 11:05:08 +03:00
Juho Hämäläinen
0ac35e1246 [common] Duplicate config for hw module.
Instead of transferring ownership just duplicate the
configuration.
2018-10-05 11:05:08 +03:00
Juho Hämäläinen
81a43e7b5e [common] Add function to duplicate configuration. 2018-10-05 11:05:08 +03:00
Juho Hämäläinen
8e1db64cd9 [card] Use common pattern of getting hw module.
Try to get module first without configuration and
if the module doesn't exist yet load config and
try again.
2018-10-05 11:05:08 +03:00
Juho Hämäläinen
1d4ebe363f [common] Be less verbose about missing config.
This was probably a call to pa_droid_hw_module_get()
with NULL config intentionally.
2018-10-05 11:05:08 +03:00
Juho Hämäläinen
c0a609aa7d [common] Add quirk unload_call_exit. JB#43235
Instead of closing the hw device call exit(0). This way
we can prevent possible strange segfaults from trying
to close the device and get rid of false crashes.
2018-10-05 11:05:05 +03:00
Juho Hämäläinen
929c3fdd6c [keepalive] Update state properly.
If keepalive is started after sinks or sources are
already created make sure the bookkeeping is correct.
2018-10-05 08:36:37 +03:00
JBBgameich
9d09908b82 New upstrem release (11.1.73) 2018-08-28 18:57:12 +02:00
JBBgameich
36c03408c1 New upstream release 2018-08-28 18:24:35 +02:00
JBBgameich
8ad1d210a8 New upstream release 2018-08-28 18:24:35 +02:00
Juho Hämäläinen
7c7caed93b Bump packaging version. 2018-08-28 14:30:41 +03:00
Juho Hämäläinen
aeae77a3d0
Merge pull request #81 from jusa/xml_audio_policy
Make sure QCOM_HARDWARE is defined when needed.
2018-08-28 14:29:43 +03:00
Juho Hämäläinen
4486d27741 [common] Make sure QCOM_HARDWARE is defined when needed. JB#42564
Droid headers define different things sometimes if QCOM_HARDWARE is
defined. Make sure that before including hardware/audio.h either
version.h or android-config.h is included so that the define is
correctly set if needed.
2018-08-28 14:02:02 +03:00
Bhushan Shah
ec084f07a2 Revert "rules: Use $(overridden_command)"
This reverts commit 95860ffe29.
2018-08-27 09:40:14 +05:30
Juho Hämäläinen
b0af01b59b Bump packaging version. 2018-08-23 13:02:42 +03:00
Juho Hämäläinen
59b44fd22c
Merge pull request #80 from jusa/xml_audio_policy
Fixes to primary output handling and some refactoring.
2018-08-23 12:59:49 +03:00
Juho Hämäläinen
ba435cd02e [packaging] Remove obsolete header and pc file installs. 2018-08-23 12:36:38 +03:00
Juho Hämäläinen
6847b165b6 [build] Install common headers and pc file properly. 2018-08-23 12:36:38 +03:00
Juho Hämäläinen
4ba7a2b4bf [modules] Update includes. 2018-08-23 12:36:38 +03:00
Juho Hämäläinen
4aab3b946b [common] Move public headers to include/droid 2018-08-23 12:36:38 +03:00
Juho Hämäläinen
f9839f608c [common] Use global include with public headers. 2018-08-23 12:36:38 +03:00
Juho Hämäläinen
4fb2ce754d [common] Remove sllist implementation to own header. 2018-08-23 11:09:13 +03:00
Juho Hämäläinen
d13b417421 [config] Refactor hw module creation. 2018-08-23 11:00:52 +03:00
Juho Hämäläinen
cf69ae6eee [xml-parser] More generic channel mask direction workaround. JB#42564
Seems that channel mask direction errors are more frequent than initially
thought, so just switch the direction for all errors before parsing the
mask value.
2018-08-22 14:19:07 +03:00
Juho Hämäläinen
a4c549ea9b [config] Reorder configuration file search locations. JB#42564 2018-08-22 14:19:07 +03:00
Juho Hämäläinen
7617f1927f [README] Add note about xml parsing. 2018-08-22 14:19:05 +03:00
Juho Hämäläinen
f9d1eaf6f9 [common] Remove unused config functions. 2018-08-22 14:09:54 +03:00
Juho Hämäläinen
c42b572dd5 [common] Combine output and input configurations. 2018-08-22 14:09:51 +03:00
Juho Hämäläinen
226758abca [common] Check for primary flag instead of string. JB#42564
Use flags for determining if output is primary instead of
matching a string. For inputs there really isn't a primary
input flag in HAL side but for our needs just looking for
prefix is enough.
2018-08-20 11:28:52 +03:00
Juho Hämäläinen
be5bdbd0c6 [common] Check for SPEAKER_DRC_ENABLED_TAG directly. JB#42564
No need to have separate define, just check for the needed macro
directly.
2018-08-20 11:19:50 +03:00
Juho Hämäläinen
46bac3e0b0 Merge branch 'input_flags' 2018-08-15 16:02:06 +03:00
Juho Hämäläinen
624fe0c163 [parser-xml] No need to idfef input flags. 2018-08-15 15:58:10 +03:00
Juho Hämäläinen
ee37da7b17 [common] Use uint32_t for input flags. JB#42564 2018-08-15 15:57:47 +03:00
Juho Hämäläinen
75239fdf83 [sbj] Add empty input flag struct.
Add missing struct so that we don't need to ifdef around the
structure usage elsewhere.
2018-08-15 15:57:02 +03:00
Juho Hämäläinen
9541b1e23e
Merge pull request #79 from jusa/sbj_build_fix
Fix build for Jolla1
2018-08-15 15:13:55 +03:00
Juho Hämäläinen
8ed98f9884 Bump packaging version. 2018-08-15 14:52:53 +03:00
Juho Hämäläinen
461dc48651 [sbj] Disable xml explicitly. 2018-08-15 14:52:01 +03:00
Juho Hämäläinen
317791c166 [build] Add workaround for SBJ HAL headers. JB#42564
Workaround for multiple definitions of variables from SBJ HAL headers.
2018-08-15 14:50:18 +03:00
Juho Hämäläinen
09085a8d38 [sbj] Add missing include. 2018-08-15 14:49:28 +03:00
Juho Hämäläinen
27c78eccb2 [conversion] Disable input flags for API 1 and 2. JB#42564 2018-08-15 14:49:01 +03:00
Juho Hämäläinen
5e73225f30 Bump packaging version. 2018-08-15 12:58:07 +03:00
Juho Hämäläinen
ff10cc7c62
Merge pull request #78 from jusa/xml_audio_policy
Implement parser for xml style audio policy configuration.
2018-08-15 12:56:19 +03:00
Juho Hämäläinen
7c3e431cb9 [module-droid-sink] Include conversion header. 2018-08-15 12:50:52 +03:00
Juho Hämäläinen
84a6e0a1e3 [modules] Update contact information. 2018-08-15 12:50:52 +03:00
Juho Hämäläinen
5881fe466e [packaging] Build requires expat. JB#42564 2018-08-15 12:50:52 +03:00
Juho Hämäläinen
58415a51a4 [build] Use expat. 2018-08-15 12:50:52 +03:00
Juho Hämäläinen
a6beecbbda [xml-parser] Add workaround for certain config error. JB#42564 2018-08-15 12:50:52 +03:00
Juho Hämäläinen
8c13d39139 [xml-parser] Drop include parsing for now.
We are not really interested in modules other than primary for now. As
long as primary is defined in the main configuration xml file we don't
need to parse the includes.
2018-08-15 12:50:52 +03:00
Juho Hämäläinen
d467c1ec94 [source] Include conversion header. 2018-08-15 12:50:52 +03:00
Juho Hämäläinen
97a4ed6d4a [sink] Include conversion header. 2018-08-15 12:50:52 +03:00
Juho Hämäläinen
e3fcfad49b [conversion] Add workarounds for format and device parsing. JB#42564 2018-08-15 12:50:51 +03:00
Juho Hämäläinen
cbc81a6a85 [xml-parser] New parser for xml style configuration. Fixes JB#42564 2018-08-15 12:50:49 +03:00
Juho Hämäläinen
a6192378cd [xml-parser] Placeholder for xml parser implementation. 2018-08-14 15:31:23 +03:00
Juho Hämäläinen
66482f806a [build] Add test for expat. JB#42564 2018-08-14 15:31:23 +03:00
Juho Hämäläinen
25cf33bfc5 [legacy-parser] Allocate config in parser. 2018-08-14 15:31:23 +03:00
Juho Hämäläinen
b629362685 [config] Allocate config in parsing functions. 2018-08-14 15:31:23 +03:00
Juho Hämäläinen
3f95b1bcc4 [common] Split configuration parsing to multiple files. 2018-08-14 15:31:21 +03:00
JBBgameich
5573d62ebe
Remove unused parts according to lintian 2018-07-04 14:21:03 +02:00
JBBgameich
88c2be2333 Run wrap-and-sort 2018-06-24 16:19:11 +00:00
JBBgameich
ffee6f91fc Update git repository url 2018-06-22 19:22:01 +00:00
JBBgameich
95860ffe29 rules: Use $(overridden_command) 2018-06-19 19:43:40 +02:00
JBBgameich
12185c8601 pulseaudio-module-droid-dev: update dependency name 2018-06-08 17:20:50 +00:00
JBBgameich
32edc3fea0 Add workaround for proper path detection 2018-06-06 15:01:08 +00:00
JBBgameich
736a82a7a1 New upstream release 11.1.68 2018-06-06 14:06:27 +00:00
JBBgameich
9e5b1fa04a Fix rules 2018-06-03 10:33:56 +00:00
JBBgameich
1a7bf9de98 Rename to pulseaudio-module-droid 2018-06-03 09:08:01 +00:00
Juho Hämäläinen
af15b21318
Merge pull request #77 from jusa/jb42043
Use portable module lib path.
2018-05-30 16:12:42 +03:00
Juho Hämäläinen
42a556a67a [build] Use portable module lib path. JB#42043 2018-05-30 15:32:26 +03:00
Juho Hämäläinen
6db07aea72
Merge pull request #76 from jusa/mer1908
Add realcall quirk.
2018-05-30 15:31:58 +03:00
Juho Hämäläinen
8f9145929e Bump packaging version. 2018-05-29 11:37:57 +03:00
Juho Hämäläinen
06f560e256 [README] Add description for realcall quirk. 2018-05-29 11:37:57 +03:00
Juho Hämäläinen
fafaa025d8 [common] Make pa_droid_quirk inline function. 2018-05-29 11:37:57 +03:00
Juho Hämäläinen
9a4165f42d [card] Apply specific parameters when realcall quirk is enabled. MER#1908 2018-05-29 11:37:48 +03:00
Juho Hämäläinen
3c086db834 [common] Add quirk realcall. MER#1908 2018-05-29 11:37:27 +03:00
JBBgameich
c31ce84c0f Remove fail-missing 2018-05-27 00:10:39 +02:00
JBBgameich
672f6a9455 Fix clean step 2018-05-26 22:31:21 +02:00
JBBgameich
91dbb2459e Fix dependency name 2018-05-26 22:03:45 +02:00
JBBgameich
48756afc70 Add basic copyright 2018-05-26 20:58:02 +02:00
JBBgameich
4edf08d933 Initial commit 2018-05-26 20:51:54 +02:00
Juho Hämäläinen
030586126c Bump packaging version. 2018-05-16 17:44:59 +03:00
Juho Hämäläinen
296a4840ed
Merge pull request #75 from jusa/jb41899
Add quirk output_make_writable.
2018-05-16 17:43:55 +03:00
Juho Hämäläinen
473116ee34 [README] Add description for output_make_writable quirk. 2018-05-16 17:14:33 +03:00
Juho Hämäläinen
c826746b20 [sink] Implement output_make_writable quirk. JB#41899
Make memchunk writable if the quirk is enabled.
2018-05-16 17:05:05 +03:00
Juho Hämäläinen
a2b0179c31 [common] Add quirk output_make_writable. JB#41899
Some implementations modify write buffer in-place which
can segfault PulseAudio as it assumes that write buffer
is not touched. Add quirk to make sure that the write
buffer can be safely modified.
2018-05-16 17:04:43 +03:00
Juho Hämäläinen
642644abe2 Bump packaging version. 2018-02-17 12:31:33 +02:00
Juho Hämäläinen
1bc9b9ade0
Merge pull request #73 from jusa/pa11.1
Update to PulseAudio 11.1.
2018-02-17 12:26:31 +02:00
Juho Hämäläinen
bfe94c0fec [source] Post silence if resuming input stream fails.
Some input route changes might fail a couple of times
if done too soon after voice call ends, so if resuming
suspended stream fails post silence and try again until
we get proper input stream again.
2018-02-15 16:04:59 +02:00
Juho Hämäläinen
e3e0937e4d [common] Decrease verbosity of failing input resume. 2018-02-15 15:56:37 +02:00
Juho Hämäläinen
ab92999a08 [card] Update to PulseAudio 11.1. JB#38694 2018-02-13 14:09:55 +02:00
Juho Hämäläinen
e013a5b2ee
Merge pull request #72 from jusa/jb40125
Fix input profile actions with merged input mapping.
2018-02-06 11:08:33 +02:00
Juho Hämäläinen
43e266d7de [packaging] Bump version. 2018-02-05 17:33:02 +02:00
Juho Hämäläinen
49f5a5aa1c [card] Update record profile correctly with merged input. JB#40125 2018-02-05 17:33:00 +02:00
Juho Hämäläinen
51731c9578 [common] Get mapping based on device. 2018-02-05 17:13:06 +02:00
Juho Hämäläinen
865805121a [sink] Use pa_memblock_acquire_chunk.
Convenience function so that we don't need to do
indexing ourselves.
2017-12-19 11:49:45 +02:00
Juho Hämäläinen
12b0f79ccb [packaging] Bump version. JB#40125 2017-12-18 13:10:08 +02:00
Juho Hämäläinen
f4536d12d5
Merge pull request #71 from jusa/jb40292
Set input stream to standby before closing and add new quirk.
2017-12-11 17:39:56 +02:00
Juho Hämäläinen
e754b2c768 [README] Add description for no_hw_volume quirk. 2017-12-11 17:24:18 +02:00
Juho Hämäläinen
3bf80c8a0f [sink] Allow disabling hw volume control with quirk. JB#40292
Some implementations define set_volume() callback and return
NO_ERROR from calling that, when API documentation says that
if the implementation doesn't really use hw volume control that
callback should be NULL (or return other than NO_ERROR at least).

To behave correctly with these broken implementations use
quirk no_hw_volume for disabling hw volume control when needed.
2017-12-11 16:21:05 +02:00
Juho Hämäläinen
eaf5c5bb2a [common] Add new quirk no_hw_volume. JB#40292
Add quirk for forcing no hw volume control for output
streams.
2017-12-11 16:16:41 +02:00
Juho Hämäläinen
5ffa53c1d5 [common] Set input stream to standby before closing. JB#40125
Some implementations don't like to close the input stream
if the stream is not in standby.
2017-12-11 16:16:31 +02:00
Juho Hämäläinen
c076f8d861
Merge pull request #70 from jusa/dynamictags
Flag sinks and sources with type defining properties and open multiple sinks and sources by default.
2017-12-08 14:35:38 +02:00
Juho Hämäläinen
89bc9d13e9 [README] Add section explaining quirks. 2017-11-20 12:03:03 +02:00
Juho Hämäläinen
1b7842655e [common] Enable input_atoi quirk by default with modern adaptations. 2017-11-20 12:02:34 +02:00
Juho Hämäläinen
30851d2343 [README] Update description of droid modules.
Add sections about new default profile feature and
sink/source classification properties.
2017-11-20 11:44:00 +02:00
Juho Hämäläinen
8afa9cc40d [card] Set off profile as available.
Without setting the availability to PA_AVAILABLE_YES it
is not possible to enable the off profile.
2017-11-20 11:44:00 +02:00
Juho Hämäläinen
33cf5fc36d [sink] Use pa_droid_stream_get_latency() from common. 2017-11-20 11:44:00 +02:00
Juho Hämäläinen
fe5025d562 [common] Add function to get stream latency in PulseAudio default type. 2017-11-20 11:44:00 +02:00
Juho Hämäläinen
dedd2cd8f0 [source] Pass droid mapping when opening input stream. 2017-11-20 11:44:00 +02:00
Juho Hämäläinen
3d76a68172 [common] Use droid mapping for input stream creation.
Needed to determine if the new stream is merged one or not.
2017-11-20 11:44:00 +02:00
Juho Hämäläinen
66ac854d1a [sink] Use updated stream structures. 2017-11-20 11:44:00 +02:00
Juho Hämäläinen
222db9e7c5 [source] Use updated stream structures. 2017-11-20 11:44:00 +02:00
Juho Hämäläinen
a219305f37 [common] Refactor stream data to separate structures.
Have pa_droid_output_stream and pa_droid_input_stream for
output and input streams, respectively.
2017-11-20 11:44:00 +02:00
Juho Hämäläinen
e6bec187d5 [card] Add module argument for controlling input merging.
Defaults to merging input routes for default profile.
2017-11-20 11:44:00 +02:00
Juho Hämäläinen
6cfc1b7282 [common] Add option to merge input streams in default profile.
This way if different input routes are split to multiple
input profiles we can use all routes from single PulseAudio
source.
2017-11-20 11:44:00 +02:00
Juho Hämäläinen
2eef2c0f6e [card] Attach remaining moving sink-inputs to primary sink if one exists. 2017-11-20 11:43:57 +02:00
Juho Hämäläinen
6f722023c8 [card] Use default profile with primary module by default. 2017-11-09 14:30:31 +02:00
Juho Hämäläinen
f2f5db85d2 [source] Set created source as data for input stream.
[source] Mark source proplist with droid api string.
2017-11-09 14:30:31 +02:00
Juho Hämäläinen
82ea053adc [sink] Set created sink as data for output stream. 2017-11-09 14:30:31 +02:00
Juho Hämäläinen
0b915e32ba [common] Replace combine profile with default profile.
Autodetects all outputs and inputs that can co-exist, and
marks the sinks and sources with stream types to aid in
classification elsewhere (policy-enforcement).
2017-11-09 14:30:31 +02:00
Juho Hämäläinen
0e9f29cc35 [build] Link libraries in right order. 2017-11-09 14:30:31 +02:00
Juho Hämäläinen
1da9d49c40 [common] Add quirk unload_no_close.
When enabled don't call audio_hw_device_close() for hal device.
2017-11-09 14:30:31 +02:00
Juho Hämäläinen
4933ed1934 [source] Use input name from mapping when loaded from droid card. 2017-11-09 14:30:31 +02:00
Juho Hämäläinen
253e4d79fe [keepalive] Use MCE given keepalive period.
We can use the value directly, as MCE reports N second renew
period, but waits N+15 seconds i.e. there is some scheduling
slack already added in by default.
2017-11-09 14:29:49 +02:00
Juho Hämäläinen
48a63c17cf [keepalive] Fix assert when closing module immediately after startup.
If the keepalive starts pending call and is immediately unloaded the
pending call is not cancelled and the pending call function is called
after the pulseaudio dbus connection object has ref count 0, causing
assert fail.
2017-11-09 14:29:43 +02:00
Juho Hämäläinen
1258e693c1 [sink] Default to not mixing output routes. 2017-10-30 15:22:15 +02:00
Juho Hämäläinen
520ca06e23 [build] Have micro version for pc version.
As the micro part of the version is the one representing new
versions of the modules (and the major.minor part represents
which PulseAudio version these modules work with), use the micro
part for the .pc Version number, so that it is possible to
reliably depend on module version.
2017-10-25 11:44:53 +03:00
Juho Hämäläinen
76cd016b5d [sink] Apply routing changes always immediately. Fixes MER#1832
All hal implementations (that I've seen) handle the parameter setting
gracefully anyways, no need to be extra careful ourself. Also, the way
the routing change is implemented poses difficulties with multiple
active sinks. When we have two sinks, like sink.primary and
sink.deep_buffer, and only sink.deep_buffer is active, setting the
routing changes to sink.primary won't be applied as the sink is
suspended. It would require too much effort to try to keep the routing
changes and everything in sync with multiple sinks. Thus, just drop the
extra work.
2017-10-24 10:36:41 +03:00
Juho Hämäläinen
18154fa18a Merge pull request #68 from jusa/jb40147
Fix voicecall record with certain devices.
2017-10-24 10:35:48 +03:00
Juho Hämäläinen
3fdfa2cfcd [common] Use correct input mapping with voicecall record. Fixes JB#40147 2017-10-23 17:53:09 +03:00
Juho Hämäläinen
5d3b262d75 [build] Check for voice uplink and downlink enums. JB#40147 2017-10-23 17:49:35 +03:00
Juho Hämäläinen
c37905ab01 Merge pull request #66 from jusa/dev
Use hooks with voice volume control.
2017-09-27 11:02:27 +03:00
Juho Hämäläinen
49636784a3 [sink] Use hooks for voice volume control. Fixes JB#39621
With hooks we have less of a chance of race issue when switching to and
from voice volume control. Using subscription system is bad as the
messages are not passed synchronously, whereas hooks are.
2017-09-26 16:25:58 +03:00
Juho Hämäläinen
67a9ab3922 [sink] Set volume control callbacks properly with hw volume.
Volume control callbacks wouldn't be properly set for a device with
hardware volume when starting the sink, only after switching to voice
volume control and back.
2017-09-26 16:13:13 +03:00
Juho Hämäläinen
dc698c834e Merge pull request #65 from jusa/dev
Fix output channel conversion.
2017-09-04 14:42:17 +03:00
Juho Hämäläinen
887177a194 [common] Fix output channel conversion. JB#39594
AUDIO_DEVICE_IN_ALL contains AUDIO_DEVICE_BIT_DEFAULT,
like AUDIO_DEVICE_OUT_ALL, which meant that config was
always filled with input channels, even when device
was output device. Fix the logic so that correct channel
mask is generated for output device as well.
2017-09-04 12:48:11 +03:00
Juho Hämäläinen
f0e679dbc1 [sink] Fix segfault when running standalone sink.
We need to check droid mapping pointer as well.
2017-09-04 12:48:04 +03:00
Juho Hämäläinen
d0ae6ca081 [common] Have correct type for function. 2017-09-04 10:46:10 +03:00
Juho Hämäläinen
d53995823d Merge pull request #64 from jusa/jb38419
Update droid source's input stream handling.
2017-04-27 14:09:59 +03:00
Juho Hämäläinen
d6ddfd2397 [common] Add AUDIO_SOURCE_FM_TUNER to input source table. 2017-04-27 14:05:49 +03:00
Juho Hämäläinen
a5c6c0cba8 [source] Remove extra routing control functions. JB#38419 2017-04-27 14:05:49 +03:00
Juho Hämäläinen
8a0ffcd174 [card] Remove voicecall-record implementation. JB#38419
New source doesn't need any special control with different devices,
so we can just remove the whole voicecall source controlling
functionality and handle everything in the source.
2017-04-27 14:05:49 +03:00
Juho Hämäläinen
9055f905f2 [common] Log active quirks only once. 2017-04-27 14:05:49 +03:00
Juho Hämäläinen
3727a32daf [source] Add inline function for reading. 2017-04-27 14:05:47 +03:00
Juho Hämäläinen
dd5db1f3a2 [sink] Add inline function for writing. 2017-04-27 14:05:47 +03:00
Juho Hämäläinen
f164adfccf [source] Remove voicecall source code. JB#38419
Since the changes to channel map etc are done in the route changing
code, we don't need special voicecall source anymore. Remove all code
related to that from source and card.
2017-04-27 14:05:47 +03:00
Juho Hämäläinen
18e52c31bf [common] Refactor stream route set function.
As we are now updating source route in the IO thread we cannot update
the source proplist when changing routing. Since it's not really that
important information and updating the audio source in main context is
quite a lot of work for small benefit, remove the proplist changing code
and refactor route setting to one function.
2017-04-27 14:05:47 +03:00
Juho Hämäläinen
c59e5b3d0a [source] Close input stream by default. Fixes JB#38419
When changing source port, by default we will now close the input
stream, set the new parameters, and reopen the stream. At the same time
it is possible that the channel count or buffer size of the input stream
needs to change (mainly for voicecall recording case, where we need to
use mono channel map for best compatibility across different devices).
It is also possible to revert to older behavior where input stream is
always around, using quirks=-close_input

We also now start droid source always in suspended state. We still need
to open the input stream for a while to get stream buffer size and
sample rate.
2017-04-27 14:05:47 +03:00
Juho Hämäläinen
eebd937511 [common] Refactor buffer round up. 2017-04-27 14:05:47 +03:00
Juho Hämäläinen
0f76cd2adb [source] Move standby call to stream open. 2017-04-27 14:05:47 +03:00
Juho Hämäläinen
0565eee3b5 [common] Refactor stream opening operations. JB#38419 2017-04-27 14:05:44 +03:00
Juho Hämäläinen
a4ffe4e44b Merge pull request #63 from jusa/quirks
Add dynamic setup for quirks.
2017-03-17 10:15:04 +02:00
Juho Hämäläinen
41f2ad8881 [card] Add module arg for setting quirks. JB#38005 2017-03-16 17:24:58 +02:00
Juho Hämäläinen
cbeb0f1b2e [common] Use dynamic quirks in addition to compile time setup. JB#38005
Instead of determining only on compile time which quirks to use, add
possibility to change which quirks are enabled.
2017-03-16 17:24:55 +02:00
Juho Hämäläinen
e0c325217f [README] Update readme about new header defines. 2017-02-13 11:26:21 +02:00
Juho Hämäläinen
06578a7665 Revert "[util] Use mako set_parameters hack also on moto_msm8960_jbbl based devices."
This reverts commit c996f6bf25.

Using ATOI fix for the device fixes input device routing without side
effects.
2017-02-13 11:16:45 +02:00
Juho Hämäläinen
0255b44106 Merge pull request #62 from kimmoli/mer1752
MER#1752
2017-02-13 11:15:25 +02:00
Kimmo Lindholm
4cdd88ba7b [util] Fix last ifdefs to have_enum checks 2017-02-12 17:34:00 +02:00
Kimmo Lindholm
d1104fd113 [util] Audio api major version bitwise operation fix 2017-02-12 16:03:38 +02:00
Kimmo Lindholm
0316c62cc1 [util] define QCOM_HARDWARE earlier 2017-02-12 14:49:39 +02:00
Kimmo Lindholm
ccdbb52cf0 [build] use android-config include during enum check 2017-02-12 13:21:11 +02:00
Juho Hämäläinen
4ea95ed6ed Merge pull request #61 from jusa/mer1744
Extend config parser.
2017-01-27 10:35:44 +02:00
Juho Hämäläinen
0719b25a86 [util] Extend config parser. Fixes MER#1744
New audio_policy.conf files contain new sections with new values as well
as global_configuration section per-module.

Currently other than using per-module global_configuration we ignore all
the values, but extend the parser so that when the new config values are
needed it's easier to parse them.
2017-01-26 14:57:50 +02:00
Simonas Leleiva
08f19dad20 Merge pull request #60 from jusa/mer1741
Fix build for various devices and parse audio configuration a bit better.
2017-01-24 16:37:50 +02:00
Juho Hämäläinen
5319729574 [util] Don't use IN_VOICE_CALL_MONO if it's not defined. 2017-01-23 17:18:17 +02:00
Juho Hämäläinen
96df77fadf [modules] Fix some warnings. 2017-01-23 17:18:17 +02:00
Juho Hämäläinen
f9c51119c8 [build] Check for a couple more enums. 2017-01-23 17:18:17 +02:00
Juho Hämäläinen
2017e6193a [util-audio] Conditional IN_ALL_USB. 2017-01-23 17:18:17 +02:00
Juho Hämäläinen
4a41dcd33e [util] Allow dynamic module/output/input count. Fixes MER#1741 2017-01-23 17:18:14 +02:00
Juho Hämäläinen
9486de758e Merge pull request #59 from jusa/dev
Fix build.
2017-01-20 12:06:10 +02:00
Juho Hämäläinen
46ffb90e5e [util] Fix warning. 2017-01-20 12:00:07 +02:00
Juho Hämäläinen
036c877c67 [util] Relocate VSID define.
Since AUDIO_API_VERSION_MAJ is defined outside current header, need to
move the definition.
2017-01-20 11:58:43 +02:00
Juho Hämäläinen
c14265b8c8 [util] Test for surround channel availability. Fixes JB#37353
Also remove incorrect duplicate _TELEPHONY_RX entry.
2017-01-20 11:48:23 +02:00
Juho Hämäläinen
6377270467 [build] Check for surround channel enum. 2017-01-20 11:46:22 +02:00
Juho Hämäläinen
54c8642d95 [util] Check for all input flags separately. Fixes JB#37353 2017-01-19 18:45:30 +02:00
Juho Hämäläinen
0515ff85df Merge pull request #57 from elros34/master
Use mako set_parameters hack also on moto_msm8960_jbbl based devices.
2017-01-19 18:36:32 +02:00
Juho Hämäläinen
4774b1b876 Merge pull request #58 from jusa/dev
Better support for future droid versions.
2017-01-19 18:35:07 +02:00
Juho Hämäläinen
996a8dd2eb [util] Replace version specific conversion headers. Fixes JB#37353
Instead of having version specific header files use one where most of
the values are common and device/version specific values are compile
time dynamic.

See configure.ac CC_CHECK_DROID_ENUM lines for how to add checks for
additional enum values.
2017-01-19 18:31:25 +02:00
Juho Hämäläinen
5c4c8d0ea0 [build] Check for various enums in droid headers. 2017-01-19 18:31:25 +02:00
Juho Hämäläinen
1b3da56e22 [build] Add macro for testing droid header contents. 2017-01-19 18:31:25 +02:00
Juho Hämäläinen
6bc52dac61 [util] Lower logging level of unknown values. 2017-01-19 18:31:25 +02:00
Juho Hämäläinen
fb87162518 [util] Use API version from droid headers.
No need to define the API version in conversion headers.
2017-01-19 18:31:23 +02:00
elros34
c996f6bf25 [util] Use mako set_parameters hack also on moto_msm8960_jbbl based devices. 2017-01-17 00:39:54 +01:00
Juho Hämäläinen
e28d1e22d3 Merge pull request #56 from jusa/dev
Better implementation of combined profile and some fixes.
2016-06-14 15:27:49 +03:00
Juho Hämäläinen
24c4d5ca2a [util] Add all profiles with combined profile as well.
When creating combined profile add all normal profiles to the profile
set as well. This way all the possible configurations can be enabled
with combined profile use case as well.
2016-06-14 12:49:04 +03:00
Juho Hämäläinen
660d23a332 [util] Implement combined profile properly. Fixes JB#35462 2016-06-14 12:05:12 +03:00
Juho Hämäläinen
5658b693a1 [util] Make sure audio_config struct is cleared before use. 2016-06-10 12:04:37 +03:00
Juho Hämäläinen
aae59e6bbc [util] Set initial device to current active for new streams.
When a stream is created and there already exists a stream with active
routing use the device of currently active routing as the initial
device. This way we minimize the risk of confusing the HAL by writing to
two streams with differing routes.
2016-06-10 11:30:49 +03:00
Juho Hämäläinen
9478857b3b [util] Correct naming of arguments. 2016-06-10 10:45:25 +03:00
Juho Hämäläinen
5283baee01 Merge pull request #53 from jusa/dev
Only refresh input routing if forced.
2016-06-01 11:56:55 +03:00
Juho Hämäläinen
0ecf6aa9ef [source] Only refresh routing if forced. JB#34890
Unless the routing is forced do not refresh routing. With output routing
it is necessary to refresh the routing when changing audio mode, but
input routing doesn't have similar requirement. Also on some devices
setting identical input routing blocks thread for a while. Due to this
disable input route refreshing for most cases.
2016-06-01 11:50:45 +03:00
Juho Hämäläinen
4b01e83ceb [util] Fix build with HAL v1 and v2 devices. Fixes JB#34737 2016-04-01 13:45:23 +03:00
Juho Hämäläinen
368a45981b Merge pull request #51 from jusa/dev
Voicecall record improvements.
2016-04-01 13:38:28 +03:00
Juho Hämäläinen
eb5841793d [card] Create specific record source for qcom 5.1 devices. Fixes JB#34737
[card] Create normal source even if voicecall source creation was unsuccessful.
2016-04-01 13:36:53 +03:00
Juho Hämäläinen
a6e8e0909f [util] Use mono channel mask with qcom 5.1 devices. Fixes JB#34737 2016-04-01 13:36:52 +03:00
Juho Hämäläinen
5ab42b04b8 [packaging] Bump minor version. 2016-03-22 11:05:07 +02:00
Juho Hämäläinen
7a54b44e87 Merge pull request #49 from jusa/pa8
Update to PulseAudio 8.0.
2016-03-22 11:03:52 +02:00
Juho Hämäläinen
126995ed22 [util] Updates for PulseAudio 8.0. MER#1507 2016-03-21 11:08:27 +02:00
Juho Hämäläinen
9a7310c3ef [source] Updates for PulseAudio 8.0. MER#1507 2016-03-21 11:08:27 +02:00
Juho Hämäläinen
a3b1b6df44 [sink] Updates for PulseAudio 8.0. MER#1507 2016-03-21 11:08:27 +02:00
Juho Hämäläinen
c869cbfac7 Merge pull request #48 from jusa/mer1544
Clear extra devices when doing voicecall routings.
2016-03-17 15:02:44 +02:00
Juho Hämäläinen
7d0a13f2b9 [sink] Clear extra devices when doing voicecall routings. Fixes MER#1544
As extra device stream operations are not allowed during active voice
call if there is active extra device stream when voice call is started
the extra route may never be cleared causing routing problems during the
call.

As a fix clear all extra routes when doing routing changes during active
voice call.
2016-03-17 14:49:17 +02:00
Juho Hämäläinen
3599618581 [util-42] Remove mako hacks as ATOI workaround works as well. 2016-03-12 17:27:55 +02:00
Juho Hämäläinen
51207d5fc0 Merge pull request #47 from ballock/master
Fixed non-voicecall inputs.
2016-03-12 17:26:16 +02:00
Boleslaw Tokarski
ef3b625b9a [mako] Fixed non-voicecall inputs. Fixes NEMO#873. 2016-03-10 20:24:18 +01:00
Juho Hämäläinen
43c423fe16 Merge pull request #46 from jusa/mer1520
Option to write silence on resume.
2016-02-26 14:02:09 +02:00
Juho Hämäläinen
f630f72a08 [source] Use suspend function from common. 2016-02-25 16:55:03 +02:00
Juho Hämäläinen
204c8b325b [sink] Slave sink follows primary sink port changes. MER#1520 2016-02-25 16:54:58 +02:00
Juho Hämäläinen
9f98f681cb [util] Function to check if sink is droid sink. MER#1520 2016-02-25 16:54:52 +02:00
Juho Hämäläinen
ed85fec56e [card] Enable module argument for sink silence on resume. MER#1520 2016-02-25 16:54:48 +02:00
Juho Hämäläinen
810a710491 [sink] Add module argument to write silence on resume. Fixes MER#1520
Add module argument for defining how much to write silence to stream
after resuming from suspend. This is a workaround for devices where for
some reason beginning of audio data is silenced right after resume.
Argument is multiples of stream buffer size.
2016-02-25 16:54:37 +02:00
Juho Hämäläinen
8a6811559c [util] Add function to suspend streams. MER#1520 2016-02-25 16:53:57 +02:00
Juho Hämäläinen
e8ed1903e6 Merge pull request #45 from ballock/master
Audio on mako aka Nexus 4 on cm11
2016-02-16 15:59:39 +02:00
Bolesław Tokarski
4dd8e54fb6 [util-44] Added mako inputs. Fixes NEMO#873.
The inputs are based on a diff against droid-util-42.h.
2016-02-16 14:37:23 +01:00
Bolesław Tokarski
5a7f44c554 [util-44] Pulseaudio output fix for mako by sledges. Contributes to NEMO#873. 2016-02-16 14:37:11 +01:00
Juho Hämäläinen
81562f0d81 Merge pull request #43 from jusa/dev
Small fixes to voice volume control and input routings.
2016-02-01 10:40:56 +02:00
Juho Hämäläinen
f832805bf2 Merge branch 'Litew-master' 2016-02-01 10:38:38 +02:00
Litew
b0012431dd [util-44] Make microphone and other sources work in Xiaomi Redmi 1S (armani). 2016-02-01 10:38:11 +02:00
Juho Hämäläinen
39c586983a [sink] Don't try to control voice volume with non-primary streams. 2016-01-11 14:47:44 +02:00
Juho Hämäläinen
bf27dd56a6 [util] Add check for primary stream. 2016-01-11 14:33:30 +02:00
Juho Hämäläinen
612ea6b81c [util-51] Add define for secondary mic. Fixes MER#1445 2016-01-08 12:04:43 +02:00
Juho Hämäläinen
e89472616b [README] Add notion about common-devel. 2016-01-08 11:57:41 +02:00
Matti Lehtimäki
c8f79644eb [util] Use mako set_parameters hack also on other 2011 Xperias. 2015-11-13 17:46:02 +02:00
Juho Hämäläinen
00c70bdd0b Merge pull request #41 from jusa/dev
Make it possible to combine multiple sinks in one profile.
2015-11-13 17:30:58 +02:00
Juho Hämäläinen
34e7d45b3d [util-42] Correct default device for mako. 2015-11-13 17:27:19 +02:00
Juho Hämäläinen
df0290cdae [util] Log device name. 2015-11-13 17:27:19 +02:00
Juho Hämäläinen
b82cf708ee [build] Provide device name as string. 2015-11-13 17:27:19 +02:00
Juho Hämäläinen
d1cc0bc49c [build] Workaround for relinking phase.
For some reason with -no-undefined passed to linker during relinking
phase linker doesn't see the symbols from droid modules. As a workaround
remove the flag.

With the workaround changes require more testing, as compilation
itself doesn't already reveal undefined symbols.

When the real root cause is found and fixed this workaround should be
removed.
2015-11-11 14:59:28 +02:00
Juho Hämäläinen
2371d6aebc [card] Use new util functions for module ops. 2015-11-11 14:59:28 +02:00
Juho Hämäläinen
3dc385f79d [source] Use new util functions for stream ops. MER#1419 2015-11-11 14:59:24 +02:00
Juho Hämäläinen
3489b27081 [sink] Use new util functions for stream ops. MER#1419 2015-11-11 14:59:21 +02:00
Juho Hämäläinen
7ca8d67fd5 [util] Add new functions for stream operations. MER#1419
Add functions for opening output and input streams, setting output and
input stream route, and setting parameters to streams and hw module.

The greatest improvement this brings is output stream routing handling
in one place. This way if/when there are multiple output streams routing
changes done to primary output are forwarded to "secondary" or "slave"
output streams.
2015-11-11 14:59:16 +02:00
Juho Hämäläinen
7e9a063aa0 [sink] Name sink with output name instead of module name. MER#1419 2015-11-11 14:59:11 +02:00
Juho Hämäläinen
a0ce2c0901 [card] Add possibility to combine outputs to profile. MER#1419 2015-11-11 14:59:07 +02:00
Juho Hämäläinen
2f2b3bc1d5 [util] Add functions for using combined profiles. MER#1419 2015-11-11 14:59:02 +02:00
Juho Hämäläinen
bc57bdf5be [util,card] Store mappings in idxsets. MER#1419 2015-11-11 14:57:01 +02:00
Juho Hämäläinen
fe42e98fa2 [sink] Parse flags for stand-alone sink. 2015-11-02 15:55:21 +02:00
Juho Hämäläinen
8ff19c0857 [sink] List output flags in sink proplist. 2015-11-02 15:54:50 +02:00
Juho Hämäläinen
7d0098bee6 Merge pull request #40 from jusa/dev
Voicecall record improvements.
2015-11-02 14:36:54 +02:00
Juho Hämäläinen
51c1194977 [sink] Try shared object before opening hw module.
When opening droid-sink as stand-alone module try getting the hw module
from PulseAudio shared object db before opening new hw module.
2015-11-02 11:54:37 +02:00
Juho Hämäläinen
7655116ea6 [card] Better support for voicecall record. Fixes MER#1390 2015-10-26 15:59:23 +02:00
Juho Hämäläinen
3e4a28fad8 [source] Allow forcing port change. MER#1390 2015-10-26 15:27:05 +02:00
Juho Hämäläinen
e49dd3150c [util] Add default input port to source mapping. MER#1390 2015-10-26 15:27:03 +02:00
Juho Hämäläinen
688eb9c9f7 [util] Update headers with default input device. 2015-10-26 14:49:45 +02:00
Juho Hämäläinen
6d735430ab Merge pull request #39 from jusa/dev
Split common and devel packages from droid modules.
2015-10-23 10:25:08 +03:00
Juho Hämäläinen
0262d24b97 [packaging] Split sbj packaging to common and devel. 2015-10-23 00:41:09 +03:00
Juho Hämäläinen
7de3b65c88 [packaging] Split normal packaging to common and devel. MER#1377 2015-10-23 00:41:09 +03:00
Juho Hämäläinen
2922e95589 [build] Generate pc file for libdroid-util. MER#1377 2015-10-23 00:41:07 +03:00
Juho Hämäläinen
1493c1b08b [build] Build libdroid-util in separate directory. 2015-10-22 23:44:05 +03:00
Juho Hämäläinen
21fba89128 [util] Move util code for separating as common. 2015-10-22 23:32:35 +03:00
Juho Hämäläinen
015ad75e32 Merge pull request #37 from jusa/dev
Voicecall and droid-source improvements.
2015-09-30 14:58:55 +03:00
Juho Hämäläinen
1e69e38c37 [util-51] Enable VSID for 5.1 with qcom bsp. Fixes MER#1356 2015-09-30 14:27:14 +03:00
Juho Hämäläinen
df1d8625f1 [card] Implement VSID setting when changing to voicecall.
Some adaptations have a notion of VSIDs. To enable audio route during
voice call in addition to setting the audio mode we need to enable one
(or more) VSIDs. This first implementation only supports enabling one
VSID at a time.
2015-09-30 14:26:42 +03:00
Juho Hämäläinen
80e03d7c00 [card] Remove unused define. 2015-09-29 10:18:38 +03:00
Juho Hämäläinen
5f6ad544e8 [source] Fix typo in log message. 2015-09-29 10:15:43 +03:00
Juho Hämäläinen
46bf9094e0 [sink] Fix typo in log message. 2015-09-29 10:15:43 +03:00
Juho Hämäläinen
feee030ca7 [card] Fix typo in log message. 2015-09-29 10:15:43 +03:00
Juho Hämäläinen
f8c922058f [util] Include android-config.h.
Include android-config.h as it includes android-version.h and
possibly other platform specific defines.
2015-09-29 10:15:43 +03:00
Juho Hämäläinen
65129833fb [source] Add missing modargs to module. 2015-09-29 10:15:43 +03:00
Juho Hämäläinen
60aa87331a [sink] Add missing modargs to module. 2015-09-29 10:15:43 +03:00
Juho Hämäläinen
a5d8675a6f [card] Add missing general module arguments. 2015-09-29 10:15:43 +03:00
Juho Hämäläinen
3c879d27ae [sink] Add overriding modargs for sink. 2015-09-29 10:15:40 +03:00
Juho Hämäläinen
db96c064ef [source] Add overriding modargs for source.
Add source specific module arguments so that source can be configured
with different parameters than sink.
2015-09-29 10:15:36 +03:00
Juho Hämäläinen
2fa1d356f8 [source] Pass device as integer if needed. Fixes MER#1343
Due to some android implementations' broken (unsigned) integer use,
add possibility to pass input source device as integer. Routing
parameters are passed using the set_parameters() as strings, so the
HAL implementation needs to convert them back to unsigned integers.
As the input devices are specified as unsigned integers > INT_MAX,
trying to do operations like atoi() with the values creates bogus
values, as glibc atoi() truncates values > INT_MAX (as does latest
bionic variant as well).

Hackish solution to overcome this is to pass the unsigned values
as integers, so that the string-formatted value range stays inside
INT_MIN and INT_MAX.
2015-09-25 15:54:27 +03:00
Juho Hämäläinen
6cec6b7c3a Merge pull request #36 from jusa/dev
Fixes to playback, record routing, and updates for 5.1 devices.
2015-09-11 15:45:30 +03:00
Juho Hämäläinen
bb8b83c374 [util-51] Add missing formats. 2015-09-11 15:30:39 +03:00
Juho Hämäläinen
a75fa10ad2 [util-51] Add qcom specific entries. 2015-09-11 15:30:39 +03:00
Juho Hämäläinen
8e8d78989f [util] Use default audio source if nothing specific is defined. 2015-09-11 15:30:39 +03:00
Juho Hämäläinen
e38d050690 [util] Correct comparison for default audio source. Fixes MER#1286 2015-09-11 15:30:39 +03:00
Juho Hämäläinen
9384008836 [sink] Set initial latency correctly.
Latency would be set correctly after first suspend anyway, but fix
initial latency setting. PulseAudio uses microseconds, HAL milliseconds.
2015-09-11 15:28:54 +03:00
Juho Hämäläinen
89e29ead84 [sink] Sleep after stream writing blocks. Fixes MER#1212
After HAL buffer is full and stream writing starts to block close to the
buffer length, sleep for one buffer length time. When io thread is
sleeping the thread can be waken up for different reasons, and if we
constantly block in the write function io thread is unable to react
immediately.
2015-09-11 15:26:46 +03:00
Juho Hämäläinen
22e1fbbada [sink] Remove mention of buffer count. 2015-09-11 15:13:48 +03:00
Juho Hämäläinen
510209493e Merge pull request #35 from jusa/mer1265
Make attached devices parsing more tolerant of unknown devices.
2015-08-26 08:33:16 +03:00
Juho Hämäläinen
33911d8606 [util] Make attached devices parsing more tolerant of unknown devices. Fixes MER#1265
Previously no unknown devices in attached sections were allowed.
Output and input sections already allow for unknown devices as long as
at least one known device is found per section. This changes attached
devices parsing to behave the same way, as long as at least one device
in attached_input_devices or attached_output_devices is known allow
module loading.
2015-08-25 16:15:40 +03:00
59 changed files with 9048 additions and 4874 deletions

3
.gitignore vendored
View file

@ -19,3 +19,6 @@ config.status
libtool
*.pc
stamp-*
# Added by Droidian
!.circleci/

201
README
View file

@ -1,201 +0,0 @@
PulseAudio Droid modules
========================
Supported Android versions:
* 4.1.x with Qualcomm extensions (tested with 4.1.2)
* 4.2.x
* 4.4.x
* 5.1
Headers for defining devices and strings for different droid versions are in
src/droid/droid-util-XXX.h
These headers are then included in src/droid/droid-util.h based on detected
droid version.
The purpose of droid-modules is to "replace AudioFlinger". Many hardware
adaptations use ALSA as the kernel interface, but there is no saying that
someday vendor would create and use something proprietary or otherwise
different from ALSA. Also the ALSA implementation in droid devices may contain
funny ways to achieve things (notable example is voicecall) which might be
difficult to do if interfacing directly with ALSA to replace AudioFlinger.
Also using ALSA directly would mean that the whole HAL adaptation would need to
be ported for each new device adaptation. With droid-modules this is much more
simpler, with somewhat stable HAL (HALv2 as of now, also different vendors add
their own incompatible extensions) API. In best scenarios using droid-modules
with new device is just compiling against target.
Android version and device specific variations should be optimally handled in
droid-util-XXX.h files, without modifying other parts of the implementation.
Components
==========
module-droid-card
-----------------
Ideally only module-droid-card is loaded and then droid-card loads
configuration, creates profiles and loads sinks and sources based on the
selected profile.
Droid-card reads configuration from /vendor/etc/audio_policy.conf or
/system/etc/audio_policy.conf, depending on which is found first. If vendor
config is found, configuration is read from there, otherwise from system
configuration.
From audio_policy.conf file 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 (input-output) primary-primary and lpa-primary.
When module-droid-card is run without module_id argument, as default "primary"
is used.
virtual profiles
----------------
In addition to aforementioned card profiles, 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.
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
After this, when there is an active voicecall (created by ofono for example),
voice audio starts to flow between modem and audio chip.
To disable voicecall and return to media audio:
pactl set-card-profile droid_card.primary primary-primary
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
card profile, and they are maintained for the whole duration of the voicecall
and after.
This sequence follows the droid HAL idea that when changing audio mode the mode
change is done when next routing change happens. output-parking and
input-parking ports are just convenience for PulseAudio, where setting already
active port is a no-op (output/input-parking doesn't do any real routing
changes).
Current virtual profiles are:
* voicecall
* voicecall-record
* communication
* ringtone
Communication profile is used for VoIP-like applications, to enable some
voicecall related algorithms without being in voicecall. Ringtone profile
should be used when ringtone is playing, to again enable possible loudness
related optimizations etc. Voicecall-record profile can be enabled when
voicecall profile is active.
module-droid-sink and module-droid-source
-----------------------------------------
Normally user should not need to load droid-sink or droid-source modules by
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.conf, 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
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)
Volume control during voicecall
-------------------------------
When voicecall virtual profile is enabled, active droid-sink is internally
switched to voicecall volume control mode. What this means is changing the sink
volume or volume of normal streams connected to the sink do not change active
voicecall volume. Special stream is needed to control the voicecall volume
level. By default this stream is identified by stream property media.role,
with value "phone". This can be changed by providing module arguments
voice_property_key and voice_property_value to module-droid-card.
Usually droid HAL has 6 volume levels for voicecall.
Temporary sink audio routing
----------------------------
It is possible to add temporary extra route(s) to sink audio routing with
specific stream property. When stream with property key
droid.device.additional-route connects to droid-sink, this extra route is added
(if possible) to the enabled routes for the duration of the stream.
For example, if droid-sink has active port output-wired_headphone:
paplay --property=droid.device.additional-route=AUDIO_DEVICE_OUT_SPEAKER a.wav
As long as the new stream is connected to droid-sink, output routing is
SPEAKER+WIRED_HEADPHONE.
module-droid-keepalive
----------------------
Keepalive module is MCE (https://github.com/nemomobile/mce) specific module
tracking sink/source activity and keeping a WAKELOCK when there are active
streams.

356
README.md Normal file
View file

@ -0,0 +1,356 @@
PulseAudio Droid modules
========================
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
PulseAudio modules in this package and for inclusion in other projects
* **droid** with actual PulseAudio modules
Linking to libdroid is **not encouraged**, usually only HAL functions are needed
which can be accessed using the pulsecore shared API (see below).
Supported Android versions:
* 11.x
Headers for defining devices and strings for different droid versions are in
src/common/droid-util-audio.h.
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:
# configure.ac:
CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_DEVICE_OUT_IP])
CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_DEVICE_OUT_OTHER_NEW])
# and then in droid-util-audio.h add macros to proper tables:
/* string_conversion_table_output_device[] */
STRING_ENTRY_IF_OUT_IP
STRING_ENTRY_IF_OUT_OTHER_NEW
/* string_conversion_table_output_device_fancy[] */
FANCY_ENTRY_IF_OUT_IP("output-ip")
FANCY_ENTRY_IF_OUT_OTHER_NEW("output-other_new")
In addition to the above macros there are also now defines
HAVE_ENUM_AUDIO_DEVICE_OUT_IP and HAVE_ENUM_AUDIO_DEVICE_OUT_OTHER_NEW.
The purpose of droid-modules is to "replace AudioFlinger". Many hardware
adaptations use ALSA as the kernel interface, but there is no saying that
someday vendor would create and use something proprietary or otherwise
different from ALSA. Also the ALSA implementation in droid devices may contain
funny ways to achieve things (notable example is voicecall) which might be
difficult to do if interfacing directly with ALSA to replace AudioFlinger.
Also using ALSA directly would mean that the whole HAL adaptation would need to
be ported for each new device adaptation. With droid-modules this is much more
simpler, with somewhat stable HAL (HALv3 as of now, also different vendors add
their own incompatible extensions) API. In best scenarios using droid-modules
with new device is just compiling against target.
Components
==========
common
------
The common part of PulseAudio Droid modules contains library for handling
most operations towards audio HAL.
### Audio policy configuration parsing
Configuration parser reads audio policy xml files.
### Configuration files
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
/vendor/etc/audio/audio_policy_configuration.xml
/vendor/etc/audio_policy_configuration.xml
/system/etc/audio_policy_configuration.xml
module-droid-card
-----------------
Ideally only module-droid-card is loaded and then droid-card loads
configuration, creates profiles and loads sinks and sources based on the
selected profile.
default 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.
virtual profiles
----------------
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.
As an illustration, following command line sequence enables voicecall mode and
routes audio to internal handsfree (ihf - "handsfree 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
After this, when there is an active voicecall (created by ofono for example),
voice audio starts to flow between modem and audio chip.
To disable voicecall and return to media audio:
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 default
card profile, and they are maintained for the whole duration of the voicecall
and after.
This sequence follows the droid HAL idea that when changing audio mode the mode
change is done when next routing change happens. output-parking and
input-parking ports are just convenience for PulseAudio, where setting already
active port is a no-op (output/input-parking doesn't do any real routing
changes).
Current virtual profiles are:
* voicecall
* voicecall-record
* communication
* ringtone
Communication profile is used for VoIP-like applications, to enable some
voicecall related algorithms without being in voicecall. Ringtone profile
should be used when ringtone is playing, to again enable possible loudness
related optimizations etc. Voicecall-record profile can be enabled when
voicecall profile is active.
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
-----------------------------------------
Normally user should not need to load droid-sink or droid-source modules by
hand, but droid-card loads appropriate modules based on the active card
profile.
Changing output routing is as simple as
pactl set-sink-port sink.primary output-wired_headphone
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
--------------------------------------
As droid HAL makes assumptions on (input) routing based on what the parameters
for the stream are (device, sample rate, channels, format, etc.) normal
PulseAudio sources are a bit inflexible as only sample rate can change after
source creation and even then there are restrictions based on alternative
sample rate value.
To overcome this and to allow some more variables affecting the stream being
passed to the input stream droid source is modified to reconfigure itself
with the source-output that connects to it. This means, that just looking at
inactive source from "pactl list" listing doesn't tell the whole story.
Droid source is always reconfigured with the *last* source-output that
connects to it, possibly already connected source-outputs will continue
to read from the source but through resampler.
For example,
1) source-output 44100Hz, stereo connects (so1)
1) source is configured with 44100Hz, stereo
2) so1 connects to the source without resampler
2) source-output 16000Hz, mono connects (so2)
1) so1 is detached from the source
2) source is configured with 16000Hz, mono
3) so2 connects to the source without resampler
4) resampler is created for so1, 16000Hz, mono -> 44100Hz stereo
5) so1 is re-attached to the source through resampler
3) source-output 16000Hz, mono connects (so3)
1) so1 and so2 are detached from the source
2) so3 connects to the source without resampler
3) so1 is re-attached to the source through resampler
4) so2 is attached to the source
Classifying sinks and sources
-----------------------------
Certain property values are set to all active sinks and sources based on their
functionality to ease device classification.
Currently following properties are set:
* For droid sinks
* droid.output.primary
* droid.output.low_latency
* droid.output.media_latency
* droid.output.offload
* droid.output.voip
* For droid sources
* droid.input.builtin
* droid.input.external
If the property is set and with value "true", the sink or source should be
used for the property type. If the property is not defined or contains
value "false" it shouldn't be used for the property type.
For example, we might have sink.primary and sink.low_latency with following
properties:
* sink.primary
* droid.output.primary "true"
* droid.output.media_latency "true"
* sink.low_latency
* droid.output.low_latency "true"
There also may be just one sink, with all the properties defined as "true"
and so on.
Right now there exists only one source (input device) which will always have
both properties as true.
Options
-------
There are some adaptations that require hacks to get things working. These
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 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.
* close_input
* Enabled by default.
* Close input stream when not in use instead of suspending the stream.
Cannot be changed when multiple inputs are merged to single source.
* unload_no_close
* Disabled by default.
* Don't call audio_hw_device_close() for the hw module when unloading.
Mostly useful for tracking module unload issues.
* 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 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 option so that the realcall parameter is applied
when switching to voicecall profile.
* unload_call_exit
* Disabled by default.
* Some HAL module implementations get stuck in mutex or segfault when
trying to unload the module. To avoid confusing segfaults call
exit(0) instead of calling unload for the module.
* output_fast
* Enabled by default.
* Create separate sink if AUDIO_OUTPUT_FLAG_FAST is found. If this sink
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 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 option can be enabled and 10 seconds of sleep is added after
opening hw module.
* 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 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.
Options can be enabled or disabled normally as module arguments, for example:
load-module module-droid-card hw_volume=false record_voice_16k=true
Volume control during voicecall
-------------------------------
When voicecall virtual profile is enabled, active droid-sink is internally
switched to voicecall volume control mode. What this means is changing the sink
volume or volume of normal streams connected to the sink do not change active
voicecall volume. Special stream is needed to control the voicecall volume
level. By default this stream is identified by stream property media.role,
with value "phone". This can be changed by providing module arguments
voice_property_key and voice_property_value to module-droid-card.
Usually droid HAL has 6 volume levels for voicecall.
Temporary sink audio routing
----------------------------
It is possible to add temporary route to sink audio routing with specific
stream property. When stream with property key
droid.device.additional-route connects to droid-sink, this extra route is set
(if possible) as the enabled route for the duration of the stream.
For example, if droid-sink has active port output-wired_headphone:
paplay --property=droid.device.additional-route=AUDIO_DEVICE_OUT_SPEAKER a.wav
As long as the new stream is connected to droid-sink, output routing is
SPEAKER.
HAL API
-------
If there is need to call HAL directly from other modules it can be done with
function pointer API stored in PulseAudio shared map.
Once the function pointers are acquired when called they will work the same
way as defined in Android audio.h. For example:
void *handle;
int (*set_parameters)(void *handle, const char *key_value_pairs);
char* (*get_parameters)(void *handle, const char *keys);
handle = pa_shared_get(core, "droid.handle.v1");
set_parameters = pa_shared_get(core, "droid.set_parameters.v1");
get_parameters = pa_shared_get(core, "droid.get_parameters.v1");
set_parameters(handle, "route=2;");
char *value = get_parameters(handle, "connected");

View file

@ -1,6 +1,6 @@
AC_PREREQ(2.60)
AC_INIT([pulseaudio-modules-droid], [m4_esyscmd(./git-version-gen .tarball-version)], [mer-general@lists.merproject.org])
AC_INIT([pulseaudio-modules-droid-modern], [m4_esyscmd(./git-version-gen .tarball-version)], [mer-general@lists.merproject.org])
AC_CONFIG_HEADER([config.h])
AM_INIT_AUTOMAKE([foreign -Wall silent-rules])
AC_CONFIG_MACRO_DIR(m4)
@ -20,13 +20,15 @@ AC_PROG_CC_C99
AM_PROG_CC_C_O
AC_PROG_GCC_TRADITIONAL
m4_define(pa_major, `echo $VERSION | cut -d. -f1 | cut -d- -f1`)
m4_define(pa_minor, `echo $VERSION | cut -d. -f2 | cut -d- -f1`)
m4_define(pa_major, `pkg-config --modversion libpulse | cut -d. -f1 | cut -d- -f1`)
m4_define(pa_minor, `pkg-config --modversion libpulse | cut -d. -f2 | cut -d- -f1`)
m4_define(pa_module_version, `echo $VERSION | cut -d. -f3 | cut -d- -f1`)
AC_SUBST(PA_MAJOR, pa_major)
AC_SUBST(PA_MAJORMINOR, pa_major.pa_minor)
AC_SUBST(PA_MODULE_VERSION, pa_module_version)
DESIRED_FLAGS="-Wall -W -Wextra -pedantic -pipe -Wno-long-long -Winline -Wvla -Wno-overlength-strings -Wunsafe-loop-optimizations -Wundef -Wformat=2 -Wlogical-op -Wsign-compare -Wpacked -Wformat-security -Wmissing-include-dirs -Wformat-nonliteral -Wold-style-definition -Wpointer-arith -Winit-self -Wfloat-equal -Wmissing-prototypes -Wstrict-prototypes -Wredundant-decls -Wmissing-declarations -Wmissing-noreturn -Wshadow -Wendif-labels -Wstrict-aliasing=2 -Wwrite-strings -Wno-unused-parameter -ffast-math -Wp,-D_FORTIFY_SOURCE=2 -fno-common -fdiagnostics-show-option" # PulseAudio 0.9.15 usess same + -Wcast-align -Wdeclaration-after-statement
DESIRED_FLAGS="-std=gnu11 -Wall -W -Wextra -pipe -Wno-long-long -Wno-overlength-strings -Wunsafe-loop-optimizations -Wundef -Wformat=2 -Wlogical-op -Wsign-compare -Wformat-security -Wmissing-include-dirs -Wformat-nonliteral -Wold-style-definition -Wpointer-arith -Winit-self -Wdeclaration-after-statement -Wfloat-equal -Wmissing-prototypes -Wstrict-prototypes -Wredundant-decls -Wmissing-declarations -Wmissing-noreturn -Wshadow -Wendif-labels -Wcast-align -Wstrict-aliasing -Wwrite-strings -Wno-unused-parameter -fno-common -fdiagnostics-show-option -fdiagnostics-color=auto"
for flag in $DESIRED_FLAGS ; do
CC_CHECK_CFLAGS([$flag], [CFLAGS="$CFLAGS $flag"])
@ -168,12 +170,10 @@ AS_IF([test "$pulseaudio_cv__Bool" = "yes"], [
#LT_INIT([dlopen win32-dll disable-static])
AC_PROG_LIBTOOL
PKG_CHECK_MODULES([PULSEAUDIO], [libpulse >= 5.0 pulsecore >= 5.0])
PKG_CHECK_MODULES([PULSEAUDIO], [libpulse >= 14.2 pulsecore >= 14.2])
AC_SUBST(PULSEAUDIO_CFLAGS)
AC_SUBST(PULSEAUDIO_LIBS)
pulseaudiodir=`pkg-config --variable=prefix pulsecore`
#PKG_CHECK_MODULES([DROIDHEADERS], [android-headers >= 0.0.6])
# android-headers.pc has broken version field
PKG_CHECK_MODULES([DROIDHEADERS], [android-headers])
@ -183,13 +183,43 @@ PKG_CHECK_MODULES([HYBRIS], [libhardware >= 0.1.0])
AC_SUBST(HYBRIS_CFLAGS)
AC_SUBST(HYBRIS_LIBS)
PKG_CHECK_MODULES([DBUS], [dbus-1 >= 1.2])
AC_SUBST(DBUS_CFLAGS)
AC_SUBST(DBUS_LIBS)
PKG_CHECK_MODULES([EVDEV], [libevdev >= 1.0])
AC_SUBST(EVDEV_CFLAGS)
AC_SUBST(EVDEV_LIBS)
AC_ARG_WITH([module-dir],
AS_HELP_STRING([--with-module-dir],[Directory where to install the modules to (defaults to ${pulseaudiodir}/lib/pulse-${PA_MAJORMINOR}/modules/]),
[modlibexecdir=$withval], [modlibexecdir="${pulseaudiodir}/lib/pulse-${PA_MAJORMINOR}/modules"])
#### expat (for xml config format parsing) ####
PKG_CHECK_MODULES([EXPAT], [expat >= 2.1])
AC_SUBST(EXPAT_CFLAGS)
AC_SUBST(EXPAT_LIBS)
# Input devices
CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_DEVICE_IN_FM_RX])
CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_DEVICE_IN_FM_RX_A2DP])
# Audio sources
CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_SOURCE_ECHO_REFERENCE])
CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_SOURCE_FM_TUNER])
CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_SOURCE_FM_RX])
CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_SOURCE_FM_RX_A2DP])
# Output flags
CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH])
# Channels
CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_CHANNEL_IN_VOICE_CALL_MONO])
CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO])
CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO])
# Formats
CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_FORMAT_PCM_OFFLOAD])
CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_FORMAT_FLAC])
CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_FORMAT_OPUS])
AC_ARG_WITH(
[module-dir],
AS_HELP_STRING([--with-module-dir],[Directory where to install the modules to (defaults to ${libdir}/pulse-${PA_MAJORMINOR}/modules]),
[modlibexecdir=$withval], [modlibexecdir="${libdir}/pulse-${PA_MAJORMINOR}/modules"])
AC_SUBST(modlibexecdir)
@ -201,10 +231,16 @@ AC_ARG_WITH([droid-device],
[droiddevice=$withval], [droiddevice="generic"]
)
if test "x$droiddevice" != x ; then
DROID_DEVICE_CFLAGS="-DDROID_DEVICE_`echo $droiddevice | tr '[a-z]' '[A-Z]'`=1"
DROID_DEVICE_CFLAGS="-DDROID_DEVICE_`echo $droiddevice | tr '[a-z]' '[A-Z]'`=1 -DDROID_DEVICE_STRING=\"\\\"$droiddevice\\\"\""
AC_SUBST([DROID_DEVICE_CFLAGS])
fi
# Workaround for SBJ HAL headers
if test "x$droiddevice" = xsbj ; then
SBJ_DEVICE_LDFLAGS="-Wl,--allow-multiple-definition"
AC_SUBST([SBJ_DEVICE_LDFLAGS])
fi
AC_MSG_CHECKING([If we are using hardfp tool chain])
case `echo | gcc -v -xc -o - - 2>&1 | grep COLLECT_GCC_OPTIONS | tail -1` in
*float-abi=hard*) hardfp=yes; AC_MSG_RESULT([yes]) ;;
@ -220,6 +256,8 @@ fi
AC_CONFIG_FILES([
Makefile
src/Makefile
src/common/Makefile
src/common/libdroid-util.pc
src/droid/Makefile
])
@ -233,8 +271,7 @@ echo "
CFLAGS: ${CFLAGS}
prefix: ${prefix}
PulseAudio prefix: ${pulseaudiodir}
modules directory: ${modlibexecdir}
Droid device ${droiddevice}
Droid device: ${droiddevice}
"

98
debian/changelog vendored Normal file
View file

@ -0,0 +1,98 @@
pulseaudio-modules-droid-modern (16.1.101+gemian11+nmu1) bookworm; urgency=medium
* Non-maintainer upload.
* add config files
-- Penelope Gwen <support@pogmom.me> Sun, 29 Mar 2026 14:04:19 -0700
pulseaudio-modules-droid-modern (16.1.101+gemian1) unstable; urgency=medium
* New upstream nabbed from droidian
-- Adam Boardman <adamboardman@gmail.com> Tue, 04 Apr 2023 16:02:47 +0100
pulseaudio-modules-droid (12.2.84+gemian) buster; urgency=medium
* New upstream release
-- TheKit <thekit@disroot.org> Wed, 03 Jun 2020 01:55:10 +0100
pulseaudio-modules-droid (12.2.79+gemian) buster; urgency=medium
* Branch packaging for Gemian
-- TheKit <thekit@disroot.org> Wed, 13 Nov 2019 13:39:31 +0100
pulseaudio-modules-droid (12.2.79-3) unstable; urgency=medium
* Fix pulseaudio droid module version
-- Jonah Brüchert <jbb@kaidan.im> Tue, 12 Nov 2019 12:35:51 +0100
pulseaudio-modules-droid (12.2.79-2) unstable; urgency=medium
* Fix generating the pkgconfig files with proper pathes
-- Jonah Brüchert <jbb@kaidan.im> Tue, 12 Nov 2019 12:06:47 +0100
pulseaudio-modules-droid (12.2.79-1) unstable; urgency=medium
* New upstream release
-- Jonah Brüchert <jbb@kaidan.im> Sun, 06 Oct 2019 15:23:45 +0200
pulseaudio-modules-droid (12.2.78-1) unstable; urgency=medium
* New upstream release
-- Jonah Brüchert <jbb@kaidan.im> Thu, 25 Apr 2019 22:37:38 +0200
pulseaudio-modules-droid (11.1.75-1) unstable; urgency=medium
* New upstream release
-- Jonah Brüchert <jbb@kaidan.im> Tue, 13 Nov 2018 21:17:39 +0100
pulseaudio-modules-droid (11.1.74-1) unstable; urgency=medium
* New upstream release
-- Jonah Brüchert <jbb@kaidan.im> Sat, 13 Oct 2018 20:43:53 +0200
pulseaudio-modules-droid (11.1.73-1) unstable; urgency=medium
* New upstream release
-- Jonah Brüchert <jbb@kaidan.im> Sat, 13 Oct 2018 20:43:29 +0200
pulseaudio-modules-droid (11.1.72-1) unstable; urgency=medium
* New upstream release
-- Jonah Brüchert <jbb@kaidan.im> Sun, 26 Aug 2018 12:27:09 +0200
pulseaudio-modules-droid (11.1.71-1) unstable; urgency=medium
* New upstream release
-- Jonah Brüchert <jbb@kaidan.im> Wed, 22 Aug 2018 14:04:55 +0200
pulseaudio-modules-droid (11.1.68-1) unstable; urgency=medium
* New upstream release
-- Jonah Brüchert <jbb@kaidan.im> Wed, 06 Jun 2018 14:03:22 +0200
pulseaudio-modules-droid (11.1.67-1) unstable; urgency=medium
* New upstream release
* Move to mer-hybris upstream
* Split packaging from source
-- Jonah Brüchert <jbb@kaidan.im> Sat, 26 May 2018 20:06:24 +0200
pulseaudio-modules-droid (0.1) xenial; urgency=medium
* Initial release.
-- Marius Gripsgard <marius@ubports.com> Fri, 19 Jan 2018 07:39:13 +0100

1
debian/compat vendored Normal file
View file

@ -0,0 +1 @@
11

43
debian/control vendored Normal file
View file

@ -0,0 +1,43 @@
Source: pulseaudio-modules-droid-modern
Section: sound
Priority: optional
Build-Depends: android-headers,
check,
debhelper (>= 11),
dh-exec,
intltool,
pulseaudio-pulsecore-dev,
libdbus-1-dev,
libhardware-dev,
libhybris-common-dev,
libltdl-dev,
libpulse-dev,
libexpat1-dev,
libevdev-dev,
libudev-dev
Maintainer: Adam Boardman <adamboardman@gmail.com>
Standards-Version: 4.3.0
Homepage: https://github.com/mer-hybris/pulseaudio-modules-droid
Vcs-Git: https://github.com/gemian/pulseaudio-modules-droid-modern.git
Vcs-Browser: https://github.com/gemian/pulseaudio-modules-droid-modern
Package: pulseaudio-modules-droid-modern
Architecture: any
Depends: ${misc:Depends}, ${shlibs:Depends}
Provides: pulseaudio-modules-droid-apispecific
Conflicts: pulseaudio-modules-droid-apispecific
Description: PulseAudio Droid HAL module
Pulseaudio modules to interact with the Android HAL.
.
This package contains the actual modules, for Android 11+.
Package: pulseaudio-modules-droid-modern-dev
Architecture: any
Depends: pulseaudio-modules-droid-modern (= ${binary:Version}),
${misc:Depends},
Provides: pulseaudio-modules-droid-apispecific-dev
Conflicts: pulseaudio-modules-droid-apispecific-dev
Description: PulseAudio Droid HAL module - development headers
Pulseaudio modules to interact with the Android HAL.
.
This package contains the development headers.

44
debian/copyright vendored Normal file
View file

@ -0,0 +1,44 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: pulseaudio-modules-droid-modern
Source: https://github.com/mer-hybris/pulseaudio-modules-droid-modern
Files: *
Copyright: 2013-2022, Jolla Ltd.
License: LGPL-2.1
Files: debian/*
Copyright: 2018, Jonah Brüchert
2017, 2018, Marius Gripsgard
License: LGPL-2.1
Files: m4/*
Copyright: 2006, 2007, xine project
2006, 2007, Diego Pettenò <flameeyes@gmail.com>
License: GPL-2+
License: GPL-2+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 dated June, 1991, or (at
your option) any later version.
.
On Debian systems, the complete text of version 2 of the GNU General
Public License can be found in '/usr/share/common-licenses/GPL-2'.
License: LGPL-2.1
This package is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation, version 2.1 of
the License.
.
This package 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 package; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
.
On Debian systems, the complete text of the GNU Lesser General
Public License can be found in `/usr/share/common-licenses/LGPL-2.1'.

4
debian/preinst vendored Executable file
View file

@ -0,0 +1,4 @@
#!/bin/sh
rm /etc/pulse/default.pa.gemian || true
rm /etc/pulse/arm_droid_card_custom.pa || true

View file

@ -0,0 +1,2 @@
usr/include/pulsecore/modules/droid/*.h
usr/lib/*/pkgconfig/*

View file

@ -0,0 +1,7 @@
usr/lib/pulse-*/modules/libdroid-sink*.so
usr/lib/pulse-*/modules/libdroid-source*.so
usr/lib/pulse-*/modules/libdroid-util*.so
usr/lib/pulse-*/modules/module-droid-card*.so
usr/lib/pulse-*/modules/module-droid-sink*.so
usr/lib/pulse-*/modules/module-droid-source*.so
etc/*

33
debian/rules vendored Executable file
View file

@ -0,0 +1,33 @@
#!/usr/bin/make -f
# -*- makefile -*-
include /usr/share/dpkg/default.mk
PA_MODULE_DIR := $$(readlink -f /usr/lib/pulse-*/modules)
%:
dh $@ --with=autoreconf
override_dh_auto_configure:
dh_auto_configure -- --disable-static --with-module-dir=${PA_MODULE_DIR}
override_dh_autoreconf:
echo ${DEB_VERSION_UPSTREAM} > .tarball-version
dh_autoreconf
override_dh_auto_clean:
if [ -f .tarball-version ]; then rm .tarball-version; fi
dh_auto_clean
override_dh_shlibdeps:
dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info -l/usr/lib/${DEB_HOST_MULTIARCH}/pulseaudio:/usr/lib/pulse-*/modules
override_dh_auto_install:
dh_auto_install
rm debian/tmp/usr/lib/pulse-*/modules/*.la
install -d debian/tmp/usr/include/pulsecore/modules/droid
install -m 644 src/common/*.h debian/tmp/usr/include/pulsecore/modules/droid
install -d debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/pkgconfig
install -m 644 src/common/*.pc debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/pkgconfig

1
debian/source/format vendored Normal file
View file

@ -0,0 +1 @@
3.0 (native)

View file

@ -0,0 +1 @@
load-module module-droid-card

142
etc/pulse/default.pa.gemian Normal file
View file

@ -0,0 +1,142 @@
#!/usr/bin/pulseaudio -nF
#
# This file is part of PulseAudio.
#
# PulseAudio is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# PulseAudio is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
# This startup script is used only if PulseAudio is started per-user
# (i.e. not in system mode)
.nofail
.fail
load-module module-droid-keepalive
### Automatically augment property information from .desktop files
### stored in /usr/share/application
load-module module-augment-properties
load-module module-null-sink sink_name=sink.null rate=48000
load-module module-stream-restore
### Switch when connected by default (ubports)
load-module module-switch-on-connect ignore_virtual=yes
### Should be after module-*-restore but before module-*-detect (sfos)
load-module module-switch-on-port-available
### If droid-card needs other arguments than the default, have the new
### load-module line in /etc/pulse/arm_droid_card_custom.pa
.ifexists /etc/pulse/arm_droid_card_custom.pa
.include /etc/pulse/arm_droid_card_custom.pa
.else
load-module module-droid-card rate=48000
.endif
### Needed on many new devices. HADK guide explains how to implement this fully
.ifexists module-droid-glue.so
.nofail
load-module module-droid-glue
.fail
.endif
.ifexists module-droid-hidl-28.so
.nofail
load-module module-droid-hidl-28
.fail
.endif
load-module module-null-sink sink_name=sink.fake.sco rate=8000 channels=1
load-module module-null-source source_name=source.fake.sco rate=8000 channels=1
#load-module module-bluetooth-discover bluez4_args="sco_sink=sink.fake.sco sco_source=source.fake.sco" bluez5_args="headset=droid"
load-module module-bluetooth-discover
load-module module-bluetooth-policy
#load-module module-policy-enforcement
load-module module-role-ducking trigger_roles=alarm,notification,warning ducking_roles=x-maemo volume=-200dB
### Load several protocols
.ifexists module-esound-protocol-unix.so
load-module module-esound-protocol-unix
.endif
load-module module-native-protocol-unix
### Network access (may be configured with paprefs, so leave this commented
### here if you plan to use paprefs)
#load-module module-esound-protocol-tcp
#load-module module-native-protocol-tcp
#load-module module-zeroconf-publish
### Load the RTP receiver module (also configured via paprefs, see above)
#load-module module-rtp-recv
### Load the RTP sender module (also configured via paprefs, see above)
#load-module module-null-sink sink_name=rtp format=s16be channels=2 rate=44100 sink_properties="device.description='RTP Multicast Sink'"
#load-module module-rtp-send source=rtp.monitor
### Load additional modules from GSettings. This can be configured with the paprefs tool.
### Please keep in mind that the modules configured by paprefs might conflict with manually
### loaded modules.
.ifexists module-gsettings.so
.nofail
load-module module-gsettings
.fail
.endif
### Make sure we always have a sink around, even if it is a null sink.
load-module module-always-sink
### Honour intended role device property
load-module module-intended-roles
### Automatically suspend sinks/sources that become idle for too long
load-module module-suspend-on-idle timeout=1
### If autoexit on idle is enabled we want to make sure we only quit
### when no local session needs us anymore.
.ifexists module-console-kit.so
load-module module-console-kit
.endif
.ifexists module-systemd-login.so
load-module module-systemd-login
.endif
### Load DBus protocol
.ifexists module-dbus-protocol.so
load-module module-dbus-protocol
.endif
### Move orphan streams to placeholder sinks or sources so that playback doesn't get
### interrupted. Policy enforcement module then moves the streams to new appropriate
### sinks or sources.
#load-module module-rescue-streams sink_name=sink.null source_name=sink.null.monitor
### Enable positioned event sounds
load-module module-position-event-sounds
### Modules to allow auto-loading of filters (such as echo cancellation)
### on demand. module-filter-heuristics tries to determine what filters
### make sense, and module-filter-apply does the heavy-lifting of
### loading modules and rerouting streams.
load-module module-filter-heuristics
load-module module-filter-apply
### Make some devices default
set-default-sink sink.primary_output
set-default-source source.droid

26
m4/check_droid_enum.m4 Normal file
View file

@ -0,0 +1,26 @@
AC_DEFUN([CC_CHECK_DROID_ENUM],
[AC_MSG_CHECKING([if droid headers have enum $2])
AC_LANG_SAVE
AC_LANG_C
SAVE_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $1"
AC_TRY_COMPILE(
[ #include <android-config.h>
#ifdef QCOM_BSP
#define QCOM_HARDWARE
#endif
#include <system/audio.h> ],
[ unsigned int e = $2; ],
cc_check_droid_enum=yes, cc_check_droid_enum=no)
CFLAGS="$SAVE_CFLAGS"
AC_LANG_RESTORE
AC_MSG_RESULT([$cc_check_droid_enum])
if test x"$cc_check_droid_enum" = x"yes"; then
AC_DEFINE(HAVE_ENUM_$2,,[define if enum $2 is found in headers])
AC_DEFINE(STRING_ENTRY_IF_$2,[STRING_ENTRY($2),],[string entry for enum $2])
AC_DEFINE(FANCY_ENTRY_IF_$2(n),[{$2, n},],[fancy entry for enum $2])
else
AC_DEFINE(STRING_ENTRY_IF_$2,,[string entry for enum $2])
AC_DEFINE(FANCY_ENTRY_IF_$2(n),,[fancy entry for enum $2])
fi
])

View file

@ -1,50 +0,0 @@
%define device sbj
%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-%{device}
Summary: PulseAudio Droid HAL modules
Version: %{pulsemajorminor}.1
Release: 1
Group: Multimedia/PulseAudio
License: LGPLv2.1+
URL: https://github.com/mer-hybris/multimedia-pulseaudio-modules-droid
Source0: %{name}-%{version}.tar.bz2
Requires: pulseaudio >= %{pulseversion}
BuildRequires: automake
BuildRequires: libtool
BuildRequires: libtool-ltdl-devel
BuildRequires: pkgconfig(pulsecore) >= %{pulsemajorminor}
BuildRequires: pkgconfig(android-headers)
BuildRequires: pkgconfig(libhardware)
BuildRequires: pkgconfig(dbus-1)
Provides: pulseaudio-modules-droid
%description
PulseAudio Droid HAL modules.
%prep
%setup -q -n %{name}-%{version}
%build
echo "%{moduleversion}" > .tarball-version
%reconfigure --disable-static --with-droid-device=%{device}
make %{?jobs:-j%jobs}
%pre
systemctl-user stop pulseaudio.service || :
%post
systemctl-user daemon-reload || :
systemctl-user restart pulseaudio.service || :
%install
rm -rf %{buildroot}
%make_install
%files
%defattr(-,root,root,-)
%{_libdir}/pulse-%{pulsemajorminor}/modules/*.so

View file

@ -5,39 +5,77 @@
Name: pulseaudio-modules-droid
Summary: PulseAudio Droid HAL modules
Version: %{pulsemajorminor}.1
Version: %{pulsemajorminor}.101
Release: 1
Group: Multimedia/PulseAudio
License: LGPLv2.1+
License: LGPLv2+
URL: https://github.com/mer-hybris/pulseaudio-modules-droid
Source0: %{name}-%{version}.tar.bz2
Requires: pulseaudio >= %{pulseversion}
Requires: %{name}-common = %{version}-%{release}
Requires: pulseaudio-module-keepalive >= 1.0.0
BuildRequires: automake
BuildRequires: libtool
BuildRequires: libtool-ltdl-devel
BuildRequires: pkgconfig(pulsecore) >= %{pulsemajorminor}
BuildRequires: pkgconfig(android-headers)
BuildRequires: pkgconfig(libhardware)
BuildRequires: pkgconfig(dbus-1)
BuildRequires: pkgconfig(expat)
%description
PulseAudio Droid HAL modules.
%package common
Summary: Common libs for the PulseAudio droid modules
Requires: pulseaudio >= %{pulseversion}
%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}
%description devel
This contains development files for PulseAudio droid modules.
%prep
%setup -q -n %{name}-%{version}
%autosetup -n %{name}-%{version}
%build
echo "%{moduleversion}" > .tarball-version
# Obtain the DEVICE from the same source as used in /etc/os-release
. /usr/lib/droid-devel/hw-release.vars
if [ -e "%{_includedir}/droid-devel/hw-release.vars" ]; then
. %{_includedir}/droid-devel/hw-release.vars
else
. %{_libdir}/droid-devel/hw-release.vars
fi
%reconfigure --disable-static --with-droid-device=$MER_HA_DEVICE
make %{?jobs:-j%jobs}
%make_build
%install
rm -rf %{buildroot}
%make_install
%files
%defattr(-,root,root,-)
%{_libdir}/pulse-%{pulsemajorminor}/modules/*.so
%{_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 %{_includedir}/pulsecore/modules/droid
%{_includedir}/pulsecore/modules/droid/conversion.h
%{_includedir}/pulsecore/modules/droid/droid-config.h
%{_includedir}/pulsecore/modules/droid/droid-util.h
%{_includedir}/pulsecore/modules/droid/sllist.h
%{_includedir}/pulsecore/modules/droid/utils.h
%{_includedir}/pulsecore/modules/droid/version.h
%{_libdir}/pkgconfig/*.pc

View file

@ -1 +1 @@
SUBDIRS = droid
SUBDIRS = common droid

38
src/common/Makefile.am Normal file
View file

@ -0,0 +1,38 @@
AM_LIBADD = \
$(PULSEAUDIO_LIBS) \
$(HYBRIS_LIBS) \
$(EXPAT_LIBS)
AM_CFLAGS = \
$(DROID_DEVICE_CFLAGS) \
$(PULSEAUDIO_CFLAGS) \
$(DROIDHEADERS_CFLAGS) \
$(HYBRIS_CFLAGS) \
$(EXPAT_CFLAGS) \
-DPULSEAUDIO_VERSION=@PA_MAJOR@ \
-I$(top_srcdir)/src/common \
-I$(top_srcdir)/src/common/include
modlibexec_LTLIBRARIES = libdroid-util.la
includedir = @includedir@/pulsecore/modules/droid
include_HEADERS = include/droid/version.h \
include/droid/conversion.h \
include/droid/droid-config.h \
include/droid/droid-util.h \
include/droid/sllist.h \
include/droid/utils.h
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libdroid-util.pc
libdroid_util_la_SOURCES = droid-util.c \
droid-config.c \
conversion.c \
config-parser-xml.c \
config-parser-xml.h \
sllist.c \
utils.c \
droid-util-audio.h
libdroid_util_la_LDFLAGS = -avoid-version -Wl,-z,noexecstack -lhybris-common $(SBJ_DEVICE_LDFLAGS)
libdroid_util_la_LIBADD = $(AM_LIBADD)
libdroid_util_la_CFLAGS = $(AM_CFLAGS)

File diff suppressed because it is too large Load diff

View file

@ -1,10 +1,10 @@
#ifndef foodroidkeepalivefoo
#define foodroidkeepalivefoo
#ifndef foodroidconfigparserxmlfoo
#define foodroidconfigparserxmlfoo
/*
* Copyright (C) 2013 Jolla Ltd.
* Copyright (C) 2022 Jolla Ltd.
*
* Contact: Juho Hämäläinen <juho.hamalainen@tieto.com>
* 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
@ -26,19 +26,8 @@
#include <config.h>
#endif
#include <pulsecore/core.h>
#include <pulsecore/core-util.h>
#include <pulsecore/macro.h>
#include <pulsecore/dbus-shared.h>
#include <pulsecore/atomic.h>
typedef struct pa_droid_keepalive pa_droid_keepalive;
pa_droid_keepalive* pa_droid_keepalive_new(pa_core *c);
void pa_droid_keepalive_free(pa_droid_keepalive *k);
void pa_droid_keepalive_start(pa_droid_keepalive *k);
void pa_droid_keepalive_stop(pa_droid_keepalive *k);
#include <droid/droid-config.h>
dm_config_device *pa_parse_droid_audio_config_xml(const char *filename);
#endif

529
src/common/conversion.c Normal file
View file

@ -0,0 +1,529 @@
/*
* Copyright (C) 2013-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/version.h"
#if ANDROID_VERSION_MAJOR == 4 && ANDROID_VERSION_MINOR == 1
#include "droid-util-41qc.h"
#else
#include "droid-util-audio.h"
#endif
#include <pulsecore/core-util.h>
#include <hardware/audio.h>
#include "droid/conversion.h"
#include "droid/droid-config.h"
#define CONVERT_FUNC(TABL) \
bool pa_convert_ ## TABL (uint32_t value, pa_conversion_field_t field, uint32_t *to_value) { \
for (unsigned int i = 0; i < sizeof( conversion_table_ ## TABL )/(sizeof(uint32_t)*2); i++) { \
if ( conversion_table_ ## TABL [i][field] == value) { \
*to_value = conversion_table_ ## TABL [i][!field]; \
return true; \
} \
} \
return false; \
} struct __funny_extra_to_allow_semicolon
/* Creates convert_format convert_channel etc.
* bool pa_convert_func(uint32_t value, pa_conversion_field_t field, uint32_t *to_value);
* return true if conversion succesful */
CONVERT_FUNC(format);
CONVERT_FUNC(output_channel);
CONVERT_FUNC(input_channel);
#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);
pa_assert(to_str);
for (unsigned int i = 0; list[i].str; i++) {
if (list[i].value == value) {
*to_str = list[i].str;
return true;
}
}
return false;
}
static bool string_convert_str_to_num(const struct string_conversion *list, const char *str, uint32_t *to_value) {
pa_assert(list);
pa_assert(str);
pa_assert(to_value);
for (unsigned int i = 0; list[i].str; i++) {
if (pa_streq(list[i].str, str)) {
*to_value = list[i].value;
return true;
}
}
return false;
}
static char *list_string(struct string_conversion *list, uint32_t flags) {
char *str = NULL;
char *tmp;
for (unsigned int i = 0; list[i].str; i++) {
if (popcount(list[i].value) != 1)
continue;
if (flags & list[i].value) {
if (str) {
tmp = pa_sprintf_malloc("%s|%s", str, list[i].str);
pa_xfree(str);
str = tmp;
} else {
str = pa_sprintf_malloc("%s", list[i].str);
}
}
}
return str;
}
/* Generic conversion */
bool pa_string_convert_num_to_str(pa_conversion_string_t type, uint32_t value, const char **to_str) {
switch (type) {
case CONV_STRING_FORMAT:
return string_convert_num_to_str(string_conversion_table_format, value, to_str);
case CONV_STRING_OUTPUT_CHANNELS:
return string_convert_num_to_str(string_conversion_table_output_channels, value, to_str);
case CONV_STRING_INPUT_CHANNELS:
return string_convert_num_to_str(string_conversion_table_input_channels, value, to_str);
case CONV_STRING_OUTPUT_DEVICE:
return string_convert_num_to_str(string_conversion_table_output_device, value, to_str);
case CONV_STRING_INPUT_DEVICE:
return string_convert_num_to_str(string_conversion_table_input_device, value, to_str);
case CONV_STRING_OUTPUT_FLAG:
return string_convert_num_to_str(string_conversion_table_output_flag, value, to_str);
case CONV_STRING_INPUT_FLAG:
return string_convert_num_to_str(string_conversion_table_input_flag, value, to_str);
case CONV_STRING_AUDIO_SOURCE_FANCY:
return string_convert_num_to_str(string_conversion_table_audio_source_fancy, value, to_str);
}
pa_assert_not_reached();
return false;
}
bool pa_string_convert_str_to_num(pa_conversion_string_t type, const char *str, uint32_t *to_value) {
switch (type) {
case CONV_STRING_FORMAT:
return string_convert_str_to_num(string_conversion_table_format, str, to_value);
case CONV_STRING_OUTPUT_CHANNELS:
return string_convert_str_to_num(string_conversion_table_output_channels, str, to_value);
case CONV_STRING_INPUT_CHANNELS:
return string_convert_str_to_num(string_conversion_table_input_channels, str, to_value);
case CONV_STRING_OUTPUT_DEVICE:
return string_convert_str_to_num(string_conversion_table_output_device, str, to_value);
case CONV_STRING_INPUT_DEVICE:
return string_convert_str_to_num(string_conversion_table_input_device, str, to_value);
case CONV_STRING_OUTPUT_FLAG:
return string_convert_str_to_num(string_conversion_table_output_flag, str, to_value);
case CONV_STRING_INPUT_FLAG:
return string_convert_str_to_num(string_conversion_table_input_flag, str, to_value);
case CONV_STRING_AUDIO_SOURCE_FANCY:
return string_convert_str_to_num(string_conversion_table_audio_source_fancy, str, to_value);
}
pa_assert_not_reached();
return false;
}
/* Output device */
bool pa_string_convert_output_device_num_to_str(audio_devices_t value, const char **to_str) {
return string_convert_num_to_str(string_conversion_table_output_device, (uint32_t) value, to_str);
}
bool pa_string_convert_output_device_str_to_num(const char *str, audio_devices_t *to_value) {
return string_convert_str_to_num(string_conversion_table_output_device, str, (uint32_t*) to_value);
}
/* 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);
}
bool pa_string_convert_input_device_str_to_num(const char *str, audio_devices_t *to_value) {
return string_convert_str_to_num(string_conversion_table_input_device, str, (uint32_t*) to_value);
}
/* 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);
}
bool pa_string_convert_flag_str_to_num(const char *str, audio_output_flags_t *to_value) {
return string_convert_str_to_num(string_conversion_table_output_flag, str, (uint32_t*) to_value);
}
char *pa_list_string_flags(audio_output_flags_t flags) {
return list_string(string_conversion_table_output_flag, flags);
}
bool pa_input_device_default_audio_source(audio_devices_t input_device, audio_source_t *default_source)
{
/* 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) {
*default_source = conversion_table_default_audio_source[i][1];
return true;
}
}
return false;
}
bool pa_droid_output_port_name(audio_devices_t value, const char **to_str) {
return string_convert_num_to_str(string_conversion_table_output_device_fancy, (uint32_t) value, to_str);
}
bool pa_droid_input_port_name(audio_devices_t value, const char **to_str) {
return string_convert_num_to_str(string_conversion_table_input_device_fancy, (uint32_t) value, to_str);
}
static int parse_list(const struct string_conversion *table,
const char *separator,
const char *str,
uint32_t *dst,
char **unknown_entries) {
int count = 0;
char *entry;
char *unknown = NULL;
const char *state = NULL;
pa_assert(table);
pa_assert(separator);
pa_assert(str);
pa_assert(dst);
pa_assert(unknown_entries);
*dst = 0;
*unknown_entries = NULL;
while ((entry = pa_split(str, separator, &state))) {
uint32_t d = 0;
if (!string_convert_str_to_num(table, entry, &d)) {
if (*unknown_entries) {
unknown = pa_sprintf_malloc("%s|%s", *unknown_entries, entry);
pa_xfree(*unknown_entries);
pa_xfree(entry);
} else
unknown = entry;
*unknown_entries = unknown;
continue;
}
*dst |= d;
count++;
pa_xfree(entry);
}
return count;
}
int pa_conversion_parse_list(pa_conversion_string_t type, const char *separator,
const char *str, uint32_t *dst, char **unknown_entries) {
switch (type) {
case CONV_STRING_FORMAT:
return parse_list(string_conversion_table_format, separator, str, dst, unknown_entries);
case CONV_STRING_OUTPUT_CHANNELS:
return parse_list(string_conversion_table_output_channels, separator, str, dst, unknown_entries);
case CONV_STRING_INPUT_CHANNELS:
return parse_list(string_conversion_table_input_channels, separator, str, dst, unknown_entries);
case CONV_STRING_OUTPUT_DEVICE:
return parse_list(string_conversion_table_output_device, separator, str, dst, unknown_entries);
case CONV_STRING_INPUT_DEVICE:
return parse_list(string_conversion_table_input_device, separator, str, dst, unknown_entries);
case CONV_STRING_OUTPUT_FLAG:
return parse_list(string_conversion_table_output_flag, separator, str, dst, unknown_entries);
case CONV_STRING_INPUT_FLAG:
return parse_list(string_conversion_table_input_flag, separator, str, dst, unknown_entries);
/* Not handled in this context */
case CONV_STRING_AUDIO_SOURCE_FANCY:
return 0;
}
pa_assert_not_reached();
return 0;
}
bool pa_conversion_parse_sampling_rates(const char *fn, const unsigned ln,
const char *str,
uint32_t sampling_rates[AUDIO_MAX_SAMPLING_RATES]) {
pa_assert(fn);
pa_assert(str);
char *entry;
const char *state = NULL;
uint32_t pos = 0;
while ((entry = pa_split(str, VALUE_SEPARATOR, &state))) {
int32_t val;
if (pos == 0 && pa_streq(entry, "dynamic")) {
sampling_rates[pos++] = (uint32_t) -1;
pa_xfree(entry);
break;
}
if (pos == AUDIO_MAX_SAMPLING_RATES) {
pa_log("[%s:%u] Too many sample rate entries (> %d)", fn, ln, AUDIO_MAX_SAMPLING_RATES);
pa_xfree(entry);
return false;
}
if (pa_atoi(entry, &val) < 0) {
pa_log("[%s:%u] Bad sample rate value %s", fn, ln, entry);
pa_xfree(entry);
return false;
}
sampling_rates[pos++] = val;
pa_xfree(entry);
}
sampling_rates[pos] = 0;
return true;
}
static bool check_and_log(const char *fn, const unsigned ln, const char *field,
const int count, const char *str, char *unknown,
const bool must_recognize_all) {
bool fail;
pa_assert(fn);
pa_assert(field);
pa_assert(str);
fail = must_recognize_all && unknown;
if (unknown) {
pa_log_info("[%s:%u] Unknown %s entries: %s", fn, ln, field, unknown);
pa_xfree(unknown);
}
if (count == 0 || fail) {
pa_log("[%s:%u] Failed to parse %s (%s).", fn, ln, field, str);
return false;
}
return true;
}
bool pa_conversion_parse_formats(const char *fn, const unsigned ln,
const char *str,
audio_format_t *formats) {
int count;
char *unknown = NULL;
pa_assert(fn);
pa_assert(str);
pa_assert(formats);
/* Needs to be probed later */
if (pa_streq(str, "dynamic")) {
*formats = 0;
return true;
}
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
* conversions with no recognized formats log only info level and return false. */
check_and_log(fn, ln, "format", count == 0 ? 1 : count, str, unknown, false);
return count > 0;
}
static int parse_channels(const char *fn, const unsigned ln,
const char *str, bool in_output,
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);
/* Needs to be probed later */
if (pa_streq(str, "dynamic")) {
channel_masks[0] = 0;
return 1;
}
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",
count == 0 ? 1 : count, str, unknown, false);
return success ? count : -1;
}
int pa_conversion_parse_output_channels(const char *fn, const unsigned ln,
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,
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 must_recognize_all,
audio_devices_t *devices) {
int count;
char *unknown = NULL;
pa_assert(fn);
pa_assert(str);
pa_assert(devices);
count = pa_conversion_parse_list(in_output ? CONV_STRING_OUTPUT_DEVICE : CONV_STRING_INPUT_DEVICE,
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
* conversions with no recognized devices log only info level and return false. */
check_and_log(fn, ln, in_output ? "output device" : "input device",
count == 0 ? 1 : count, str, unknown, must_recognize_all);
return count > 0;
}
bool pa_conversion_parse_output_devices(const char *fn, const unsigned ln,
char *str, bool must_recognize_all,
audio_devices_t *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 must_recognize_all,
audio_devices_t *devices) {
return parse_devices(fn, ln, str, false, must_recognize_all, devices);
}
bool pa_conversion_parse_output_flags(const char *fn, const unsigned ln,
const char *str, audio_output_flags_t *flags) {
int count;
char *unknown = NULL;
pa_assert(fn);
pa_assert(str);
pa_assert(flags);
count = pa_conversion_parse_list(CONV_STRING_OUTPUT_FLAG, "|", str, flags, &unknown);
return check_and_log(fn, ln, "flags", count, str, unknown, false);
}
bool pa_conversion_parse_input_flags(const char *fn, const unsigned ln,
const char *str, uint32_t *flags) {
int count;
char *unknown = NULL;
pa_assert(fn);
pa_assert(str);
pa_assert(flags);
count = pa_conversion_parse_list(CONV_STRING_INPUT_FLAG, "|", str, flags, &unknown);
return check_and_log(fn, ln, "flags", count, str, unknown, false);
}
bool pa_conversion_parse_version(const char *fn, const unsigned ln, const char *str, uint32_t *version) {
uint32_t version_maj;
uint32_t version_min;
pa_assert(fn);
pa_assert(str);
pa_assert(version);
if ((sscanf(str, "%u.%u", &version_maj, &version_min)) != 2) {
pa_log("[%s:%u] Failed to parse %s (%s).", fn, ln, AUDIO_HAL_VERSION_TAG, str);
return false;
} else {
*version = HARDWARE_DEVICE_API_VERSION(version_maj, version_min);
return true;
}
}

366
src/common/droid-config.c Normal file
View file

@ -0,0 +1,366 @@
/*
* Copyright (C) 2013-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/version.h"
#include "droid/droid-config.h"
#include "droid/sllist.h"
#include "config-parser-xml.h"
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#ifdef HAVE_VALGRIND_MEMCHECK_H
#include <valgrind/memcheck.h>
#endif
#include <pulse/xmalloc.h>
#include <pulsecore/core-util.h>
#include <pulsecore/log.h>
#include <pulsecore/macro.h>
#include <pulsecore/modargs.h>
#include <hardware/audio.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"
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,
SYSTEM_AUDIO_POLICY_CONFIG_XML_FILE,
NULL};
pa_assert(ma);
if ((manual_config = pa_modargs_get_value(ma, "config", NULL))) {
if (!(config = pa_parse_droid_audio_config(manual_config)))
pa_log("Failed to parse configuration from %s", manual_config);
} else {
int i;
for (i = 0; config_location[i]; i++) {
if ((config = pa_parse_droid_audio_config(config_location[i])))
break;
else
pa_log_debug("Failed to parse configuration from %s", config_location[i]);
}
}
if (!config)
pa_log("Failed to parse any configuration.");
return config;
}
static dm_config_profile *config_profile_dup(const dm_config_profile *profile) {
dm_config_profile *copy = pa_xnew0(dm_config_profile, 1);
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;
}
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;
copy->type = route->type;
copy->sources = dm_list_new();
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;
}
}
}
DM_LIST_FOREACH_DATA(port_copy, ports, state) {
if (dm_config_port_equal(port_copy, route->sink)) {
copy->sink = port_copy;
break;
}
}
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;
}
}
}
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;
}
dm_config_device *dm_config_dup(const dm_config_device *config) {
dm_config_device *copy;
dm_config_module *module;
void *state;
pa_assert(config);
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);
}
}
DM_LIST_FOREACH_DATA(module, config->modules, state)
dm_list_push_back(copy->modules, config_module_dup(module));
return copy;
}
dm_config_device *pa_parse_droid_audio_config(const char *filename) {
return pa_parse_droid_audio_config_xml(filename);
}
static void config_global_free(void *data) {
dm_config_global *global = data;
pa_xfree(global->key);
pa_xfree(global->value);
pa_xfree(global);
}
static void config_profile_free(void *data) {
dm_config_profile *profile = data;
pa_xfree(profile->name);
pa_xfree(profile);
}
static void config_port_free(void *data) {
dm_config_port *port = data;
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);
}
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);
DM_LIST_FOREACH_DATA(module, config->modules, state) {
if (pa_streq(module_id, module->name))
return module;
}
return NULL;
}
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(name);
DM_LIST_FOREACH_DATA(port, module->ports, state) {
if (pa_streq(name, port->name))
return port;
}
return NULL;
}
dm_config_port *dm_config_default_output_device(dm_config_module *module) {
pa_assert(module);
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;
}
}
char *dm_config_escape_string(const char *string) {
if (!string)
return NULL;
/* Just replace whitespace with underscores for now. */
return pa_replace(string, " ", "_");
}
dm_config_port *dm_config_find_device_port(dm_config_port *port, audio_devices_t device) {
dm_config_port *device_port;
void *state;
pa_assert(port);
DM_LIST_FOREACH_DATA(device_port, port->module->device_ports, state) {
if (device_port->type == device)
return device_port;
}
return NULL;
}
bool dm_config_port_equal(const dm_config_port *a, const dm_config_port *b) {
if ((!a && b) || (a && !b))
return false;
else if (!a && !b)
return true;
return (pa_streq(a->name, b->name) && a->type == b->type);
}
dm_config_port *dm_config_find_mix_port(dm_config_module *module, const char *name) {
dm_config_port *mix_port = NULL;
void *state;
DM_LIST_FOREACH_DATA(mix_port, module->mix_ports, state) {
if (pa_streq(mix_port->name, name))
return mix_port;
}
return NULL;
}

View file

@ -0,0 +1,433 @@
/*
* Copyright (C) 2017-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.
*/
#ifndef _DROID_UTIL_AUDIO_H_
#define _DROID_UTIL_AUDIO_H_
#include <android-config.h>
#ifdef QCOM_BSP
#define QCOM_HARDWARE
#endif
#include <hardware/audio.h>
#include <pulse/channelmap.h>
#ifdef STRING_ENTRY
#error Macro clashing with our helper macro already defined somewhere, fix this droid lib.
#endif
struct string_conversion {
uint32_t value;
const char *str;
};
#define STRING_ENTRY(str) { str, #str }
// 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. */
{ PA_CHANNEL_POSITION_FRONT_LEFT, AUDIO_CHANNEL_IN_LEFT_PROCESSED },
{ PA_CHANNEL_POSITION_FRONT_RIGHT, AUDIO_CHANNEL_IN_RIGHT_PROCESSED },
{ PA_CHANNEL_POSITION_FRONT_CENTER, AUDIO_CHANNEL_IN_FRONT_PROCESSED },
{ PA_CHANNEL_POSITION_REAR_CENTER, AUDIO_CHANNEL_IN_BACK_PROCESSED },
{ PA_CHANNEL_POSITION_SUBWOOFER, AUDIO_CHANNEL_IN_PRESSURE },
{ PA_CHANNEL_POSITION_AUX0, AUDIO_CHANNEL_IN_X_AXIS },
{ PA_CHANNEL_POSITION_AUX1, AUDIO_CHANNEL_IN_Y_AXIS },
{ PA_CHANNEL_POSITION_AUX2, AUDIO_CHANNEL_IN_Z_AXIS },
{ PA_CHANNEL_POSITION_MONO, AUDIO_CHANNEL_IN_VOICE_UPLINK },
{ PA_CHANNEL_POSITION_MONO, 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_S24_32LE, AUDIO_FORMAT_PCM_8_24_BIT },
{ PA_SAMPLE_S24LE, AUDIO_FORMAT_PCM_24_BIT_PACKED },
{ PA_SAMPLE_S32LE, AUDIO_FORMAT_PCM_32_BIT }
};
uint32_t conversion_table_default_audio_source[][2] = {
{ AUDIO_DEVICE_IN_COMMUNICATION, AUDIO_SOURCE_MIC },
{ AUDIO_DEVICE_IN_AMBIENT, AUDIO_SOURCE_MIC },
{ AUDIO_DEVICE_IN_BUILTIN_MIC, AUDIO_SOURCE_MIC },
{ AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, AUDIO_SOURCE_MIC },
{ 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_RX_A2DP) && defined(HAVE_ENUM_AUDIO_SOURCE_FM_RX_A2DP)
{ AUDIO_DEVICE_IN_FM_RX_A2DP, AUDIO_SOURCE_FM_RX_A2DP },
#endif
};
/* Output devices */
struct string_conversion string_conversion_table_output_device[] = {
/* Each device listed here needs fancy name counterpart
* in string_conversion_table_output_device_fancy. */
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_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 ),
{ 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 }
};
struct string_conversion string_conversion_table_output_device_fancy[] = {
{ AUDIO_DEVICE_OUT_EARPIECE, "output-earpiece" },
{ AUDIO_DEVICE_OUT_SPEAKER, "output-speaker" },
{ 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_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" },
{ 0, NULL }
};
/* Input devices */
struct string_conversion string_conversion_table_input_device[] = {
/* Each device listed here needs fancy name counterpart
* in string_conversion_table_input_device_fancy. */
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_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. */
STRING_ENTRY_IF_AUDIO_DEVICE_IN_FM_RX
STRING_ENTRY_IF_AUDIO_DEVICE_IN_FM_RX_A2DP
{ 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_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_FM_RX ( "input-fm_rx" )
FANCY_ENTRY_IF_AUDIO_DEVICE_IN_FM_RX_A2DP ( "input-fm_rx_a2dp" )
{ 0, NULL }
};
/* Audio source fancy names */
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_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. */
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" )
{ (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 ),
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. */
STRING_ENTRY_IF_AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH
{ 0, NULL }
};
struct string_conversion string_conversion_table_input_flag[] = {
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 }
};
/* 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 ),
{ 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_FRONT_BACK ),
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
{ 0, NULL }
};
/* Formats */
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_AMR_NB ),
STRING_ENTRY( AUDIO_FORMAT_AMR_WB ),
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 ),
{ 0, NULL }
};
#undef STRING_ENTRY
#endif

2596
src/common/droid-util.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,111 @@
#ifndef foodroidconversionfoo
#define foodroidconversionfoo
/*
* Copyright (C) 2018-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 <pulsecore/modargs.h>
#include <hardware/audio.h>
/* From recent audio_policy_conf.h */
#ifndef AUDIO_HAL_VERSION_TAG
#define AUDIO_HAL_VERSION_TAG "audio_hal_version"
#endif
#ifndef GAINS_TAG
#define GAINS_TAG "gains"
#endif
#include <droid/version.h>
#include <droid/droid-config.h>
typedef enum {
CONV_FROM_PA,
CONV_FROM_HAL
} pa_conversion_field_t;
typedef enum {
CONV_STRING_FORMAT,
CONV_STRING_OUTPUT_CHANNELS,
CONV_STRING_INPUT_CHANNELS,
CONV_STRING_OUTPUT_DEVICE,
CONV_STRING_INPUT_DEVICE,
CONV_STRING_OUTPUT_FLAG,
CONV_STRING_INPUT_FLAG,
CONV_STRING_AUDIO_SOURCE_FANCY,
} pa_conversion_string_t;
bool pa_string_convert_num_to_str(pa_conversion_string_t type, uint32_t value, const char **to_str);
bool pa_string_convert_str_to_num(pa_conversion_string_t type, const char *str, uint32_t *to_value);
bool pa_convert_output_channel(uint32_t value, pa_conversion_field_t from, uint32_t *to_value);
bool pa_convert_input_channel(uint32_t value, pa_conversion_field_t from, uint32_t *to_value);
bool pa_convert_format(uint32_t value, pa_conversion_field_t from, uint32_t *to_value);
bool pa_string_convert_output_device_num_to_str(audio_devices_t value, const char **to_str);
bool pa_string_convert_output_device_str_to_num(const char *str, audio_devices_t *to_value);
bool pa_string_convert_input_device_num_to_str(audio_devices_t value, const char **to_str);
bool pa_string_convert_input_device_str_to_num(const char *str, audio_devices_t *to_value);
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_flags(audio_output_flags_t flags);
/* Get default audio source associated with input device.
* Return true if default source was found. */
bool pa_input_device_default_audio_source(audio_devices_t input_device, audio_source_t *default_source);
/* Pretty port names */
bool pa_droid_output_port_name(audio_devices_t value, const char **to_str);
bool pa_droid_input_port_name(audio_devices_t value, const char **to_str);
int pa_conversion_parse_list(pa_conversion_string_t type, const char *separator,
const char *str, uint32_t *dst, char **unknown_entries);
bool pa_conversion_parse_sampling_rates(const char *fn, const unsigned ln,
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,
audio_format_t *formats);
int pa_conversion_parse_output_channels(const char *fn, const unsigned ln,
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,
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 must_recognize_all,
audio_devices_t *devices);
bool pa_conversion_parse_input_devices(const char *fn, const unsigned ln,
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);
bool pa_conversion_parse_input_flags(const char *fn, const unsigned ln,
const char *str, uint32_t *flags);
bool pa_conversion_parse_version(const char *fn, const unsigned ln, const char *str, uint32_t *version);
#endif

View file

@ -0,0 +1,135 @@
#ifndef foodroidconfigfoo
#define foodroidconfigfoo
/*
* Copyright (C) 2018-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 <pulsecore/modargs.h>
#include <android-config.h>
#include <hardware/audio.h>
#include <droid/sllist.h>
#include <droid/version.h>
#define AUDIO_MAX_SAMPLING_RATES (32)
#define AUDIO_MAX_CHANNEL_MASKS (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 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;
struct dm_config_port {
dm_config_module *module;
/* common values */
dm_config_type_t port_type; /* either mixPort or devicePort */
char *name;
dm_config_role_t role;
dm_list *profiles; /* dm_config_profile* */
/* devicePort specific values */
audio_devices_t type;
char *address;
/* mixPort specific values */
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;
int version_major;
int version_minor;
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 dm_config_device {
dm_list *global_config; /* dm_config_global* */
dm_list *modules; /* dm_config_module* */
};
/* Config parser */
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 */
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);
dm_config_port *dm_config_find_mix_port(dm_config_module *module, const char *name);
#endif

View file

@ -0,0 +1,358 @@
#ifndef foodroidutilfoo
#define foodroidutilfoo
/*
* Copyright (C) 2013-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 <pulsecore/core-util.h>
#include <pulsecore/macro.h>
#include <pulsecore/mutex.h>
#include <pulsecore/strlist.h>
#include <pulsecore/atomic.h>
#include <pulsecore/modargs.h>
#include <droid/version.h>
#include <droid/droid-config.h>
#define PROP_DROID_DEVICES "droid.devices"
#define PROP_DROID_FLAGS "droid.flags"
#define PROP_DROID_HW_MODULE "droid.hw_module"
#define PROP_DROID_API_STRING "droid-hal"
#define PROP_DROID_OUTPUT_PRIMARY "droid.output.primary"
#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"
#define PA_DROID_PRIMARY_DEVICE "primary"
typedef struct pa_droid_hw_module pa_droid_hw_module;
typedef struct pa_droid_stream pa_droid_stream;
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 struct pa_droid_options pa_droid_options;
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_options {
bool enabled[DM_OPTION_COUNT];
};
struct pa_droid_hw_module {
PA_REFCNT_DECLARE;
pa_core *core;
char *shared_name;
dm_config_device *config;
dm_config_module *enabled_module;
pa_mutex *hw_mutex;
pa_mutex *output_mutex;
pa_mutex *input_mutex;
struct hw_module_t *hwmod;
audio_hw_device_t *device;
const char *module_id;
uint32_t stream_id;
bool bt_sco_enabled;
pa_idxset *outputs;
pa_idxset *inputs;
pa_hook_slot *sink_put_hook_slot;
pa_hook_slot *sink_unlink_hook_slot;
pa_atomic_t active_outputs;
pa_droid_options options;
/* Mode and input control */
struct _state {
audio_mode_t mode;
} state;
};
struct pa_droid_output_stream {
struct audio_stream_out *stream;
pa_sample_spec sample_spec;
pa_channel_map channel_map;
};
struct pa_droid_input_stream {
struct audio_stream_in *stream;
pa_sample_spec default_sample_spec;
pa_channel_map default_channel_map;
pa_sample_spec sample_spec;
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;
};
struct pa_droid_stream {
PA_REFCNT_DECLARE;
pa_droid_hw_module *module;
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;
char *module_id;
};
/* Profiles */
typedef struct pa_droid_profile_set pa_droid_profile_set;
typedef struct pa_droid_mapping pa_droid_mapping;
typedef struct pa_droid_port_data {
dm_config_port *device_port;
} pa_droid_port_data;
typedef struct pa_droid_port {
pa_droid_mapping *mapping;
dm_config_port *device_port;
char *name;
char *description;
unsigned priority;
} pa_droid_port;
struct pa_droid_mapping {
pa_droid_profile_set *profile_set;
dm_config_module *module;
dm_config_port *mix_port;
dm_list *device_ports;
char *name;
char *description;
unsigned priority;
pa_proplist *proplist;
/* Mapping doesn't own the ports */
pa_idxset *ports;
pa_direction_t direction;
pa_sink *sink;
pa_source *source;
};
typedef struct pa_droid_profile {
pa_droid_profile_set *profile_set;
dm_config_module *module;
char *name;
char *description;
unsigned priority;
/* Idxsets contain pa_droid_mapping objects.
* Profile doesn't own the mappings, these
* are references to structs in profile set
* 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 {
dm_config_device *config;
pa_hashmap *all_ports;
pa_hashmap *output_mappings;
pa_hashmap *input_mappings;
pa_hashmap *profiles;
};
#define PA_DROID_OUTPUT_PARKING "output-parking"
#define PA_DROID_INPUT_PARKING "input-parking"
/* 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, 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);
void pa_droid_hw_module_unref(pa_droid_hw_module *hw);
void pa_droid_hw_module_lock(pa_droid_hw_module *hw);
bool pa_droid_hw_module_try_lock(pa_droid_hw_module *hw);
void pa_droid_hw_module_unlock(pa_droid_hw_module *hw);
void pa_droid_options_log(pa_droid_hw_module *hw);
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);
bool pa_droid_hw_has_mic_control(pa_droid_hw_module *hw);
int pa_droid_hw_mic_get_mute(pa_droid_hw_module *hw_module, bool *muted);
void pa_droid_hw_mic_set_mute(pa_droid_hw_module *hw_module, bool muted);
/* Profiles */
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_free(pa_droid_profile *p);
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. */
pa_droid_mapping *pa_droid_idxset_get_primary(pa_idxset *i);
void pa_droid_mapping_free(pa_droid_mapping *am);
/* Add ports from sinks/sources.
* May be called multiple times for one sink/source. */
void pa_droid_add_ports(pa_hashmap *ports, pa_droid_mapping *am, pa_card *card);
/* Add ports from card.
* May be called multiple times for one card profile. */
void pa_droid_add_card_ports(pa_card_profile *cp, pa_hashmap *ports, pa_droid_mapping *am, pa_core *core);
/* Module operations */
int pa_droid_set_parameters(pa_droid_hw_module *hw, const char *parameters);
pa_droid_stream *pa_droid_hw_primary_output_stream(pa_droid_hw_module *hw);
/* Stream operations */
pa_droid_stream *pa_droid_stream_ref(pa_droid_stream *s);
void pa_droid_stream_unref(pa_droid_stream *s);
int pa_droid_stream_set_parameters(pa_droid_stream *s, const char *parameters);
/* Output stream operations */
pa_droid_stream *pa_droid_open_output_stream(pa_droid_hw_module *module,
const pa_sample_spec *spec,
const pa_channel_map *map,
dm_config_port *mix_port,
dm_config_port *device_port);
/* Set routing to the input or output stream, with following side-effects:
* Output:
* - if routing is set to primary output stream, set routing to all other
* open streams as well
* - if routing is set to non-primary stream and primary stream exists, do nothing
* - if routing is set to non-primary stream and primary stream doesn't exist, set routing
* Input:
* - buffer size or channel count may change
*/
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 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,
const pa_channel_map *requested_channel_map,
const pa_proplist *proplist);
bool pa_droid_stream_reconfigure_input(pa_droid_stream *s,
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_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);
bool pa_droid_stream_is_primary(pa_droid_stream *s);
int pa_droid_stream_suspend(pa_droid_stream *s, bool suspend);
size_t pa_droid_stream_buffer_size(pa_droid_stream *s);
pa_usec_t pa_droid_stream_get_latency(pa_droid_stream *s);
static inline int pa_droid_output_stream_any_active(pa_droid_stream *s) {
return pa_atomic_load(&s->module->active_outputs);
}
static inline ssize_t pa_droid_stream_write(pa_droid_stream *stream, const void *buffer, size_t bytes) {
return stream->output->stream->write(stream->output->stream, buffer, bytes);
}
static inline ssize_t pa_droid_stream_read(pa_droid_stream *stream, void *buffer, size_t bytes) {
return stream->input->stream->read(stream->input->stream, buffer, bytes);
}
void pa_droid_stream_set_data(pa_droid_stream *s, void *data);
void *pa_droid_stream_get_data(pa_droid_stream *s);
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);
#endif

View file

@ -0,0 +1,94 @@
#ifndef foosllistfoo
#define foosllistfoo
/*
* Copyright (C) 2018-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 <stdbool.h>
#include <pulse/def.h>
#define SLLIST_APPEND(t, head, item) \
do { \
item->next = NULL; \
if (!head) { \
head = item; \
} else { \
t *_list; \
for (_list = head; _list->next; _list = _list->next); \
_list->next = item; \
} \
} while (0)
#define SLLIST_FOREACH(i, head) \
for (i = (head); i; i = i->next)
#define SLLIST_STEAL_FIRST(i, head) \
do { \
if (head) { \
i = head; \
head = head->next; \
} else \
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

View file

@ -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

View file

@ -0,0 +1,55 @@
#ifndef foodroidversionfoo
#define foodroidversionfoo
/*
* Copyright (C) 2018-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.
*/
#include <android-config.h>
#if defined(QCOM_BSP) || defined(DROID_DEVICE_SBJ)
#define QCOM_HARDWARE
#endif
#include <hardware/audio.h>
#if !defined(ANDROID_VERSION_MAJOR) || !defined(ANDROID_VERSION_MINOR) || !defined(ANDROID_VERSION_PATCH)
#error "ANDROID_VERSION_* not defined. Did you get your headers via extract-headers.sh?"
#endif
/* 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!
#warning Compile likely fails or module may malfunction.
#endif
#define AUDIO_API_VERSION_MAJ ((AUDIO_DEVICE_API_VERSION_CURRENT >> 8) & 0xff)
#define AUDIO_API_VERSION_MIN (AUDIO_DEVICE_API_VERSION_CURRENT & 0xff)
#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

View file

@ -0,0 +1,11 @@
prefix=@prefix@
exec_prefix=${prefix}
libdir=@libdir@
includedir=${prefix}/include
libexecdir=@libexecdir@
Name: libdroid-util
Description: Common droid module building interface.
Version: @PA_MODULE_VERSION@
Libs: -L${prefix}/lib/pulse-@PA_MAJORMINOR@/modules -ldroid-util
Cflags: -D_REENTRANT -I${includedir}/pulsecore/modules

172
src/common/sllist.c Normal file
View file

@ -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;
}

64
src/common/utils.c Normal file
View file

@ -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;
}

View file

@ -1,57 +1,45 @@
AM_LIBADD = \
$(PULSEAUDIO_LIBS) \
$(HYBRIS_LIBS)
AM_CFLAGS = \
$(DROID_DEVICE_CFLAGS) \
$(PULSEAUDIO_CFLAGS) \
$(DROIDHEADERS_CFLAGS) \
$(HYBRIS_CFLAGS) \
-DPULSEAUDIO_VERSION=@PA_MAJOR@ \
-I$(top_srcdir)/src/droid
-I$(top_srcdir)/src/droid \
-I$(top_srcdir)/src/common/include
modlibexec_LTLIBRARIES = \
libdroid-util.la \
libdroid-sink.la \
libdroid-source.la \
module-droid-keepalive.la \
module-droid-sink.la \
module-droid-source.la \
module-droid-card.la
noinst_HEADERS = module-droid-sink-symdef.h module-droid-source-symdef.h module-droid-card-symdef.h module-droid-keepalive-symdef.h
module_droid_keepalive_la_SOURCES = keepalive.c keepalive.h module-droid-keepalive.c
module_droid_keepalive_la_LDFLAGS = -module -avoid-version -Wl,-no-undefined -Wl,-z,noexecstack
module_droid_keepalive_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS)
module_droid_keepalive_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
libdroid_util_la_SOURCES = droid-util.c droid-util.h
libdroid_util_la_LDFLAGS = -avoid-version -Wl,-no-undefined -Wl,-z,noexecstack -lhybris-common
libdroid_util_la_LIBADD = $(AM_LIBADD)
libdroid_util_la_CFLAGS = $(AM_CFLAGS)
libdroid_sink_la_SOURCES = droid-sink.c droid-sink.h
libdroid_sink_la_LDFLAGS = -avoid-version -Wl,-no-undefined -Wl,-z,noexecstack -lhybris-common
libdroid_sink_la_LIBADD = $(AM_LIBADD) libdroid-util.la
libdroid_sink_la_LDFLAGS = -avoid-version -Wl,-z,noexecstack -lhybris-common
libdroid_sink_la_LIBADD = $(top_builddir)/src/common/libdroid-util.la $(AM_LIBADD)
libdroid_sink_la_CFLAGS = $(AM_CFLAGS)
libdroid_source_la_SOURCES = droid-source.c droid-source.h
libdroid_source_la_LDFLAGS = -avoid-version -Wl,-no-undefined -Wl,-z,noexecstack -lhybris-common
libdroid_source_la_LIBADD = $(AM_LIBADD) libdroid-util.la
libdroid_source_la_LDFLAGS = -avoid-version -Wl,-z,noexecstack -lhybris-common
libdroid_source_la_LIBADD = $(top_builddir)/src/common/libdroid-util.la $(AM_LIBADD)
libdroid_source_la_CFLAGS = $(AM_CFLAGS)
module_droid_sink_la_SOURCES = module-droid-sink.c
module_droid_sink_la_LDFLAGS = -module -avoid-version -Wl,-no-undefined -Wl,-z,noexecstack -lhybris-common
module_droid_sink_la_LIBADD = $(AM_LIBADD) -lm libdroid-util.la libdroid-sink.la
module_droid_sink_la_CFLAGS = $(AM_CFLAGS)
module_droid_sink_la_LDFLAGS = -module -avoid-version -Wl,-z,noexecstack -lhybris-common
module_droid_sink_la_LIBADD = -lm libdroid-sink.la $(AM_LIBADD)
module_droid_sink_la_CFLAGS = $(AM_CFLAGS) -DPA_MODULE_NAME=module_droid_sink
module_droid_source_la_SOURCES = module-droid-source.c
module_droid_source_la_LDFLAGS = -module -avoid-version -Wl,-no-undefined -Wl,-z,noexecstack -lhybris-common
module_droid_source_la_LIBADD = $(AM_LIBADD) -lm libdroid-util.la libdroid-source.la
module_droid_source_la_CFLAGS = $(AM_CFLAGS)
module_droid_source_la_LDFLAGS = -module -avoid-version -Wl,-z,noexecstack -lhybris-common
module_droid_source_la_LIBADD = -lm libdroid-source.la $(AM_LIBADD)
module_droid_source_la_CFLAGS = $(AM_CFLAGS) -DPA_MODULE_NAME=module_droid_source
module_droid_card_la_SOURCES = module-droid-card.c
module_droid_card_la_LDFLAGS = -module -avoid-version -Wl,-no-undefined -Wl,-z,noexecstack -lhybris-common
module_droid_card_la_LIBADD = $(AM_LIBADD) -lm libdroid-util.la libdroid-sink.la libdroid-source.la
module_droid_card_la_CFLAGS = $(AM_CFLAGS)
module_droid_card_la_SOURCES = module-droid-card.c droid-extcon.c droid-extevdev.c
module_droid_card_la_LDFLAGS = -module -avoid-version -Wl,-z,noexecstack -lhybris-common -ludev
module_droid_card_la_LIBADD = -lm libdroid-sink.la libdroid-source.la $(top_builddir)/src/common/libdroid-util.la $(AM_LIBADD) $(EVDEV_LIBS)
module_droid_card_la_CFLAGS = $(AM_CFLAGS) $(EVDEV_CFLAGS) -DPA_MODULE_NAME=module_droid_card

269
src/droid/droid-extcon.c Normal file
View file

@ -0,0 +1,269 @@
/***
This file is part of PulseAudio.
Copyright (C) 2013 Canonical Ltd.
Contact: David Henningsson
Ricardo Salveti de Araujo <ricardo.salveti@canonical.com>
PulseAudio is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 2.1 of the License,
or (at your option) any later version.
PulseAudio is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with PulseAudio; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA.
***/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <pulsecore/core-util.h>
#include <pulsecore/device-port.h>
#include <pulsecore/i18n.h>
#include <libudev.h>
#include "droid-extcon.h"
/* For android */
#define EXTCON_NAME "switch"
/* TODO: Backport stuff to 4.0, remove before upstreaming */
#ifndef PA_PORT_AVAILABLE_YES
#define PA_PORT_AVAILABLE_YES PA_AVAILABLE_YES
#define PA_PORT_AVAILABLE_NO PA_AVAILABLE_NO
#define PA_PORT_AVAILABLE_UNKNOWN PA_AVAILABLE_UNKNOWN
#define pa_port_available_t pa_available_t
#endif
static pa_port_available_t hponly_avail(int state)
{
return (state & 2) ? PA_PORT_AVAILABLE_YES : PA_PORT_AVAILABLE_NO;
}
static pa_port_available_t hsmic_avail(int state)
{
return (state & 1) ? PA_PORT_AVAILABLE_YES : PA_PORT_AVAILABLE_NO;
}
struct droid_switch {
char *name;
uint32_t current_value;
};
static void droid_switch_free(struct droid_switch *as) {
if (!as)
return;
pa_xfree(as->name);
pa_xfree(as);
}
static struct droid_switch *droid_switch_new(const char *name) {
struct droid_switch *as = NULL;
char *filename = pa_sprintf_malloc("/sys/class/%s/%s/state", EXTCON_NAME, name);
char *state = pa_read_line_from_file(filename);
if (state == NULL) {
pa_log_debug("Cannot open '%s'. Skipping.", filename);
pa_xfree(filename);
return NULL;
}
pa_xfree(filename);
as = pa_xnew0(struct droid_switch, 1);
as->name = pa_xstrdup(name);
if (pa_atou(state, &as->current_value) < 0) {
pa_log_warn("Switch '%s' has invalid value '%s'", name, state);
pa_xfree(state);
droid_switch_free(as);
return NULL;
}
pa_log_debug("Switch '%s' opened with value '%s'", name, state);
return as;
}
struct udev_data {
struct udev *udev;
struct udev_monitor *monitor;
pa_io_event *event;
};
struct pa_droid_extcon {
pa_card *card;
struct droid_switch *h2w;
struct udev_data udev;
};
static struct droid_switch *find_matching_switch(pa_droid_extcon *u,
const char *devpath) {
if (pa_streq(devpath, "/devices/virtual/" EXTCON_NAME "/h2w"))
return u->h2w; /* To be extended if we ever support more switches */
return NULL;
}
static void notify_ports(pa_droid_extcon *u, struct droid_switch *as) {
pa_device_port *p;
void *state;
pa_assert(as == u->h2w); /* To be extended if we ever support more switches */
pa_log_debug("Value of switch %s is now %d.", as->name, as->current_value);
PA_HASHMAP_FOREACH(p, u->card->ports, state) {
if (p->direction == PA_DIRECTION_OUTPUT) {
if (!strcmp(p->name, "output-wired_headset"))
pa_device_port_set_available(p, hsmic_avail(as->current_value));
if (!strcmp(p->name, "output-wired_headphone"))
pa_device_port_set_available(p, hponly_avail(as->current_value));
}
if (p->direction == PA_DIRECTION_INPUT) {
if (!strcmp(p->name, "input-wired_headset"))
pa_device_port_set_available(p, hsmic_avail(as->current_value));
}
}
}
static void udev_cb(pa_mainloop_api *a, pa_io_event *e, int fd,
pa_io_event_flags_t events, void *userdata) {
pa_droid_extcon *u = userdata;
struct udev_device *d = udev_monitor_receive_device(u->udev.monitor);
struct udev_list_entry *entry;
struct droid_switch *as;
const char *devpath, *state;
if (!d) {
pa_log("udev_monitor_receive_device failed.");
pa_assert(a);
a->io_free(u->udev.event);
u->udev.event = NULL;
return;
}
devpath = udev_device_get_devpath(d);
if (!devpath) {
pa_log("udev_device_get_devpath failed.");
goto out;
}
pa_log_debug("Got uevent with devpath=%s", devpath);
as = find_matching_switch(u, devpath);
if (!as)
goto out;
entry = udev_list_entry_get_by_name(
udev_device_get_properties_list_entry(d), "SWITCH_STATE");
if (!entry) {
pa_log("udev_list_entry_get_by_name failed to find 'SWITCH_STATE' entry.");
goto out;
}
state = udev_list_entry_get_value(entry);
if (!state) {
pa_log("udev_list_entry_get_by_name failed.");
goto out;
}
if (pa_atou(state, &as->current_value) < 0) {
pa_log_warn("Switch '%s' has invalid value '%s'", as->name, state);
goto out;
}
notify_ports(u, as);
out:
udev_device_unref(d);
}
static bool init_udev(pa_droid_extcon *u, pa_core *core) {
int fd;
u->udev.udev = udev_new();
if (!u->udev.udev) {
pa_log("udev_new failed.");
return false;
}
u->udev.monitor = udev_monitor_new_from_netlink(u->udev.udev, "udev");
if (!u->udev.monitor) {
pa_log("udev_monitor_new_from_netlink failed.");
return false;
}
if (udev_monitor_filter_add_match_subsystem_devtype(u->udev.monitor, EXTCON_NAME, NULL) < 0) {
pa_log("udev_monitor_filter_add_match_subsystem_devtype failed.");
return false;
}
if (udev_monitor_enable_receiving(u->udev.monitor) < 0) {
pa_log("udev_monitor_enable_receiving failed.");
return false;
}
fd = udev_monitor_get_fd(u->udev.monitor);
if (fd < 0) {
pa_log("udev_monitor_get_fd failed");
return false;
}
pa_assert_se(u->udev.event = core->mainloop->io_new(core->mainloop, fd,
PA_IO_EVENT_INPUT, udev_cb, u));
return true;
}
pa_droid_extcon *pa_droid_extcon_new(pa_core *core, pa_card *card) {
pa_droid_extcon *u = pa_xnew0(pa_droid_extcon, 1);
pa_assert(core);
pa_assert(card);
u->card = card;
u->h2w = droid_switch_new("h2w");
if (!u->h2w)
goto fail;
if (!init_udev(u, core))
goto fail;
notify_ports(u, u->h2w);
return u;
fail:
pa_droid_extcon_free(u);
return NULL;
}
void pa_droid_extcon_free(pa_droid_extcon *u) {
pa_assert(u);
if (u->udev.event)
u->card->core->mainloop->io_free(u->udev.event);
if (u->udev.monitor)
udev_monitor_unref(u->udev.monitor);
if (u->udev.udev)
udev_unref(u->udev.udev);
if (u->h2w)
droid_switch_free(u->h2w);
pa_xfree(u);
}

32
src/droid/droid-extcon.h Normal file
View file

@ -0,0 +1,32 @@
#ifndef foodroidextconhfoo
#define foodroidextconhfoo
/***
This file is part of PulseAudio.
Copyright (C) 2013 Canonical Ltd.
Contact: David Henningsson
PulseAudio is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 2.1 of the License,
or (at your option) any later version.
PulseAudio is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with PulseAudio; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA.
***/
typedef struct pa_droid_extcon pa_droid_extcon;
pa_droid_extcon *pa_droid_extcon_new(pa_core *, pa_card *);
void pa_droid_extcon_free(pa_droid_extcon *);
#endif

278
src/droid/droid-extevdev.c Normal file
View file

@ -0,0 +1,278 @@
/***
This file is part of PulseAudio.
Copyright (C) 2019 UBports foundation.
Author(s): Ratchanan Srirattanamet <ratchanan@ubports.com>
PulseAudio is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 2.1 of the License,
or (at your option) any later version.
PulseAudio is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with PulseAudio; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA.
***/
#define _GNU_SOURCE // For scandir and versionsort
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <dirent.h>
#include <fcntl.h>
#include <errno.h>
#include <libevdev/libevdev.h>
#include <pulsecore/core-util.h>
#include <pulsecore/device-port.h>
#include "droid-extevdev.h"
#define DEV_INPUT_EVENT "/dev/input"
#define EVENT_DEV_NAME "event"
#define N_ELEMENTS(X) (sizeof(X)/sizeof(*(X)))
struct pa_droid_extevdev {
pa_card *card;
struct libevdev *evdev_dev;
pa_io_event *event;
/* Switch values */
bool sw_headphone_insert : 1;
bool sw_microphone_insert : 1;
bool sw_lineout_insert : 1;
};
static int is_event_device(const struct dirent *dir) {
return strncmp(EVENT_DEV_NAME, dir->d_name, 5) == 0;
}
static struct libevdev *find_switch_evdev(void) {
struct dirent **namelist;
int ndev, i;
struct libevdev *ret = NULL;
ndev = scandir(DEV_INPUT_EVENT, &namelist, is_event_device, versionsort);
for (i=0; i<ndev; i++) {
char fname[PATH_MAX];
int fd;
struct libevdev *dev;
int err;
snprintf(fname, sizeof(fname),
"%s/%s", DEV_INPUT_EVENT, namelist[i]->d_name);
pa_log_debug("Checking %s for headphone switch.", fname);
fd = open(fname, O_RDONLY|O_NONBLOCK);
if (fd < 0) {
err = errno;
pa_log_warn("Unable to open device %s, ignored: %s",
fname, strerror(err));
continue;
}
if ((err = libevdev_new_from_fd(fd, &dev)) < 0) {
err = -err;
pa_log_warn("Unable to create libevdev device for %s, ignored: %s",
fname, strerror(err));
close(fd);
continue;
}
if (libevdev_has_event_code(dev, EV_SW, SW_HEADPHONE_INSERT)) {
ret = dev;
break;
}
libevdev_free(dev);
close(fd);
}
for (i=0; i<ndev; i++)
free(namelist[i]);
free(namelist);
return ret;
}
/* Put the port we want to be active (for each direction) later in the list.
* module-switch-on-port-available will switch to the available port as it
* become available, so the last port available will stay active. */
static const char *headphone_ports[] = {
"output-speaker+wired_headphone",
"output-wired_headphone",
};
static const char *headset_ports[] = {
"output-wired_headset",
"input-wired_headset",
};
static void notify_ports(pa_droid_extevdev *u) {
unsigned int i;
pa_log_debug("headphone: %d, microphone: %d, lineout: %d, yes: %d, no: %d", u->sw_headphone_insert,
u->sw_microphone_insert, u->sw_lineout_insert, PA_AVAILABLE_YES, PA_AVAILABLE_NO);
pa_available_t has_headphone =
((u->sw_headphone_insert || u->sw_lineout_insert)
&& !u->sw_microphone_insert) ? PA_AVAILABLE_YES : PA_AVAILABLE_NO;
pa_log_debug("has_headphone: %d", has_headphone);
for (i=0; i < N_ELEMENTS(headphone_ports); i++) {
pa_device_port *p = pa_hashmap_get(u->card->ports, headphone_ports[i]);
pa_log_debug("headphone device port %d, %p", i, p);
if (p)
pa_device_port_set_available(p, has_headphone);
}
pa_available_t has_headset =
((u->sw_headphone_insert || u->sw_lineout_insert)
&& u->sw_microphone_insert) ? PA_AVAILABLE_YES : PA_AVAILABLE_NO;
pa_log_debug("has_headset: %d", has_headset);
for (i=0; i < N_ELEMENTS(headset_ports); i++) {
pa_device_port *p = pa_hashmap_get(u->card->ports, headset_ports[i]);
if (p)
pa_device_port_set_available(p, has_headset);
}
}
/* Called from IO context */
static void evdev_cb(pa_mainloop_api *a, pa_io_event *e, int fd,
pa_io_event_flags_t events, void *userdata) {
pa_droid_extevdev *u = userdata;
unsigned int flags = LIBEVDEV_READ_FLAG_NORMAL;
int err;
struct input_event ev;
pa_log_debug("EV callback start...");
while (1) {
err = libevdev_next_event(u->evdev_dev, flags, &ev);
if (err == -EAGAIN) {
if (flags == LIBEVDEV_READ_FLAG_SYNC) {
/* Switch the flag back to read next normal events. */
flags = LIBEVDEV_READ_FLAG_NORMAL;
continue;
} else {
/* We run out of event. */
break;
}
} else if (err == LIBEVDEV_READ_STATUS_SYNC) {
if (flags == LIBEVDEV_READ_FLAG_NORMAL) {
/* Handle dropped events by switching to SYNC mode. */
flags = LIBEVDEV_READ_FLAG_SYNC;
continue;
} /* Otherwise we're in the middle of handling it. */
} else if (err < 0) {
pa_log_error("Error in reading the event from evdev: %s",
strerror(-err));
/* TODO: Should we just remove the event source? */
break;
}
/* ev now contains the current event. */
if (ev.type == EV_SW) {
switch (ev.code) {
case SW_HEADPHONE_INSERT:
pa_log_debug("Headphone Insert %d", ev.value);
u->sw_headphone_insert = ev.value;
break;
case SW_MICROPHONE_INSERT:
pa_log_debug("Microphone Insert %d", ev.value);
u->sw_microphone_insert = ev.value;
break;
case SW_LINEOUT_INSERT:
pa_log_debug("Lineout Insert %d", ev.value);
u->sw_lineout_insert = ev.value;
break;
default:
pa_log_debug("Unknown switch %d", ev.code);
/* Ignore unknown switch. */
break;
}
} else if (ev.type == EV_SYN && ev.code == SYN_REPORT) {
pa_log_debug("SYN Report");
notify_ports(u);
}
}
pa_log_debug("EV callback end.");
}
static void read_initial_switch_values(pa_droid_extevdev *u) {
/* A local variable is needed because sw_* are bitfields. */
int value;
#define INIT_SW(code, sw_var) \
if (libevdev_fetch_event_value(u->evdev_dev, EV_SW, code, &value)) \
u->sw_var = value; \
else \
u->sw_var = false;
INIT_SW(SW_HEADPHONE_INSERT, sw_headphone_insert)
INIT_SW(SW_MICROPHONE_INSERT, sw_microphone_insert)
INIT_SW(SW_LINEOUT_INSERT, sw_lineout_insert)
#undef INIT_SW
notify_ports(u);
}
pa_droid_extevdev *pa_droid_extevdev_new(pa_core *core, pa_card *card) {
pa_droid_extevdev *u = pa_xnew0(pa_droid_extevdev, 1);
pa_assert(core);
pa_assert(card);
u->card = card;
u->evdev_dev = find_switch_evdev();
if (!u->evdev_dev)
goto fail;
pa_assert_se(u->event = core->mainloop->io_new(core->mainloop,
libevdev_get_fd(u->evdev_dev), PA_IO_EVENT_INPUT, evdev_cb, u));
read_initial_switch_values(u);
return u;
fail:
pa_droid_extevdev_free(u);
return NULL;
}
void pa_droid_extevdev_free(pa_droid_extevdev *u) {
if (u->event)
u->card->core->mainloop->io_free(u->event);
if (u->evdev_dev) {
int fd = libevdev_get_fd(u->evdev_dev);
libevdev_free(u->evdev_dev);
close(fd);
}
pa_xfree(u);
}

View file

@ -0,0 +1,32 @@
#ifndef foodroidextevdevhfoo
#define foodroidextevdevhfoo
/***
This file is part of PulseAudio.
Copyright (C) 2019 UBports foundation.
Author(s): Ratchanan Srirattanamet <ratchanan@ubports.com>
PulseAudio is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 2.1 of the License,
or (at your option) any later version.
PulseAudio is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with PulseAudio; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA.
***/
typedef struct pa_droid_extevdev pa_droid_extevdev;
pa_droid_extevdev *pa_droid_extevdev_new(pa_core *, pa_card *);
void pa_droid_extevdev_free(pa_droid_extevdev *);
#endif

File diff suppressed because it is too large Load diff

View file

@ -2,9 +2,9 @@
#define foodroidsinkfoo
/*
* Copyright (C) 2013 Jolla Ltd.
* Copyright (C) 2013-2018 Jolla Ltd.
*
* Contact: Juho Hämäläinen <juho.hamalainen@tieto.com>
* 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
@ -41,7 +41,7 @@
#include <pulsecore/macro.h>
#include <pulsecore/card.h>
#include "droid-util.h"
#include <droid/droid-util.h>
pa_sink *pa_droid_sink_new(pa_module *m,
pa_modargs *ma,

View file

@ -1,7 +1,7 @@
/*
* Copyright (C) 2013 Jolla Ltd.
* Copyright (C) 2013-2022 Jolla Ltd.
*
* Contact: Juho Hämäläinen <juho.hamalainen@tieto.com>
* 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
@ -50,9 +50,13 @@
#include <pulsecore/thread-mq.h>
#include <pulsecore/rtpoll.h>
#include <pulsecore/time-smoother.h>
#include <pulsecore/resampler.h>
#include <pulse/util.h>
#include <pulse/version.h>
#include "droid-source.h"
#include "droid-util.h"
#include <droid/droid-util.h>
#include <droid/conversion.h>
struct userdata {
pa_core *core;
@ -65,15 +69,17 @@ struct userdata {
pa_rtpoll *rtpoll;
pa_memchunk memchunk;
audio_devices_t primary_devices;
bool routing_changes_enabled;
size_t source_buffer_size;
size_t buffer_size;
pa_usec_t timestamp;
pa_resampler *resampler;
pa_droid_card_data *card_data;
pa_droid_hw_module *hw_module;
audio_stream_in_t *stream;
pa_droid_stream *stream;
bool stream_valid;
};
#define DEFAULT_MODULE_ID "primary"
@ -82,123 +88,66 @@ struct userdata {
#define DROID_AUDIO_SOURCE_UNDEFINED "undefined"
static void userdata_free(struct userdata *u);
static int suspend(struct userdata *u);
static void unsuspend(struct userdata *u);
static void source_reconfigure(struct userdata *u,
const pa_sample_spec *reconfigure_sample_spec,
const pa_channel_map *reconfigure_channel_map,
const pa_proplist *proplist,
dm_config_port *update_device_port);
static int do_routing(struct userdata *u, audio_devices_t devices) {
int ret;
char *setparam;
char *devlist;
pa_proplist *p;
const char *source_str;
audio_devices_t old_device;
audio_source_t source = (uint32_t) -1;
pa_assert(u);
pa_assert(u->stream);
if (!u->routing_changes_enabled) {
pa_log_debug("Skipping routing change.");
return 0;
}
if (u->primary_devices == devices)
pa_log_debug("Refresh active device routing.");
old_device = u->primary_devices;
u->primary_devices = devices;
devlist = pa_list_string_input_device(devices);
pa_assert(devlist);
#ifdef DROID_DEVICE_I9305
devices &= ~AUDIO_DEVICE_BIT_IN;
#endif
if (pa_input_device_default_audio_source(devices, &source))
setparam = pa_sprintf_malloc("%s=%u;%s=%u", AUDIO_PARAMETER_STREAM_ROUTING, devices,
AUDIO_PARAMETER_STREAM_INPUT_SOURCE, source);
else
setparam = pa_sprintf_malloc("%s=%u", AUDIO_PARAMETER_STREAM_ROUTING, devices);
pa_log_debug("set_parameters(%s) %s : %#010x", setparam, devlist, devices);
#if defined(DROID_DEVICE_MAKO) || defined(DROID_DEVICE_IYOKAN)
#warning Using mako set_parameters hack.
ret = u->card_data->set_parameters(u->card_data, setparam);
#else
ret = u->stream->common.set_parameters(&u->stream->common, setparam);
#endif
if (ret < 0) {
if (ret == -ENOSYS)
pa_log_warn("set_parameters(%s) not allowed while stream is active", setparam);
else
pa_log_warn("set_parameters(%s) failed", setparam);
u->primary_devices = old_device;
} else {
if (source != (uint32_t) -1)
pa_assert_se(pa_droid_audio_source_name(source, &source_str));
else
source_str = DROID_AUDIO_SOURCE_UNDEFINED;
p = pa_proplist_new();
pa_proplist_sets(p, DROID_AUDIO_SOURCE, source_str);
pa_source_update_proplist(u->source, PA_UPDATE_REPLACE, p);
pa_proplist_free(p);
}
pa_xfree(devlist);
pa_xfree(setparam);
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;
}
/* 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 thread_read(struct userdata *u) {
void *p;
ssize_t readd;
pa_memchunk chunk;
chunk.index = 0;
chunk.memblock = pa_memblock_new(u->core->mempool, (size_t) u->buffer_size);
if (!u->stream_valid) {
/* try to resume or post silence */
unsuspend(u);
if (!u->stream_valid) {
p = pa_memblock_acquire(chunk.memblock);
chunk.length = pa_memblock_get_length(chunk.memblock);
pa_silence_memory(p, chunk.length, &u->source->sample_spec);
pa_source_post(u->source, &chunk);
pa_memblock_release(chunk.memblock);
goto end;
}
}
p = pa_memblock_acquire(chunk.memblock);
readd = u->stream->read(u->stream, (uint8_t*) p, pa_memblock_get_length(chunk.memblock));
readd = pa_droid_stream_read(u->stream, p, pa_memblock_get_length(chunk.memblock));
pa_memblock_release(chunk.memblock);
if (readd < 0) {
pa_log("Failed to read from stream. (err %i)", readd);
pa_log("Failed to read from stream. (err %zd)", readd);
goto end;
}
u->timestamp += pa_bytes_to_usec(readd, &u->source->sample_spec);
chunk.index = 0;
chunk.length = readd;
if (u->resampler) {
pa_memchunk rchunk;
pa_resampler_run(u->resampler, &chunk, &rchunk);
if (rchunk.length > 0)
pa_source_post(u->source, &rchunk);
if (rchunk.memblock)
pa_memblock_unref(rchunk.memblock);
goto end;
}
if (chunk.length > 0)
pa_source_post(u->source, &chunk);
@ -217,14 +166,16 @@ static void thread_func(void *userdata) {
pa_log_debug("Thread starting up.");
if (u->core->realtime_scheduling)
#if PA_CHECK_VERSION(13,0,0)
pa_thread_make_realtime(u->core->realtime_priority);
#else
pa_make_realtime(u->core->realtime_priority);
#endif
pa_thread_mq_install(&u->thread_mq);
u->timestamp = pa_rtclock_now();
u->stream->common.standby(&u->stream->common);
for (;;) {
int ret;
@ -236,11 +187,7 @@ static void thread_func(void *userdata) {
pa_rtpoll_set_timer_disabled(u->rtpoll);
/* Sleep */
#if (PULSEAUDIO_VERSION == 5)
if ((ret = pa_rtpoll_run(u->rtpoll, true)) < 0)
#elif (PULSEAUDIO_VERSION == 6)
if ((ret = pa_rtpoll_run(u->rtpoll)) < 0)
#endif
goto fail;
if (ret == 0)
@ -263,9 +210,9 @@ static int suspend(struct userdata *u) {
int ret;
pa_assert(u);
pa_assert(u->stream);
assert_stream(u->stream, return 0);
ret = u->stream->common.standby(&u->stream->common);
ret = pa_droid_stream_suspend(u->stream, true);
if (ret == 0)
pa_log_info("Device suspended.");
@ -274,47 +221,61 @@ static int suspend(struct userdata *u) {
}
/* Called from IO context */
static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
struct userdata *u = PA_SOURCE(o)->userdata;
static void unsuspend(struct userdata *u) {
pa_assert(u);
switch (code) {
case PA_SOURCE_MESSAGE_SET_STATE: {
switch ((pa_source_state_t) PA_PTR_TO_UINT(data)) {
case PA_SOURCE_SUSPENDED: {
int r;
if (!u->stream) {
assert_stream(u->stream, u->stream_valid = false);
} else if (pa_droid_stream_suspend(u->stream, false) >= 0) {
u->stream_valid = true;
pa_log_info("Resuming...");
} else
u->stream_valid = false;
}
pa_assert(PA_SOURCE_IS_OPENED(u->source->thread_info.state));
/* Called from IO context */
static int source_set_state_in_io_thread_cb(pa_source *s, pa_source_state_t new_state, pa_suspend_cause_t new_suspend_cause) {
struct userdata *u;
int r;
if ((r = suspend(u)) < 0)
return r;
pa_assert(s);
pa_assert_se(u = s->userdata);
break;
}
/* It may be that only the suspend cause is changing, in which case there's
* nothing more to do. */
if (new_state == s->thread_info.state)
return 0;
case PA_SOURCE_IDLE:
break;
case PA_SOURCE_RUNNING: {
pa_log_info("Resuming...");
u->timestamp = pa_rtclock_now();
break;
}
switch (new_state) {
case PA_SOURCE_SUSPENDED:
if (PA_SOURCE_IS_OPENED(u->source->thread_info.state)) {
if ((r = suspend(u)) < 0)
return r;
}
case PA_SOURCE_UNLINKED: {
/* Suspending since some implementations do not want to free running stream. */
suspend(u);
break;
}
break;
/* not needed */
case PA_SOURCE_INIT:
case PA_SOURCE_INVALID_STATE:
;
case PA_SOURCE_IDLE:
/* Fall through */
case PA_SOURCE_RUNNING:
if (u->source->thread_info.state == PA_SOURCE_SUSPENDED) {
unsuspend(u);
u->timestamp = pa_rtclock_now();
}
break;
}
case PA_SOURCE_UNLINKED:
/* Suspending since some implementations do not want to free running stream. */
suspend(u);
break;
/* not needed */
case PA_SOURCE_INIT:
case PA_SOURCE_INVALID_STATE:
break;
}
return pa_source_process_msg(o, code, data, offset, chunk);
return 0;
}
static int source_set_port_cb(pa_source *s, pa_device_port *p) {
@ -326,7 +287,7 @@ static int source_set_port_cb(pa_source *s, pa_device_port *p) {
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. */
@ -334,27 +295,14 @@ static int source_set_port_cb(pa_source *s, pa_device_port *p) {
return 0;
}
pa_log_debug("Source set port %u", data->device);
pa_log_debug("Source set port %#010x (%s)", data->device_port->type, data->device_port->name);
return do_routing(u, data->device);
}
if (!PA_SOURCE_IS_OPENED(u->source->state))
pa_droid_stream_set_route(u->stream, data->device_port);
else
source_reconfigure(u, NULL, NULL, NULL, data->device_port);
static void source_set_voicecall_source_port(struct userdata *u) {
pa_device_port *port;
pa_droid_port_data *data;
void *state;
pa_assert(u);
pa_assert(u->source);
PA_HASHMAP_FOREACH(port, u->source->ports, state) {
data = PA_DEVICE_PORT_DATA(port);
if (data->device & AUDIO_DEVICE_IN_VOICE_CALL) {
pa_source_set_port(u->source, port->name, false);
break;
}
}
return 0;
}
static void source_set_name(pa_modargs *ma, pa_source_new_data *data, const char *module_id) {
@ -378,78 +326,179 @@ static void source_set_name(pa_modargs *ma, pa_source_new_data *data, const char
}
}
#if (PULSEAUDIO_VERSION == 5)
static void source_get_mute_cb(pa_source *s) {
#elif (PULSEAUDIO_VERSION == 6)
static int source_get_mute_cb(pa_source *s, bool *muted) {
#endif
struct userdata *u = s->userdata;
int ret = 0;
bool b;
pa_assert(u);
pa_assert(u->hw_module && u->hw_module->device);
pa_assert(u->hw_module);
pa_droid_hw_module_lock(u->hw_module);
if (u->hw_module->device->get_mic_mute(u->hw_module->device, &b) < 0) {
pa_log("Failed to get mute state.");
ret = -1;
}
pa_droid_hw_module_unlock(u->hw_module);
#if (PULSEAUDIO_VERSION == 5)
if (ret == 0)
s->muted = b;
#elif (PULSEAUDIO_VERSION == 6)
if (ret == 0)
*muted = b;
return ret;
#endif
return pa_droid_hw_mic_get_mute(u->hw_module, muted);
}
static void source_set_mute_cb(pa_source *s) {
struct userdata *u = s->userdata;
pa_assert(u);
pa_assert(u->hw_module && u->hw_module->device);
pa_droid_hw_module_lock(u->hw_module);
if (u->hw_module->device->set_mic_mute(u->hw_module->device, s->muted) < 0)
pa_log("Failed to set mute state to %smuted.", s->muted ? "" : "un");
pa_droid_hw_module_unlock(u->hw_module);
pa_droid_hw_mic_set_mute(u->hw_module, s->muted);
}
static void source_set_mute_control(struct userdata *u) {
pa_assert(u);
pa_assert(u->hw_module && u->hw_module->device);
if (u->hw_module->device->set_mic_mute) {
pa_log_info("Using hardware mute control for %s", u->source->name);
if (pa_droid_hw_has_mic_control(u->hw_module)) {
pa_source_set_get_mute_callback(u->source, source_get_mute_cb);
pa_source_set_set_mute_callback(u->source, source_set_mute_cb);
} else {
pa_log_info("Using software mute control for %s", u->source->name);
pa_source_set_get_mute_callback(u->source, NULL);
pa_source_set_set_mute_callback(u->source, NULL);
}
}
void pa_droid_source_set_routing(pa_source *s, bool enabled) {
struct userdata *u = s->userdata;
/* Called from main and IO context */
static void update_latency(struct userdata *u) {
pa_assert(u);
pa_assert(u->source);
pa_assert(s);
pa_assert(s->userdata);
if (u->stream)
u->buffer_size = pa_droid_stream_buffer_size(u->stream);
else
u->buffer_size = 1024; /* Random valid value */
if (u->routing_changes_enabled != enabled)
pa_log_debug("%s source routing changes.", enabled ? "Enabling" : "Disabling");
u->routing_changes_enabled = enabled;
assert_stream(u->stream, return);
if (u->source_buffer_size) {
u->buffer_size = pa_droid_buffer_size_round_up(u->source_buffer_size, u->buffer_size);
pa_log_info("Using buffer size %zu (requested %zu).", u->buffer_size, u->source_buffer_size);
} else
pa_log_info("Using buffer size %zu.", u->buffer_size);
if (pa_thread_mq_get())
pa_source_set_fixed_latency_within_thread(u->source, pa_bytes_to_usec(u->buffer_size, pa_droid_stream_sample_spec(u->stream)));
else
pa_source_set_fixed_latency(u->source, pa_bytes_to_usec(u->buffer_size, pa_droid_stream_sample_spec(u->stream)));
pa_log_debug("Set fixed latency %" PRIu64 " usec", pa_bytes_to_usec(u->buffer_size, pa_droid_stream_sample_spec(u->stream)));
}
static void source_reconfigure(struct userdata *u,
const pa_sample_spec *reconfigure_sample_spec,
const pa_channel_map *reconfigure_channel_map,
const pa_proplist *proplist,
dm_config_port *update_device_port) {
pa_channel_map old_channel_map;
pa_sample_spec old_sample_spec;
pa_channel_map new_channel_map;
pa_sample_spec new_sample_spec;
pa_queue *source_outputs = NULL;
if (pa_source_used_by(u->source)) {
/* If we already have connected source outputs detach those
* so that when re-attaching them to our source resampling etc.
* is renegotiated correctly. */
source_outputs = pa_source_move_all_start(u->source, NULL);
}
pa_source_suspend(u->source, true, PA_SUSPEND_UNAVAILABLE);
old_channel_map = *pa_droid_stream_channel_map(u->stream);
old_sample_spec = *pa_droid_stream_sample_spec(u->stream);
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_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.");
else
pa_log_info("Failed to reconfigure input stream, no worries, using defaults.");
/* We need to be really careful here as we are modifying
* quite profound internal structures. */
new_sample_spec = *pa_droid_stream_sample_spec(u->stream);
new_channel_map = *pa_droid_stream_channel_map(u->stream);
u->source->channel_map = new_channel_map;
u->source->sample_spec = new_sample_spec;
pa_assert_se(pa_cvolume_remap(&u->source->reference_volume, &old_channel_map, &new_channel_map));
pa_assert_se(pa_cvolume_remap(&u->source->real_volume, &old_channel_map, &new_channel_map));
pa_assert_se(pa_cvolume_remap(&u->source->soft_volume, &old_channel_map, &new_channel_map));
update_latency(u);
pa_source_suspend(u->source, false, PA_SUSPEND_UNAVAILABLE);
if (source_outputs && u->source) {
pa_source_move_all_finish(u->source, source_outputs, false);
}
}
static pa_hook_result_t source_output_new_hook_callback(void *hook_data,
void *call_data,
void *slot_data) {
pa_source_output_new_data *new_data = call_data;
struct userdata *u = slot_data;
pa_droid_stream *primary_output;
/* Not meant for us */
if (new_data->source != u->source)
return PA_HOOK_OK;
if (!pa_droid_stream_reconfigure_input_needed(u->stream,
&new_data->sample_spec,
&new_data->channel_map,
new_data->proplist))
return PA_HOOK_OK;
pa_log_info("New source-output connecting and our source needs to be reconfigured.");
/* Workaround for fm-radio loopback */
if (pa_safe_streq(pa_proplist_gets(new_data->proplist, "media.name"), "fmradio-loopback-source") &&
(primary_output = pa_droid_hw_primary_output_stream(u->hw_module))) {
pa_log_debug("Workaround for fm-radio loopback.");
source_reconfigure(u,
pa_droid_stream_sample_spec(primary_output),
pa_droid_stream_channel_map(primary_output),
new_data->proplist,
NULL);
} else
source_reconfigure(u, &new_data->sample_spec, &new_data->channel_map, new_data->proplist, NULL);
return PA_HOOK_OK;
}
static void source_reconfigure_after_changes(struct userdata *u) {
pa_source_output *so = NULL;
pa_source_output *so_i;
void *state = NULL;
if (!pa_source_used_by(u->source))
return;
/* Find last inserted source-output */
so = pa_idxset_iterate(u->source->outputs, &state, NULL);
if (so) {
while ((so_i = pa_idxset_iterate(u->source->outputs, &state, NULL)))
so = so_i;
}
if (so && pa_droid_stream_reconfigure_input_needed(u->stream,
&so->sample_spec,
&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, NULL);
}
}
static pa_hook_result_t source_output_unlink_post_hook_callback(void *hook_data,
void *call_data,
void *slot_data) {
source_reconfigure_after_changes(slot_data);
return PA_HOOK_OK;
}
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) {
@ -458,41 +507,58 @@ pa_source *pa_droid_source_new(pa_module *m,
char *thread_name = NULL;
pa_source_new_data data;
const char *module_id = NULL;
const char *tmp;
uint32_t sample_rate;
uint32_t alternate_sample_rate;
audio_devices_t dev_in;
pa_sample_spec sample_spec;
pa_channel_map channel_map;
const char *format;
bool namereg_fail = false;
pa_droid_config_audio *config = NULL; /* Only used when source is created without card */
uint32_t source_buffer = 0;
bool voicecall_source = false;
int ret;
audio_format_t hal_audio_format = 0;
audio_channel_mask_t hal_channel_mask = 0;
pa_assert(m);
pa_assert(ma);
pa_assert(driver);
pa_log_info("Create new droid-source");
/* When running under card use hw module name for source by default. */
if (am)
module_id = am->input->module->name;
module_id = am->mix_port->name;
else
module_id = pa_modargs_get_value(ma, "module_id", DEFAULT_MODULE_ID);
sample_spec = m->core->default_sample_spec;
channel_map = m->core->default_channel_map;
if (device & AUDIO_DEVICE_IN_VOICE_CALL) {
pa_log_info("Enabling voice call record source. Most module arguments are overridden.");
voicecall_source = true;
/* First parse both sample spec and channel map, then see if source_* 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 source sample specification and channel map.");
goto fail;
}
if (pa_modargs_get_sample_spec_and_channel_map(ma, &sample_spec, &channel_map, PA_CHANNEL_MAP_AIFF) < 0) {
pa_log("Failed to parse sample specification and channel map.");
if (pa_modargs_get_value(ma, "source_channel_map", NULL)) {
if (pa_modargs_get_channel_map(ma, "source_channel_map", &channel_map) < 0) {
pa_log("Failed to parse source channel map.");
goto fail;
}
sample_spec.channels = channel_map.channels;
}
if ((format = pa_modargs_get_value(ma, "source_format", NULL))) {
if ((sample_spec.format = pa_parse_sample_format(format)) < 0) {
pa_log("Failed to parse source format.");
goto fail;
}
}
if (pa_modargs_get_value_u32(ma, "source_rate", &sample_spec.rate) < 0) {
pa_log("Failed to parse source_rate.");
goto fail;
}
if (!pa_sample_spec_valid(&sample_spec)) {
pa_log("Sample spec is not valid.");
goto fail;
}
@ -508,135 +574,48 @@ pa_source *pa_droid_source_new(pa_module *m,
}
u = pa_xnew0(struct userdata, 1);
u->stream_valid = true;
u->core = m->core;
u->module = m;
u->card = card;
u->rtpoll = pa_rtpoll_new();
pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll);
/* Enabled routing changes by default, except for voicecall source. */
u->routing_changes_enabled = voicecall_source ? false : true;
if (card_data) {
pa_assert(card);
u->card_data = card_data;
pa_assert_se((u->hw_module = pa_droid_hw_module_get(u->core, NULL, card_data->module_id)));
} else {
/* Stand-alone source */
/* Source wasn't created from inside card module, so we'll need to open
* hw module ourself. */
if (!(u->hw_module = pa_droid_hw_module_get(u->core, NULL, module_id))) {
if (!(config = pa_droid_config_load(ma)))
goto fail;
/* Ownership of config transfers to hw_module if opening of hw module succeeds. */
if (!(u->hw_module = pa_droid_hw_module_get(u->core, config, module_id)))
goto fail;
}
}
if (!pa_convert_format(sample_spec.format, CONV_FROM_PA, &hal_audio_format)) {
pa_log("Sample spec format %u not supported.", sample_spec.format);
goto fail;
}
for (int i = 0; i < channel_map.channels; i++) {
audio_channel_mask_t c;
if (!pa_convert_input_channel(channel_map.map[i], CONV_FROM_PA, &c)) {
pa_log("Failed to convert channel map.");
if (!(u->hw_module = pa_droid_hw_module_get2(u->core, ma, module_id)))
goto fail;
}
hal_channel_mask |= c;
}
if (voicecall_source) {
pa_channel_map_init_mono(&channel_map);
sample_spec.channels = 1;
/* Only allow recording both downlink and uplink. */
#ifdef QCOM_HARDWARE
hal_channel_mask = AUDIO_CHANNEL_IN_VOICE_CALL_MONO;
#else
hal_channel_mask = AUDIO_CHANNEL_IN_VOICE_UPLINK | AUDIO_CHANNEL_IN_VOICE_DNLINK;
#endif
}
u->stream = pa_droid_open_input_stream(u->hw_module, &sample_spec, &channel_map, am->mix_port->name);
struct audio_config config_in = {
.sample_rate = sample_spec.rate,
.channel_mask = hal_channel_mask,
.format = hal_audio_format
};
/* 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_module_lock(u->hw_module);
ret = u->hw_module->device->open_input_stream(u->hw_module->device,
u->hw_module->stream_in_id++,
dev_in,
&config_in,
&u->stream
#if DROID_HAL >= 3
, AUDIO_INPUT_FLAG_NONE /* Default to no input flags */
, NULL /* Don't define address */
, AUDIO_SOURCE_DEFAULT /* Default audio source */
#endif
);
pa_droid_hw_module_unlock(u->hw_module);
if (ret < 0 || !u->stream) {
if (!u->stream) {
pa_log("Failed to open input stream.");
goto fail;
}
if ((sample_rate = u->stream->common.get_sample_rate(&u->stream->common)) != sample_spec.rate) {
pa_log_warn("Requested sample rate %u but got %u instead.", sample_spec.rate, sample_rate);
sample_spec.rate = sample_rate;
}
u->buffer_size = u->stream->common.get_buffer_size(&u->stream->common);
if (source_buffer) {
if (source_buffer < u->buffer_size)
pa_log_warn("Requested buffer size %u less than HAL reported buffer size (%u).", source_buffer, u->buffer_size);
else if (source_buffer % u->buffer_size) {
uint32_t trunc = (source_buffer / u->buffer_size) * u->buffer_size;
pa_log_warn("Requested buffer size %u not multiple of HAL buffer size (%u). Using buffer size %u", source_buffer, u->buffer_size, trunc);
u->buffer_size = trunc;
} else {
pa_log_info("Using requested buffer size %u.", source_buffer);
u->buffer_size = source_buffer;
}
}
pa_log_info("Created Android stream with device: %u sample rate: %u channel mask: %u format: %u buffer size: %u",
dev_in,
sample_rate,
config_in.channel_mask,
config_in.format,
u->buffer_size);
pa_source_new_data_init(&data);
data.driver = driver;
data.module = m;
data.card = card;
/* Start suspended */
data.suspend_cause = PA_SUSPEND_IDLE;
source_set_name(ma, &data, module_id);
if (am)
source_set_name(ma, &data, am->name);
else
source_set_name(ma, &data, module_id);
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_CLASS, "sound");
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_API, PROP_DROID_API_STRING);
pa_proplist_sets(data.proplist, PROP_DROID_INPUT_EXTERNAL, "true");
pa_proplist_sets(data.proplist, PROP_DROID_INPUT_BUILTIN, "true");
/* We need to give pa_modargs_get_value_boolean() a pointer to a local
* variable instead of using &data.namereg_fail directly, because
@ -650,8 +629,8 @@ pa_source *pa_droid_source_new(pa_module *m,
}
data.namereg_fail = namereg_fail;
pa_source_new_data_set_sample_spec(&data, &sample_spec);
pa_source_new_data_set_channel_map(&data, &channel_map);
pa_source_new_data_set_sample_spec(&data, pa_droid_stream_sample_spec(u->stream));
pa_source_new_data_set_channel_map(&data, pa_droid_stream_channel_map(u->stream));
pa_source_new_data_set_alternate_sample_rate(&data, alternate_sample_rate);
if (am && card)
@ -667,7 +646,8 @@ pa_source *pa_droid_source_new(pa_module *m,
u->source->userdata = u;
u->source->parent.process_msg = source_process_msg;
u->source->parent.process_msg = pa_source_process_msg;
u->source->set_state_in_io_thread = source_set_state_in_io_thread_cb;
source_set_mute_control(u);
@ -687,25 +667,33 @@ pa_source *pa_droid_source_new(pa_module *m,
pa_xfree(thread_name);
thread_name = NULL;
pa_source_set_fixed_latency(u->source, pa_bytes_to_usec(u->buffer_size, &sample_spec));
pa_log_debug("Set fixed latency %" PRIu64 " usec", pa_bytes_to_usec(u->buffer_size, &sample_spec));
update_latency(u);
if (!voicecall_source && u->source->active_port)
if (u->source->active_port)
source_set_port_cb(u->source, u->source->active_port);
if (voicecall_source)
source_set_voicecall_source_port(u);
/* Since we started in suspended mode suspend our stream immediately as well. */
pa_droid_stream_suspend(u->stream, true);
pa_droid_stream_set_data(u->stream, u->source);
pa_source_put(u->source);
/* As late as possible */
pa_module_hook_connect(u->module,
&u->module->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_NEW],
PA_HOOK_LATE * 2,
source_output_new_hook_callback, u);
pa_module_hook_connect(u->module,
&u->module->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK_POST],
PA_HOOK_LATE * 2,
source_output_unlink_post_hook_callback, u);
return u->source;
fail:
pa_xfree(thread_name);
if (config)
pa_xfree(config);
if (u)
userdata_free(u);
@ -722,6 +710,7 @@ void pa_droid_source_free(pa_source *s) {
}
static void userdata_free(struct userdata *u) {
pa_assert(u);
if (u->source)
pa_source_unlink(u->source);
@ -739,13 +728,9 @@ static void userdata_free(struct userdata *u) {
if (u->memchunk.memblock)
pa_memblock_unref(u->memchunk.memblock);
if (u->hw_module && u->stream) {
pa_droid_hw_module_lock(u->hw_module);
u->hw_module->device->close_input_stream(u->hw_module->device, u->stream);
pa_droid_hw_module_unlock(u->hw_module);
}
if (u->stream)
pa_droid_stream_unref(u->stream);
// Stand alone source
if (u->hw_module)
pa_droid_hw_module_unref(u->hw_module);

View file

@ -2,9 +2,9 @@
#define foodroidsourcefoo
/*
* Copyright (C) 2013 Jolla Ltd.
* Copyright (C) 2013-2022 Jolla Ltd.
*
* Contact: Juho Hämäläinen <juho.hamalainen@tieto.com>
* 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
@ -41,18 +41,14 @@
#include <pulsecore/macro.h>
#include <pulsecore/card.h>
#include "droid-util.h"
#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);
void pa_droid_source_free(pa_source *s);
void pa_droid_source_set_routing(pa_source *s, bool enabled);
#endif

View file

@ -1,301 +0,0 @@
/*
* Copyright (C) 2013 Jolla Ltd.
*
* Contact: Juho Hämäläinen <juho.hamalainen@tieto.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_
#define DROID_HAL 1
#ifdef DROID_DEVICE_SBJ
#define QCOM_HARDWARE
#endif
#include <hardware/audio.h>
#include <hardware_legacy/audio_policy_conf.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),
{ 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" },
{ 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 }
};
/* 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

View file

@ -1,299 +0,0 @@
/*
* Copyright (C) 2013 Jolla Ltd.
*
* Contact: Juho Hämäläinen <juho.hamalainen@tieto.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_V42_H_
#define _ANDROID_UTIL_V42_H_
#define DROID_HAL 2
#include <hardware/audio.h>
#include <hardware_legacy/audio_policy_conf.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)
#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_REMOTE_SUBMIX),
STRING_ENTRY(AUDIO_DEVICE_OUT_DEFAULT),
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_REMOTE_SUBMIX, "output-remote_submix" },
{ 0, NULL }
};
/* Input devices */
#ifdef DROID_DEVICE_MAKO
struct string_conversion string_conversion_table_input_device[] = {
{ 0x10000, "AUDIO_DEVICE_IN_COMMUNICATION" },
{ 0x20000, "AUDIO_DEVICE_IN_AMBIENT" },
{ 0x40000, "AUDIO_DEVICE_IN_BUILTIN_MIC" },
{ 0x80000, "AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET" },
{ 0x100000, "AUDIO_DEVICE_IN_WIRED_HEADSET" },
{ 0x200000, "AUDIO_DEVICE_IN_AUX_DIGITAL" },
{ 0x400000, "AUDIO_DEVICE_IN_VOICE_CALL" },
{ 0x800000, "AUDIO_DEVICE_IN_BACK_MIC" },
{ 0x80000000, "AUDIO_DEVICE_IN_DEFAULT" },
{ 0x80000000, "AUDIO_DEVICE_IN_REMOTE_SUBMIX" }, // What's this really??
{ 0, NULL }
};
struct string_conversion string_conversion_table_input_device_fancy[] = {
{ 0x10000, "input-communication" },
{ 0x20000, "input-ambient" },
{ 0x40000, "input-builtin_mic" },
{ 0x80000, "input-bluetooth_sco_headset" },
{ 0x100000, "input-wired_headset" },
{ 0x200000, "input-aux_digital" },
{ 0x400000, "input-voice_call" },
{ 0x800000, "input-back_mic" },
{ 0x80000000, "input-remote_submix" },
{ 0, NULL }
};
#else
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_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),
{ 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_REMOTE_SUBMIX, "input-remote_submix" },
{ 0, NULL }
};
#endif
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_REMOTE_SUBMIX, "remote submix" },
#ifdef QCOM_HARDWARE
{ AUDIO_SOURCE_FM_RX, "fm rx" },
{ AUDIO_SOURCE_FM_RX_A2DP, "fm rx a2dp" },
#endif
{ (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),
{ 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_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_MAIN_MASK),
STRING_ENTRY(AUDIO_FORMAT_SUB_MASK),
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

View file

@ -1,353 +0,0 @@
/*
* Copyright (C) 2013 Jolla Ltd.
*
* Contact: Juho Hämäläinen <juho.hamalainen@tieto.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_V44_H_
#define _ANDROID_UTIL_V44_H_
#define DROID_HAL 2
// Android v4.4 has SPEAKER_DRC_ENABLED_TAG, so might the future versions
#define DROID_HAVE_DRC
// Until we implement MER_HA_CHIPSET in hw-release, every non-Qualcomm ARM
// device will need to have an exception below (just like i9305).
// This decision is based on the trend of Q3/Q4 2014 that most devices ported
// to 4.4 via hybris are Qualcomm ones.
// TODO: things elegantly
#if defined(__arm__) && !defined(DROID_DEVICE_I9305)
#define QCOM_HARDWARE
#endif
#include <hardware/audio.h>
#include <hardware_legacy/audio_policy_conf.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] = {
#ifdef DROID_DEVICE_HAMMERHEAD
{ AUDIO_DEVICE_IN_COMMUNICATION, AUDIO_SOURCE_MIC },
{ AUDIO_DEVICE_IN_AMBIENT, AUDIO_SOURCE_MIC },
{ AUDIO_DEVICE_IN_BUILTIN_MIC, AUDIO_SOURCE_MIC },
{ AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, AUDIO_SOURCE_MIC },
{ 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_BACK_MIC, AUDIO_SOURCE_MIC },
{ AUDIO_DEVICE_IN_REMOTE_SUBMIX, AUDIO_SOURCE_REMOTE_SUBMIX },
{ AUDIO_DEVICE_IN_ANC_HEADSET, AUDIO_SOURCE_MIC },
{ AUDIO_DEVICE_IN_FM_RX, AUDIO_SOURCE_FM_RX },
{ AUDIO_DEVICE_IN_FM_RX_A2DP, AUDIO_SOURCE_FM_RX_A2DP }
#else
{ AUDIO_DEVICE_IN_ALL, AUDIO_SOURCE_DEFAULT }
#endif
};
struct string_conversion {
uint32_t value;
const char *str;
};
#if 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_REMOTE_SUBMIX),
STRING_ENTRY(AUDIO_DEVICE_OUT_DEFAULT),
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),
#ifdef QCOM_HARDWARE
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),
#endif
{ 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_REMOTE_SUBMIX, "output-remote_submix" },
#ifdef QCOM_HARDWARE
{ 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" },
#endif
{ 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_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),
#ifdef QCOM_HARDWARE
STRING_ENTRY(AUDIO_DEVICE_IN_ANC_HEADSET),
STRING_ENTRY(AUDIO_DEVICE_IN_FM_RX),
STRING_ENTRY(AUDIO_DEVICE_IN_FM_RX_A2DP),
#endif
{ 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_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" },
#ifdef QCOM_HARDWARE
{ 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" },
#endif
{ 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_REMOTE_SUBMIX, "remote submix" },
#ifdef QCOM_HARDWARE
{ AUDIO_SOURCE_FM_RX, "fm rx" },
{ AUDIO_SOURCE_FM_RX_A2DP, "fm rx a2dp" },
#endif
{ (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),
STRING_ENTRY(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD),
STRING_ENTRY(AUDIO_OUTPUT_FLAG_NON_BLOCKING),
#ifdef QCOM_HARDWARE
STRING_ENTRY(AUDIO_OUTPUT_FLAG_LPA),
STRING_ENTRY(AUDIO_OUTPUT_FLAG_TUNNEL),
STRING_ENTRY(AUDIO_OUTPUT_FLAG_VOIP_RX),
#endif
{ 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_ALL),
STRING_ENTRY(AUDIO_CHANNEL_IN_FRONT_BACK),
#ifdef QCOM_HARDWARE
STRING_ENTRY(AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO),
STRING_ENTRY(AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO),
STRING_ENTRY(AUDIO_CHANNEL_IN_VOICE_CALL_MONO),
#endif
{ 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_MAIN_MASK),
STRING_ENTRY(AUDIO_FORMAT_SUB_MASK),
#ifdef QCOM_HARDWARE
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),
#endif
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

View file

@ -1,342 +0,0 @@
/*
* Copyright (C) 2015 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 _DROID_UTIL_V51_H_
#define _DROID_UTIL_V51_H_
#define DROID_HAL 3
#define DROID_HAVE_DRC
#include <hardware/audio.h>
#include <hardware_legacy/audio_policy_conf.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. */
{ PA_CHANNEL_POSITION_FRONT_LEFT, AUDIO_CHANNEL_IN_LEFT_PROCESSED },
{ PA_CHANNEL_POSITION_FRONT_RIGHT, AUDIO_CHANNEL_IN_RIGHT_PROCESSED },
{ PA_CHANNEL_POSITION_FRONT_CENTER, AUDIO_CHANNEL_IN_FRONT_PROCESSED },
{ PA_CHANNEL_POSITION_REAR_CENTER, AUDIO_CHANNEL_IN_BACK_PROCESSED },
{ PA_CHANNEL_POSITION_SUBWOOFER, AUDIO_CHANNEL_IN_PRESSURE },
{ PA_CHANNEL_POSITION_AUX0, AUDIO_CHANNEL_IN_X_AXIS },
{ PA_CHANNEL_POSITION_AUX1, AUDIO_CHANNEL_IN_Y_AXIS },
{ PA_CHANNEL_POSITION_AUX2, AUDIO_CHANNEL_IN_Z_AXIS },
{ PA_CHANNEL_POSITION_MONO, AUDIO_CHANNEL_IN_VOICE_UPLINK },
{ PA_CHANNEL_POSITION_MONO, 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] = {
#ifdef DROID_DEVICE_HAMMERHEAD
{ AUDIO_DEVICE_IN_COMMUNICATION, AUDIO_SOURCE_MIC },
{ AUDIO_DEVICE_IN_AMBIENT, AUDIO_SOURCE_MIC },
{ AUDIO_DEVICE_IN_BUILTIN_MIC, AUDIO_SOURCE_MIC },
{ AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, AUDIO_SOURCE_MIC },
{ 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_BACK_MIC, AUDIO_SOURCE_MIC },
{ AUDIO_DEVICE_IN_REMOTE_SUBMIX, AUDIO_SOURCE_REMOTE_SUBMIX },
#else
{ AUDIO_DEVICE_IN_ALL, AUDIO_SOURCE_DEFAULT }
#endif
};
struct string_conversion {
uint32_t value;
const char *str;
};
#if 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[] = {
/* Each device listed here needs fancy name counterpart
* in string_conversion_table_output_device_fancy. */
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_HDMI),
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_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),
/* 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_DEFAULT),
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_HDMI, "output-hdmi" },
{ 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_REMOTE_SUBMIX, "output-remote_submix" },
{ AUDIO_DEVICE_OUT_TELEPHONY_TX, "output-telephony" },
{ 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" },
{ 0, NULL }
};
/* Input devices */
struct string_conversion string_conversion_table_input_device[] = {
/* Each device listed here needs fancy name counterpart
* in string_conversion_table_input_device_fancy. */
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_HDMI),
STRING_ENTRY(AUDIO_DEVICE_IN_VOICE_CALL),
STRING_ENTRY(AUDIO_DEVICE_IN_TELEPHONY_RX),
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),
/* 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_DEFAULT),
STRING_ENTRY(AUDIO_DEVICE_IN_ALL),
STRING_ENTRY(AUDIO_DEVICE_IN_ALL_SCO),
STRING_ENTRY(AUDIO_DEVICE_IN_ALL_USB),
{ 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_HDMI, "input-hdmi" },
{ AUDIO_DEVICE_IN_VOICE_CALL, "input-voice_call" },
{ AUDIO_DEVICE_IN_TELEPHONY_RX, "input-telephony" },
{ 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" },
{ 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_REMOTE_SUBMIX, "remote submix" },
{ AUDIO_SOURCE_FM_TUNER, "fm tuner" },
{ (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),
STRING_ENTRY(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD),
STRING_ENTRY(AUDIO_OUTPUT_FLAG_NON_BLOCKING),
STRING_ENTRY(AUDIO_OUTPUT_FLAG_HW_AV_SYNC),
{ 0, NULL }
};
struct string_conversion string_conversion_table_input_flag[] = {
STRING_ENTRY(AUDIO_INPUT_FLAG_NONE),
STRING_ENTRY(AUDIO_INPUT_FLAG_FAST),
STRING_ENTRY(AUDIO_INPUT_FLAG_HW_HOTWORD),
{ 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_5POINT1),
STRING_ENTRY(AUDIO_CHANNEL_OUT_5POINT1_BACK),
STRING_ENTRY(AUDIO_CHANNEL_OUT_5POINT1_SIDE),
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_ALL),
STRING_ENTRY(AUDIO_CHANNEL_IN_FRONT_BACK),
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_MAIN_MASK),
STRING_ENTRY(AUDIO_FORMAT_SUB_MASK),
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

File diff suppressed because it is too large Load diff

View file

@ -1,274 +0,0 @@
#ifndef foodroidutilfoo
#define foodroidutilfoo
/*
* Copyright (C) 2013 Jolla Ltd.
*
* Contact: Juho Hämäläinen <juho.hamalainen@tieto.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 <pulsecore/core-util.h>
#include <pulsecore/macro.h>
#include <pulsecore/mutex.h>
#include <android-version.h>
#if !defined(ANDROID_VERSION_MAJOR) || !defined(ANDROID_VERSION_MINOR) || !defined(ANDROID_VERSION_PATCH)
#error "ANDROID_VERSION_* not defined. Did you get your headers via extract-headers.sh?"
#endif
#if ANDROID_VERSION_MAJOR == 4 && ANDROID_VERSION_MINOR == 1
#include "droid-util-41qc.h"
#elif ANDROID_VERSION_MAJOR == 4 && ANDROID_VERSION_MINOR == 2
#include "droid-util-42.h"
#elif ANDROID_VERSION_MAJOR == 4 && ANDROID_VERSION_MINOR == 4
#include "droid-util-44.h"
#elif ANDROID_VERSION_MAJOR == 5 && ANDROID_VERSION_MINOR == 1
#include "droid-util-51.h"
#else
#error "No valid ANDROID_VERSION found."
#endif
#define PROP_DROID_DEVICES "droid.devices"
#define PROP_DROID_FLAGS "droid.flags"
#define PROP_DROID_HW_MODULE "droid.hw_module"
typedef struct pa_droid_hw_module pa_droid_hw_module;
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_config_audio pa_droid_config_audio;
typedef struct pa_droid_config_hw_module pa_droid_config_hw_module;
struct pa_droid_hw_module {
PA_REFCNT_DECLARE;
pa_core *core;
char *shared_name;
pa_droid_config_audio *config;
const pa_droid_config_hw_module *enabled_module;
pa_mutex *hw_mutex;
struct hw_module_t *hwmod;
audio_hw_device_t *device;
const char *module_id;
uint32_t stream_out_id;
uint32_t stream_in_id;
};
struct pa_droid_card_data {
void *userdata;
/* General functions */
char *module_id;
common_set_parameters_cb_t set_parameters;
};
#define AUDIO_MAX_SAMPLING_RATES (32)
#define AUDIO_MAX_HW_MODULES (8)
#define AUDIO_MAX_INPUTS (8)
#define AUDIO_MAX_OUTPUTS (8)
typedef struct pa_droid_config_global {
audio_devices_t attached_output_devices;
audio_devices_t default_output_device;
audio_devices_t attached_input_devices;
} pa_droid_config_global;
typedef struct pa_droid_config_output {
const pa_droid_config_hw_module *module;
char name[AUDIO_HARDWARE_MODULE_ID_MAX_LEN];
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;
audio_output_flags_t flags;
} pa_droid_config_output;
typedef struct pa_droid_config_input {
const pa_droid_config_hw_module *module;
char name[AUDIO_HARDWARE_MODULE_ID_MAX_LEN];
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;
#if DROID_HAL >= 3
audio_input_flags_t flags;
#endif
} pa_droid_config_input;
struct pa_droid_config_hw_module {
const pa_droid_config_audio *config;
char name[AUDIO_HARDWARE_MODULE_ID_MAX_LEN];
pa_droid_config_output outputs[AUDIO_MAX_OUTPUTS];
uint32_t outputs_size;
pa_droid_config_input inputs[AUDIO_MAX_INPUTS];
uint32_t inputs_size;
};
struct pa_droid_config_audio {
pa_droid_config_global global_config;
pa_droid_config_hw_module hw_modules[AUDIO_MAX_HW_MODULES];
uint32_t hw_modules_size;
};
/* Profiles */
typedef struct pa_droid_profile_set pa_droid_profile_set;
typedef struct pa_droid_mapping pa_droid_mapping;
typedef struct pa_droid_port_data {
audio_devices_t device;
} pa_droid_port_data;
typedef struct pa_droid_port {
pa_droid_mapping *mapping;
audio_devices_t device;
char *name;
char *description;
unsigned priority;
} pa_droid_port;
struct pa_droid_mapping {
pa_droid_profile_set *profile_set;
const pa_droid_config_output *output;
const pa_droid_config_input *input;
char *name;
char *description;
unsigned priority;
pa_proplist *proplist;
/* Mapping doesn't own the ports */
pa_idxset *ports;
pa_direction_t direction;
pa_sink *sink;
pa_source *source;
};
typedef struct pa_droid_profile {
pa_droid_profile_set *profile_set;
const pa_droid_config_hw_module *module;
char *name;
char *description;
unsigned priority;
/* Profile doesn't own the mappings */
pa_droid_mapping *output;
pa_droid_mapping *input;
} pa_droid_profile;
struct pa_droid_profile_set {
const pa_droid_config_audio *config;
pa_hashmap *all_ports;
pa_hashmap *output_mappings;
pa_hashmap *input_mappings;
pa_hashmap *profiles;
};
#define PA_DROID_OUTPUT_PARKING "output-parking"
#define PA_DROID_INPUT_PARKING "input-parking"
/* Open hardware module */
/* 'config' can be NULL if it is assumed that hw module with module_id already is open. */
/* if opening of hw_module succeeds, config ownership is transferred to hw_module and config
* shouldn't be freed. */
pa_droid_hw_module *pa_droid_hw_module_get(pa_core *core, pa_droid_config_audio *config, const char *module_id);
pa_droid_hw_module *pa_droid_hw_module_ref(pa_droid_hw_module *hw);
void pa_droid_hw_module_unref(pa_droid_hw_module *hw);
void pa_droid_hw_module_lock(pa_droid_hw_module *hw);
bool pa_droid_hw_module_try_lock(pa_droid_hw_module *hw);
void pa_droid_hw_module_unlock(pa_droid_hw_module *hw);
/* Conversion helpers */
typedef enum {
CONV_FROM_PA,
CONV_FROM_HAL
} pa_conversion_field_t;
bool pa_convert_output_channel(uint32_t value, pa_conversion_field_t from, uint32_t *to_value);
bool pa_convert_input_channel(uint32_t value, pa_conversion_field_t from, uint32_t *to_value);
bool pa_convert_format(uint32_t value, pa_conversion_field_t from, uint32_t *to_value);
bool pa_string_convert_output_device_num_to_str(audio_devices_t value, const char **to_str);
bool pa_string_convert_output_device_str_to_num(const char *str, audio_devices_t *to_value);
bool pa_string_convert_input_device_num_to_str(audio_devices_t value, const char **to_str);
bool pa_string_convert_input_device_str_to_num(const char *str, audio_devices_t *to_value);
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.
* Return true if default source was found, false if not. */
bool pa_input_device_default_audio_source(audio_devices_t input_device, audio_source_t *default_source);
/* Config parser */
bool pa_parse_droid_audio_config(const char *filename, pa_droid_config_audio *config);
pa_droid_config_audio *pa_droid_config_load(pa_modargs *ma);
const pa_droid_config_output *pa_droid_config_find_output(const pa_droid_config_hw_module *module, const char *name);
const pa_droid_config_input *pa_droid_config_find_input(const pa_droid_config_hw_module *module, const char *name);
const pa_droid_config_hw_module *pa_droid_config_find_module(const pa_droid_config_audio *config, const char* module_id);
/* Profiles */
pa_droid_profile_set *pa_droid_profile_set_new(const pa_droid_config_hw_module *module);
void pa_droid_profile_set_free(pa_droid_profile_set *ps);
pa_droid_profile *pa_droid_profile_new(pa_droid_profile_set *ps, const pa_droid_config_output *output, const pa_droid_config_input *input);
void pa_droid_profile_free(pa_droid_profile *p);
pa_droid_mapping *pa_droid_mapping_get(pa_droid_profile_set *ps, pa_direction_t direction, const void *data);
void pa_droid_mapping_free(pa_droid_mapping *am);
/* Add ports from sinks/sources */
void pa_droid_add_ports(pa_hashmap *ports, pa_droid_mapping *am, pa_card *card);
/* Add ports from card */
void pa_droid_add_card_ports(pa_card_profile *cp, pa_hashmap *ports, pa_droid_mapping *am, pa_core *core);
/* Pretty port names */
bool pa_droid_output_port_name(audio_devices_t value, const char **to_str);
bool pa_droid_input_port_name(audio_devices_t value, const char **to_str);
/* Pretty audio source names */
bool pa_droid_audio_source_name(audio_source_t value, const char **to_str);
#endif

View file

@ -1,223 +0,0 @@
/*
* Copyright (C) 2013 Jolla Ltd.
*
* Contact: Juho Hämäläinen <juho.hamalainen@tieto.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 <signal.h>
#include <stdio.h>
#ifdef HAVE_VALGRIND_MEMCHECK_H
#include <valgrind/memcheck.h>
#endif
#include <pulse/rtclock.h>
#include <pulse/timeval.h>
#include <pulse/xmalloc.h>
#include <pulsecore/core.h>
#include <pulsecore/core-error.h>
#include <pulsecore/dbus-shared.h>
#include <pulsecore/dbus-util.h>
#include <pulsecore/atomic.h>
#include "keepalive.h"
#define MCE_BUS (DBUS_BUS_SYSTEM)
#define MCE_DBUS_NAME "com.nokia.mce"
#define MCE_DBUS_PATH "/com/nokia/mce/request"
#define MCE_DBUS_IFACE "com.nokia.mce.request"
#define MCE_DBUS_KEEPALIVE_PERIOD_REQ "req_cpu_keepalive_period"
#define MCE_DBUS_KEEPALIVE_START_REQ "req_cpu_keepalive_start"
#define MCE_DBUS_KEEPALIVE_STOP_REQ "req_cpu_keepalive_stop"
struct pa_droid_keepalive {
pa_core *core;
pa_dbus_connection *dbus_connection;
pa_atomic_t started;
pa_usec_t timeout;
pa_time_event *timer_event;
};
pa_droid_keepalive* pa_droid_keepalive_new(pa_core *c) {
pa_droid_keepalive *k;
pa_dbus_connection *dbus;
DBusError error;
pa_assert(c);
dbus_error_init(&error);
dbus = pa_dbus_bus_get(c, MCE_BUS, &error);
if (dbus_error_is_set(&error)) {
pa_log("Failed to get %s bus: %s", MCE_BUS == DBUS_BUS_SESSION ? "session" : "system", error.message);
dbus_error_free(&error);
return NULL;
}
k = pa_xnew0(pa_droid_keepalive, 1);
k->core = c;
k->dbus_connection = dbus;
k->timeout = 0;
pa_atomic_store(&k->started, 0);
return k;
}
static void send_dbus_signal(pa_dbus_connection *dbus) {
DBusMessage *msg;
pa_assert(dbus);
/* pa_log_debug("Send keepalive heartbeat."); */
pa_assert_se((msg = dbus_message_new_method_call(MCE_DBUS_NAME,
MCE_DBUS_PATH,
MCE_DBUS_IFACE,
MCE_DBUS_KEEPALIVE_START_REQ)));
dbus_connection_send(pa_dbus_connection_get(dbus), msg, NULL);
dbus_message_unref(msg);
}
static void keepalive_cb(pa_mainloop_api *m, pa_time_event *e, const struct timeval *t, void *userdata) {
pa_droid_keepalive *k = userdata;
pa_assert(k);
pa_assert(k->timer_event == e);
send_dbus_signal(k->dbus_connection);
pa_core_rttime_restart(k->core, k->timer_event, pa_rtclock_now() + k->timeout);
}
static void keepalive_start(pa_droid_keepalive *k) {
pa_assert(k);
pa_assert(k->timeout);
pa_assert(!k->timer_event);
pa_log_info("Start keepalive heartbeat with interval %lu seconds.", (unsigned long) (k->timeout / PA_USEC_PER_SEC));
/* Send first keepalive heartbeat immediately. */
send_dbus_signal(k->dbus_connection);
k->timer_event = pa_core_rttime_new(k->core, pa_rtclock_now() + k->timeout, keepalive_cb, k);
}
static void pending_req_reply_cb(DBusPendingCall *pending, void *userdata) {
pa_droid_keepalive *k = userdata;
DBusMessage *msg;
uint32_t period;
pa_assert(pending);
pa_assert(k);
pa_assert_se(msg = dbus_pending_call_steal_reply(pending));
if (dbus_message_get_type(msg) == DBUS_MESSAGE_TYPE_ERROR) {
pa_log("Failed to get %s", MCE_DBUS_KEEPALIVE_PERIOD_REQ);
goto finish;
}
pa_assert_se(dbus_message_get_args(msg, NULL,
DBUS_TYPE_INT32, &period,
DBUS_TYPE_INVALID));
k->timeout = PA_USEC_PER_SEC * (period - 5);
keepalive_start(k);
finish:
dbus_message_unref(msg);
dbus_pending_call_unref(pending);
}
void pa_droid_keepalive_start(pa_droid_keepalive *k) {
DBusPendingCall *pending = NULL;
DBusMessage *msg = NULL;
pa_assert(k);
/* Only allow first call go through. pa_atomic_inc() returns previous value before incrementing. */
if (pa_atomic_inc(&k->started) > 0)
return;
pa_assert(!k->timer_event);
/* Period time already requested, just start hearbeat. */
if (k->timeout > 0) {
keepalive_start(k);
return;
}
pa_log_debug("Starting keepalive - Request keepalive period.");
/* Send first keepalive heartbeat immediately. */
send_dbus_signal(k->dbus_connection);
pa_assert_se((msg = dbus_message_new_method_call(MCE_DBUS_NAME,
MCE_DBUS_PATH,
MCE_DBUS_IFACE,
MCE_DBUS_KEEPALIVE_PERIOD_REQ)));
dbus_connection_send_with_reply(pa_dbus_connection_get(k->dbus_connection), msg, &pending, -1);
dbus_message_unref(msg);
dbus_pending_call_set_notify(pending, pending_req_reply_cb, k, NULL);
}
void pa_droid_keepalive_stop(pa_droid_keepalive *k) {
DBusMessage *msg;
pa_assert(k);
/* Only allow last call go through. pa_atomic_dec() returns previous value before decrementing. */
if (pa_atomic_dec(&k->started) != 1)
return;
pa_assert(pa_atomic_load(&k->started) == 0);
if (!k->timer_event)
return;
pa_log_debug("Stopping keepalive.");
k->core->mainloop->time_free(k->timer_event);
k->timer_event = NULL;
pa_assert_se((msg = dbus_message_new_method_call(MCE_DBUS_NAME,
MCE_DBUS_PATH,
MCE_DBUS_IFACE,
MCE_DBUS_KEEPALIVE_STOP_REQ)));
dbus_connection_send(pa_dbus_connection_get(k->dbus_connection), msg, NULL);
dbus_message_unref(msg);
}
void pa_droid_keepalive_free(pa_droid_keepalive *k) {
pa_assert(k);
pa_assert(k->dbus_connection);
pa_assert(pa_atomic_load(&k->started) == 0);
pa_dbus_connection_unref(k->dbus_connection);
pa_xfree(k);
}

View file

@ -1,42 +0,0 @@
/*
* Copyright (C) 2013 Jolla Ltd.
*
* Contact: Juho Hämäläinen <juho.hamalainen@tieto.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 foomoduledroidcardsymdeffoo
#define foomoduledroidcardsymdeffoo
#include <pulsecore/core.h>
#include <pulsecore/module.h>
#define pa__init module_droid_card_LTX_pa__init
#define pa__done module_droid_card_LTX_pa__done
#define pa__get_author module_droid_card_LTX_pa__get_author
#define pa__get_description module_droid_card_LTX_pa__get_description
#define pa__get_usage module_droid_card_LTX_pa__get_usage
#define pa__get_version module_droid_card_LTX_pa__get_version
int pa__init(struct pa_module*m);
void pa__done(struct pa_module*m);
const char* pa__get_author(void);
const char* pa__get_description(void);
const char* pa__get_usage(void);
const char* pa__get_version(void);
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,42 +0,0 @@
/*
* Copyright (C) 2013 Jolla Ltd.
*
* Contact: Juho Hämäläinen <juho.hamalainen@tieto.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 foomoduledroidkeepalivesymdeffoo
#define foomoduledroidkeepalivesymdeffoo
#include <pulsecore/core.h>
#include <pulsecore/module.h>
#define pa__init module_droid_keepalive_LTX_pa__init
#define pa__done module_droid_keepalive_LTX_pa__done
#define pa__get_author module_droid_keepalive_LTX_pa__get_author
#define pa__get_description module_droid_keepalive_LTX_pa__get_description
#define pa__get_usage module_droid_keepalive_LTX_pa__get_usage
#define pa__get_version module_droid_keepalive_LTX_pa__get_version
int pa__init(struct pa_module*m);
void pa__done(struct pa_module*m);
const char* pa__get_author(void);
const char* pa__get_description(void);
const char* pa__get_usage(void);
const char* pa__get_version(void);
#endif

View file

@ -1,182 +0,0 @@
/*
* Copyright (C) 2013 Jolla Ltd.
*
* Contact: Juho Hämäläinen <juho.hamalainen@tieto.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 <signal.h>
#include <stdio.h>
#ifdef HAVE_VALGRIND_MEMCHECK_H
#include <valgrind/memcheck.h>
#endif
#include <pulse/xmalloc.h>
#include <pulsecore/core.h>
#include <pulsecore/i18n.h>
#include <pulsecore/module.h>
#include <pulsecore/sink.h>
#include <pulsecore/source.h>
#include <pulsecore/modargs.h>
#include <pulsecore/core-util.h>
#include <pulsecore/log.h>
#include <pulsecore/macro.h>
#include <pulsecore/idxset.h>
#include "keepalive.h"
#include "module-droid-keepalive-symdef.h"
PA_MODULE_AUTHOR("Juho Hämäläinen");
PA_MODULE_DESCRIPTION("Droid keepalive. Send cpu wakeup heartbeat while streams are active.");
PA_MODULE_VERSION(PACKAGE_VERSION);
PA_MODULE_USAGE(
"-"
);
static const char* const valid_modargs[] = {
NULL,
};
struct userdata {
pa_core *core;
pa_module *module;
pa_droid_keepalive *keepalive;
bool active;
pa_hook_slot *sink_state_changed_slot;
pa_hook_slot *source_state_changed_slot;
};
static void start(struct userdata *u) {
if (u->active)
return;
u->active = true;
pa_droid_keepalive_start(u->keepalive);
}
static void stop(struct userdata *u) {
void *state = NULL;
pa_sink *sink;
pa_source *source;
if (!u->active)
return;
while ((sink = pa_idxset_iterate(u->core->sinks, &state, NULL))) {
if (pa_sink_get_state(sink) != PA_SINK_SUSPENDED)
return;
}
state = NULL;
while ((source = pa_idxset_iterate(u->core->sources, &state, NULL))) {
if (source->monitor_of)
continue;
if (pa_source_get_state(source) != PA_SOURCE_SUSPENDED)
return;
}
/* We get here if all sinks and sources are in suspended state. */
pa_droid_keepalive_stop(u->keepalive);
u->active = false;
}
static pa_hook_result_t device_state_changed_hook_cb(pa_core *c, pa_object *o, struct userdata *u) {
pa_assert(c);
pa_object_assert_ref(o);
pa_assert(u);
if (pa_source_isinstance(o)) {
pa_source *s = PA_SOURCE(o);
/* Don't react on monitor state changes. */
if (!s->monitor_of) {
pa_source_state_t state = pa_source_get_state(s);
if (state != PA_SOURCE_SUSPENDED)
start(u);
else
stop(u);
}
} else if (pa_sink_isinstance(o)) {
pa_sink *s = PA_SINK(o);
pa_sink_state_t state = pa_sink_get_state(s);
if (state != PA_SINK_SUSPENDED)
start(u);
else
stop(u);
}
return PA_HOOK_OK;
}
int pa__init(pa_module *m) {
pa_assert(m);
struct userdata *u = pa_xnew0(struct userdata, 1);
u->core = m->core;
u->active = false;
u->module = m;
m->userdata = u;
if (!(u->keepalive = pa_droid_keepalive_new(u->core))) {
pa_log("Failed to create keepalive handler.");
goto fail;
}
u->sink_state_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_STATE_CHANGED], PA_HOOK_NORMAL, (pa_hook_cb_t) device_state_changed_hook_cb, u);
u->source_state_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_STATE_CHANGED], PA_HOOK_NORMAL, (pa_hook_cb_t) device_state_changed_hook_cb, u);
return 0;
fail:
pa__done(m);
return -1;
}
void pa__done(pa_module *m) {
struct userdata *u;
pa_assert(m);
if ((u = m->userdata)) {
if (u->sink_state_changed_slot)
pa_hook_slot_free(u->sink_state_changed_slot);
if (u->source_state_changed_slot)
pa_hook_slot_free(u->source_state_changed_slot);
if (u->keepalive) {
stop(u);
pa_droid_keepalive_free(u->keepalive);
}
pa_xfree(u);
}
}

View file

@ -1,42 +0,0 @@
/*
* Copyright (C) 2013 Jolla Ltd.
*
* Contact: Juho Hämäläinen <juho.hamalainen@tieto.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 foomoduledroidsinksymdeffoo
#define foomoduledroidsinksymdeffoo
#include <pulsecore/core.h>
#include <pulsecore/module.h>
#define pa__init module_droid_sink_LTX_pa__init
#define pa__done module_droid_sink_LTX_pa__done
#define pa__get_author module_droid_sink_LTX_pa__get_author
#define pa__get_description module_droid_sink_LTX_pa__get_description
#define pa__get_usage module_droid_sink_LTX_pa__get_usage
#define pa__get_version module_droid_sink_LTX_pa__get_version
int pa__init(struct pa_module*m);
void pa__done(struct pa_module*m);
const char* pa__get_author(void);
const char* pa__get_description(void);
const char* pa__get_usage(void);
const char* pa__get_version(void);
#endif

View file

@ -1,7 +1,7 @@
/*
* Copyright (C) 2013 Jolla Ltd.
* Copyright (C) 2013-2018 Jolla Ltd.
*
* Contact: Juho Hämäläinen <juho.hamalainen@tieto.com>
* 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
@ -37,11 +37,10 @@
#include <pulsecore/log.h>
#include <pulsecore/macro.h>
#include "droid-util.h"
#include <droid/droid-util.h>
#include <droid/conversion.h>
#include "droid-sink.h"
#include "module-droid-sink-symdef.h"
PA_MODULE_AUTHOR("Juho Hämäläinen");
PA_MODULE_DESCRIPTION("Droid sink");
PA_MODULE_USAGE("master_sink=<sink to connect to> "
@ -49,17 +48,28 @@ PA_MODULE_USAGE("master_sink=<sink to connect to> "
PA_MODULE_VERSION(PACKAGE_VERSION);
static const char* const valid_modargs[] = {
"config",
"rate",
"format",
"channels",
"channel_map",
"sink_rate",
"sink_format",
"sink_channel_map",
"sink_mix_route",
"flags",
"output",
"output_devices",
"sink_name",
"module_id",
"mute_routing_before",
"mute_routing_after",
"prewrite_on_resume",
"sink_buffer",
"deferred_volume",
"voice_property_key",
"voice_property_value",
"voice_virtual_stream",
NULL,
};
@ -74,15 +84,24 @@ void pa__done(pa_module *m) {
int pa__init(pa_module *m) {
pa_modargs *ma = NULL;
const char *flags_str;
audio_output_flags_t flags = 0;
pa_assert(m);
if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
pa_log("Failed to parse module argumets.");
pa_log("Failed to parse module arguments.");
goto fail;
}
if (!(m->userdata = pa_droid_sink_new(m, ma, __FILE__, NULL, 0, NULL, NULL)))
if ((flags_str = pa_modargs_get_value(ma, "flags", NULL))) {
if (!pa_string_convert_flag_str_to_num(flags_str, &flags)) {
pa_log("Failed to parse flags");
goto fail;
}
}
if (!(m->userdata = pa_droid_sink_new(m, ma, __FILE__, NULL, flags, NULL, NULL)))
goto fail;
pa_modargs_free(ma);

View file

@ -1,42 +0,0 @@
/*
* Copyright (C) 2013 Jolla Ltd.
*
* Contact: Juho Hämäläinen <juho.hamalainen@tieto.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 foomoduledroidsourcesymdeffoo
#define foomoduledroidsourcesymdeffoo
#include <pulsecore/core.h>
#include <pulsecore/module.h>
#define pa__init module_droid_source_LTX_pa__init
#define pa__done module_droid_source_LTX_pa__done
#define pa__get_author module_droid_source_LTX_pa__get_author
#define pa__get_description module_droid_source_LTX_pa__get_description
#define pa__get_usage module_droid_source_LTX_pa__get_usage
#define pa__get_version module_droid_source_LTX_pa__get_version
int pa__init(struct pa_module*m);
void pa__done(struct pa_module*m);
const char* pa__get_author(void);
const char* pa__get_description(void);
const char* pa__get_usage(void);
const char* pa__get_version(void);
#endif

View file

@ -1,7 +1,7 @@
/*
* Copyright (C) 2013 Jolla Ltd.
* Copyright (C) 2013-2022 Jolla Ltd.
*
* Contact: Juho Hämäläinen <juho.hamalainen@tieto.com>
* 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
@ -37,11 +37,9 @@
#include <pulsecore/log.h>
#include <pulsecore/macro.h>
#include "droid-util.h"
#include <droid/droid-util.h>
#include "droid-source.h"
#include "module-droid-source-symdef.h"
PA_MODULE_AUTHOR("Juho Hämäläinen");
PA_MODULE_DESCRIPTION("Droid source");
PA_MODULE_USAGE("master_source=<source to connect to> "
@ -49,7 +47,14 @@ PA_MODULE_USAGE("master_source=<source to connect to> "
PA_MODULE_VERSION(PACKAGE_VERSION);
static const char* const valid_modargs[] = {
"config",
"rate",
"format",
"channels",
"channel_map",
"source_rate",
"source_format",
"source_channel_map",
"flags",
"input_devices",
"source_name",
@ -74,11 +79,11 @@ int pa__init(pa_module *m) {
pa_assert(m);
if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
pa_log("Failed to parse module argumets.");
pa_log("Failed to parse module arguments.");
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);