Giter Club home page Giter Club logo

pulseaudio-modules-droid's Introduction

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.1

Headers for defining devices and strings for different droid versions are in
src/common/droid-util-XXX.h

These headers are then included in src/common/droid-util.h based on detected
droid version. Version is defined in android-version.h, included from
android-config.h, which is part of droid hal devel package.

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.

pulseaudio-modules-droid's People

Contributors

ballock avatar jusa avatar lbt avatar litew avatar martinbrook avatar mlehtima avatar saukko avatar siteshwar avatar sledges avatar

Watchers

 avatar  avatar

Forkers

zhxt

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.