forked from mer-hybris/pulseaudio-modules-droid
-
Notifications
You must be signed in to change notification settings - Fork 0
multimedia-pulseaudio-modules-droid
License
salmelamike/pulseaudio-modules-droid
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
PulseAudio Droid modules ======================== 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 Supported Android versions: * 4.1.x with Qualcomm extensions (tested with 4.1.2) * 4.2.x * 4.4.x * 5.x * 6.0.x * 7.x * 8.x Headers for defining devices and strings for different droid versions are in src/common/droid-util-audio.h (legacy headers for Jolla 1 in droid-util-41qc.h). 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 To populate our configuration structs there exists two parsers, legacy parser for old .conf format present in Android versions 7.0 and older and new xml format present from version 7.0 upwards. The legacy format is obsoleted in version 7.0 but by default still in use and most 7.0 adaptations probably contain the legacy format. But 8.0 adaptations and up start to include only the new style xml format configuration files. ### Configuration files By default new style xml format is tried first and if it is not found old config is read next. If the configuration is in non-default location for some reason "config" module argument (available for all modules, card, sink, and source) can be used to point to the configuration file location. By default files are tried in following order, /vendor/etc/audio_policy_configuration.xml (new xml format) /vendor/etc/audio_policy.conf (legacy format) /system/etc/audio_policy_configuration.xml (new xml format) /system/etc/audio_policy.conf (legacy format) 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 try to create a default profile (called surprisingly "default"). The default profile will try to merge useful output and input streams to one profile, to allow use of possible low latency outputs or multiple inputs if the input streams are split to multiple devices. For example configuration with audio_hw_modules { primary { outputs { primary {} deep_buffer {} } inputs { builtin {} external {} } } other { ... } } The default profile would contain two sinks, sink.primary and sink.deep_buffer and one source, source.builtin_external. Then this combined source would use either "builtin" or "external" input stream, depending on which one has the input route currently in use (for example, input-wired_headset from "external" and input-back_mic from "builtin" input stream). Usually this default profile is everything that is needed in normal use, and additional profiles created should be needed only for testing things out etc. additional profiles ------------------- In addition to the default profile all input and output definitions are translated to PulseAudio card profiles. For example configuration with audio_hw_modules { primary { outputs { primary {} lpa {} } inputs { primary {} } } other { ... } } Would map to card profiles (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) 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 * 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. Similarly if there is only one input device the sole source would have both input type properties set as "true", but it also might be that the different input type properties are split to two different sources. Quirks ------ There are some adaptations that require hacks to get things working. These hacks can be enabled or disabled with module argument "quirks". Some quirks are enabled by default with some adaptations etc. Currently there are following quirks: * input_atoi * Enabled by default with Android versions 5 and up. * Due to how atoi works in bionic vs libc we need to pass the input route a bit funny. If input routing doesn't work switch this on or off. * set_parameters * Disabled by default. * Some adaptations need to use hw module's generic set_parameters call to change input routing. If input routing doesn't work switch this on or off. (mostly just older adaptations) * close_input * Enabled by default. * Close input stream when not in use instead of suspending the stream. 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. * no_hw_volume * Disabled by default. * Some broken implementations are incorrectly probed for supporting hw volume control. This is manifested by always full volume with volume control not affecting volume level. To fix this enable this quirk. * output_make_writable * Disabled by default. * Some implementations modify write buffer in-place when this should not be done. This can result in random segfaults when playing audio. As a workaround make the buffer memchunk writable before passing to audio HAL. * realcall * Disabled by default. * Some vendors apply custom realcall parameter to HAL device when doing voicecall routing. If there is no voicecall audio you can try enabling this quirk so that the realcall parameter is applied 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. For example, to disable input_atoi and enable close_input quirks, use module argument quirks=-input_atoi,+close_input 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. 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.
About
multimedia-pulseaudio-modules-droid
Resources
License
Stars
Watchers
Forks
Packages 0
No packages published
Languages
- C 91.8%
- M4 6.5%
- Other 1.7%