https://wiki.postmarketos.org/api.php?action=feedcontributions&user=Asriel&feedformat=atompostmarketOS - User contributions [en]2024-03-28T12:46:36ZUser contributionsMediaWiki 1.39.6https://wiki.postmarketos.org/index.php?title=User:Asriel&diff=7324User:Asriel2019-06-30T07:02:32Z<p>Asriel: Created page with "Matrix: @asriel:kde.org {{Owns device|Xiaomi_RedMi4x_(xiaomi-santoni)}}"</p>
<hr />
<div>Matrix: @asriel:kde.org<br />
<br />
{{Owns device|Xiaomi_RedMi4x_(xiaomi-santoni)}}</div>Asrielhttps://wiki.postmarketos.org/index.php?title=Audio&diff=7314Audio2019-06-29T12:22:57Z<p>Asriel: Formatting error</p>
<hr />
<div>{{note|If you're trying out anything and learn something that would have helped, please extend this wiki page.}}<br />
<br />
== Audio on Android ==<br />
<br />
=== Mixer configuration ===<br />
<br />
This provides a brief overview of how Android audio HALs configure the ALSA mixer.<br />
<br />
Android devices can have an assortment mixer configurations such as headphones, speakers, or microphones. For a particular device the audio route configurations are defined in <code>mixer_paths.xml</code>. [https://android.googlesource.com/device/lge/hammerhead/+/kitkat-release/mixer_paths.xml For an example see the mixer path XML for Nexus 5 (hammerhead).]<br />
<br />
Android audio HALs make use of [https://android.googlesource.com/platform/external/tinyalsa/ tinyalsa] and [https://android.googlesource.com/platform/system/media/+/kitkat-release/audio_route/ audio_route]. Tinyalsa is a small standalone library to interface with ALSA in the Linux kernel. Audio HALs call the <code>audio_route</code> library which loads audio routes from an XML and controls the mixer through <code>tinyalsa</code>.<br />
<br />
==== Format of mixer_paths.xml ====<br />
* ALSA controls are defined by <code>ctl</code> elements.<br />
* Audio routes are defined by <code>path</code> elements. A <code>path</code> element contains a collection of <code>ctl</code> elements as well as other <code>path</code> elements.<br />
* The path <code>name</code> attribute is used to select an audio route.<br />
<br />
=== Headphone jack ===<br />
<br />
Android kernels use <code>switch_class</code> kernel driver to notify the Android frameworks of headphone jack events. The driver source code can be located at:<br />
<code>drivers/switch/switch_class.c</code><br />
or<br />
<code>drivers/staging/android/switch/switch_class.c</code>. Note that the switch class driver is an Android specific driver. It has not been upstreamed to the mainline kernel.<br />
<br />
In userspace the [https://android.googlesource.com/platform/frameworks/base/+/kitkat-release/services/java/com/android/server/WiredAccessoryManager.java WiredAccessoryManager] monitors the <code>/sys/class/switch/h2w</code> for uevents when the headphone is (un)plugged.<br />
<br />
Udev rules can be used to detect if headphones are plugged in, example for this is from [https://gitlab.com/postmarketOS/pmaports/blob/195114e48e0997d060036feef4965cd0e3c07ccc/device/device-xiaomi-santoni/90-device-xiaomi-santoni-audio.rules xiaomi-santoni]<br />
<br />
== Getting Audio to work on non-Android userspace ==<br />
<br />
=== Bring up Android DSP subsystem ===<br />
{{note|This is most likely for downstream kernels, if you're using a mainline kernel, this is pointless.}}<br />
{{note|This was only tested on Qualcomm MSM8937, this might also work on other chipset too, but this is untested.}}<br />
ADSP needs to be powered on before audio could work on downstream kernels. To do that, you'll have to supply firmware files that is available on your internal MMC.<br />
<br />
On a shell prompt inside postmarketOS, type <code>fdisk -l /dev/mmcblk0</code> (replace mmcblk0 with the correct device name for internal MMC). At this point you should get a familiar partition layout of a Android device.<br />
<br />
Now, the only thing that is important is the partition with <code>modem</code> label on it, which on my device it's mmcblk0p1. Mount the partition as read-only to /mnt using:<br />
<br />
<pre><br />
# mount -o ro /dev/mmcblk0p1 /mnt<br />
</pre><br />
<br />
Inside /mnt, there is a folder named <code>image</code> which has a bunch of firmware files for different parts of the device, like wcnss (for wlan), DRM contents and so on, the only thing that needs to be extracted is all the files that named <code>adsp.*</code>:<br />
<br />
<pre><br />
// Create /lib/firmware/postmarketos if it doesn't exist<br />
# mkdir -p /lib/firmware/postmarketos<br />
<br />
// Copy all adsp.* to the postmarketOS firmware directory<br />
# cp -v /mnt/image/adsp.* /lib/firmware/postmarketos<br />
</pre><br />
<br />
After that, you should be able to bring up the ADSP subsystem by running:<br />
<pre><br />
# echo 1 > /dev/subsys_adsp<br />
</pre><br />
<br />
You should check dmesg and /var/log/firmwareload.log to make sure there aren't firmwares failing to load.<br />
<br />
If it goes fine, you should see a bunch of playback devices by typing <code>aplay -l</code><br />
<br />
You also want to install <code>adsp-audio</code> from pmOS repo to load the subsystem on automatically on bootup.<br />
<br />
=== Convert XML audio to UCM ===<br />
{{note|This section is incomplete. It requires a reference to more complete documentation of the device config XML format.}}<br />
<br />
The audio routes in Linux userspace can be defined in ALSA UCM configuration files. There is a tool called [https://github.com/ford-prefect/xml2ucm xml2ucm] which will convert the Android <code>mixer_paths.xml</code> and a device config XML to UCM files. The <code>xml2ucm</code> tool introduces the device config XML which provides necessary routing information that was hardcoded in the audio HAL on Android.<br />
<br />
The <code>mixer_path.xml</code> is commonly found in the Android device repository. (e.g. <code>android_device_lge_hammerhead</code>). You must write the device config XML for your device.<br />
<br />
==== Format of device config XML ====<br />
<br />
A device config XML describes a sound card with use cases and sets of audio routes. In the examples available at the moment there is only one use case named HiFi. Under each <code><use-case></code> there are multiple <code><device></code> elements. In this context a <code><device></code> means audio route(s) which comprise a logical audio device (e.g. Headphone, Headset, Speaker).<br />
<br />
Android audio HALs can and do select multiple audio routes at once. For example a headset can have a headphone output route and a microphone input route. To handle this a <code><device></code> element (the headset) can contain multiple <code><path></code> elements (audio routes). Example device config XML files are provided in the <code>xml2ucm</code> repository.<br />
<br />
The <code>ctl-device</code> must be the name of the sound card which can be obtained using <code>aplay</code>. In the following example from the Samsung p4wifi the <code>ctl-device</code> is the sound card named <code>wm8994aif1</code>.<br />
<source lang="shell">$ aplay -L<br />
null<br />
Discard all samples (playback) or generate zero samples (capture)<br />
default:CARD=wm8994aif1<br />
wm8994-aif1, <br />
Default Audio Device<br />
sysdefault:CARD=wm8994aif1<br />
wm8994-aif1, <br />
Default Audio Device<br />
</source><br />
<br />
Once the <code>mixer_path.xml</code> and device config XML are converted to UCM format then an audio route can be set by using <code>alsaucm</code>.<br />
Example:<br />
<source lang="shell>$ alsaucm -c wm8994aif1 set _verb HiFi set _enadev Headphones</source><br />
<br />
=== libhybris ===<br />
{{note|Might not work on some devices, which in this case providing logs to the maintainer is required, and debugging is also needed too.}}<br />
Alexey Min (minlexx) is currently packaging [https://gitlab.com/postmarketOS/pmaports/merge_requests/448 pulseaudio-modules-droid] to the repository.<br />
<br />
Build and install pulseaudio-modules-droid package first, then add this to <code>/etc/pulse/default.pa</code> before the line that loads module-alsa-sink:<br />
<pre><br />
load-module module-droid-card<br />
load-module module-droid-sink<br />
load-module module-droid-source<br />
</pre><br />
<br />
Start pulseaudio in verbose mode to make sure you can get to see if the module loads successfully. If it does then you should be able to play sound files using <code>paplay</code> from pulseaudio-utils package.<br />
<br />
If you hear sounds coming from it, it works perfectly fine, if not, check dmesg, pulseaudio log and logcat.<br />
<br />
You might also want to install alsa-plugins-pulse for ALSA backend on PulseAudio.<br />
<br />
== alsactl method ==<br />
Cascardo reported having success with the following method on Debian, this should work for postmarketOS as well:<br />
<blockquote><br />
I ran a debian chroot on a cyanogenmod, set the volume up, then ran alsactl save on the chroot. booted into debian, then after alsactl restore was run, I had audio working<br />
<br />
so, in summary, it's hard to know which mixer settings will make it work, so my strategy was running some android stack that correctly set the mixer, then saving the state with a chroot or any other tool that would allow you to save, copy and restore that state later on a gnu stack<br />
</blockquote><br />
<br />
This method may work for non-Android devices as well, as long as you see an audio device in <code>alsamixer</code>. Just boot the normal OS, save the volume settings somehow, then restore them.<br />
<br />
== WM1811 ==<br />
<br />
This audio chip is present in several Samsung devices that are based on the Exynos 4412 platform. There is a configuration for the Samsung Galaxy Note 10.1 available at [https://code.google.com/archive/p/opensgn/source/default/source the opensgn project]. Have a look at the files in <code>opensgn/data/n8000/usr/share/alsa/ucm/Midas_WM1811/</code>.<br />
In <code>opensgn/data/n8000/etc/rc.local</code> there are the commands to use the configuration:<br />
<br />
<pre><br />
# restore alsa sinitial tate<br />
/usr/sbin/alsactl restore -f /usr/share/alsa/ucm/Midas_WM1811/init.state<br />
<br />
# enable speaker for output and builtin mic for input<br />
/usr/bin/alsaucm -c Midas_WM1811 set _verb HiFi set _enadev Speaker<br />
/usr/bin/alsaucm -c Midas_WM1811 set _verb HiFi set _enadev Mic<br />
</pre><br />
<br />
For other devices the configuration might need to be adapted. On the Samsung Galaxy Note 8.0 for example, the audio device is named "Kona_WM1811". Replacing all occurrences in file names and file contents of <code>Midas</code> by <code>Kona</code> worked.<br />
<br />
== Mainline ==<br />
<br />
=== Troubleshooting audio input ===<br />
<br />
A nice way to troubleshoot audio input is to run arecord in a terminal to get realtime audio levels of the default alsa input:<br />
<br />
<source lang="shell"><br />
$ arecord -vv --format=dat /dev/null<br />
Recording WAVE '/dev/null' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo<br />
ALSA <-> PulseAudio PCM I/O Plugin<br />
Its setup is:<br />
stream : CAPTURE<br />
access : RW_INTERLEAVED<br />
format : S16_LE<br />
subformat : STD<br />
channels : 2<br />
rate : 48000<br />
exact rate : 48000 (48000/1)<br />
msbits : 16<br />
buffer_size : 24000<br />
period_size : 6000<br />
period_time : 125000<br />
tstamp_mode : NONE<br />
tstamp_type : GETTIMEOFDAY<br />
period_step : 1<br />
avail_min : 6000<br />
period_event : 0<br />
start_threshold : 1<br />
stop_threshold : 24000<br />
silence_threshold: 0<br />
silence_size : 0<br />
boundary : 6755399441055744000<br />
#+ | 00%<br />
<br />
</source><br />
<br />
== See also ==<br />
* {{github|1328}} Audio added to samsung-p4wifi with udev rules for redirecting audio to headphones when plugging them in<br />
* [https://arunraghavan.net/2016/01/audio-devices-and-configuration/ How to convert Android Audio configurations to alsa/pulseaudio]<br />
* {{MR|238|pmaports}} Audio added to samsung-i927, running close to mainline<br />
<br />
[[Category:Technical Reference]]</div>Asrielhttps://wiki.postmarketos.org/index.php?title=Audio&diff=7313Audio2019-06-29T12:20:06Z<p>Asriel: </p>
<hr />
<div>{{note|If you're trying out anything and learn something that would have helped, please extend this wiki page.}}<br />
<br />
== Audio on Android ==<br />
<br />
=== Mixer configuration ===<br />
<br />
This provides a brief overview of how Android audio HALs configure the ALSA mixer.<br />
<br />
Android devices can have an assortment mixer configurations such as headphones, speakers, or microphones. For a particular device the audio route configurations are defined in <code>mixer_paths.xml</code>. [https://android.googlesource.com/device/lge/hammerhead/+/kitkat-release/mixer_paths.xml For an example see the mixer path XML for Nexus 5 (hammerhead).]<br />
<br />
Android audio HALs make use of [https://android.googlesource.com/platform/external/tinyalsa/ tinyalsa] and [https://android.googlesource.com/platform/system/media/+/kitkat-release/audio_route/ audio_route]. Tinyalsa is a small standalone library to interface with ALSA in the Linux kernel. Audio HALs call the <code>audio_route</code> library which loads audio routes from an XML and controls the mixer through <code>tinyalsa</code>.<br />
<br />
==== Format of mixer_paths.xml ====<br />
* ALSA controls are defined by <code>ctl</code> elements.<br />
* Audio routes are defined by <code>path</code> elements. A <code>path</code> element contains a collection of <code>ctl</code> elements as well as other <code>path</code> elements.<br />
* The path <code>name</code> attribute is used to select an audio route.<br />
<br />
=== Headphone jack ===<br />
<br />
Android kernels use <code>switch_class</code> kernel driver to notify the Android frameworks of headphone jack events. The driver source code can be located at:<br />
<code>drivers/switch/switch_class.c</code><br />
or<br />
<code>drivers/staging/android/switch/switch_class.c</code>. Note that the switch class driver is an Android specific driver. It has not been upstreamed to the mainline kernel.<br />
<br />
In userspace the [https://android.googlesource.com/platform/frameworks/base/+/kitkat-release/services/java/com/android/server/WiredAccessoryManager.java WiredAccessoryManager] monitors the <code>/sys/class/switch/h2w</code> for uevents when the headphone is (un)plugged.<br />
<br />
Udev rules can be used to detect if headphones are plugged in, example for this is from [https://gitlab.com/postmarketOS/pmaports/blob/195114e48e0997d060036feef4965cd0e3c07ccc/device/device-xiaomi-santoni/90-device-xiaomi-santoni-audio.rules xiaomi-santoni]<br />
<br />
== Getting Audio to work on non-Android userspace ==<br />
<br />
=== Bring up Android DSP subsystem ===<br />
{{note|This is most likely for downstream kernels, if you're using a mainline kernel, this is pointless.}}<br />
{{note|This was only tested on Qualcomm MSM8937, this might also work on other chipset too, but this is untested.}}<br />
ADSP needs to be powered on before audio could work on downstream kernels. To do that, you'll have to supply firmware files that is available on your internal MMC.<br />
<br />
On a shell prompt inside postmarketOS, type <code>fdisk -l /dev/mmcblk0</code> (replace mmcblk0 with the correct device name for internal MMC). At this point you should get a familiar partition layout of a Android device.<br />
<br />
Now, the only thing that is important is the partition with <code>modem</code> label on it, which on my device it's mmcblk0p1. Mount the partition as read-only to /mnt using:<br />
<br />
<pre><br />
# mount -o ro /dev/mmcblk0p1 /mnt<br />
</pre><br />
<br />
Inside /mnt, there is a folder named <code>image</code> which has a bunch of firmware files for different parts of the device, like wcnss (for wlan), DRM contents and so on, the only thing that needs to be extracted is all the files that named <code>adsp.*</code>:<br />
<br />
<pre><br />
// Create /lib/firmware/postmarketos if it doesn't exist<br />
# mkdir -p /lib/firmware/postmarketos<br />
<br />
// Copy all adsp.* to the postmarketOS firmware directory<br />
# cp -v /mnt/image/adsp.* /lib/firmware/postmarketos<br />
</pre><br />
<br />
After that, you should be able to bring up the ADSP subsystem by running:<br />
<pre><br />
# echo 1 > /dev/subsys_adsp<br />
</pre><br />
<br />
You should check dmesg and /var/log/firmwareload.log to make sure there aren't firmwares failing to load.<br />
<br />
If it goes fine, you should see a bunch of playback devices by typing <code>aplay -l</code><br />
<br />
You also want to install <code>adsp-audio</code> from pmOS repo to load the subsystem on automatically on bootup.<br />
<br />
=== Convert XML audio to UCM ===<br />
{{note|This section is incomplete. It requires a reference to more complete documentation of the device config XML format.}}<br />
<br />
The audio routes in Linux userspace can be defined in ALSA UCM configuration files. There is a tool called [https://github.com/ford-prefect/xml2ucm xml2ucm] which will convert the Android <code>mixer_paths.xml</code> and a device config XML to UCM files. The <code>xml2ucm</code> tool introduces the device config XML which provides necessary routing information that was hardcoded in the audio HAL on Android.<br />
<br />
The <code>mixer_path.xml</code> is commonly found in the Android device repository. (e.g. <code>android_device_lge_hammerhead</code>). You must write the device config XML for your device.<br />
<br />
==== Format of device config XML ====<br />
<br />
A device config XML describes a sound card with use cases and sets of audio routes. In the examples available at the moment there is only one use case named HiFi. Under each <code><use-case></code> there are multiple <code><device></code> elements. In this context a <code><device></code> means audio route(s) which comprise a logical audio device (e.g. Headphone, Headset, Speaker).<br />
<br />
Android audio HALs can and do select multiple audio routes at once. For example a headset can have a headphone output route and a microphone input route. To handle this a <code><device></code> element (the headset) can contain multiple <code><path></code> elements (audio routes). Example device config XML files are provided in the <code>xml2ucm</code> repository.<br />
<br />
The <code>ctl-device</code> must be the name of the sound card which can be obtained using <code>aplay</code>. In the following example from the Samsung p4wifi the <code>ctl-device</code> is the sound card named <code>wm8994aif1</code>.<br />
<source lang="shell">$ aplay -L<br />
null<br />
Discard all samples (playback) or generate zero samples (capture)<br />
default:CARD=wm8994aif1<br />
wm8994-aif1, <br />
Default Audio Device<br />
sysdefault:CARD=wm8994aif1<br />
wm8994-aif1, <br />
Default Audio Device<br />
</source><br />
<br />
Once the <code>mixer_path.xml</code> and device config XML are converted to UCM format then an audio route can be set by using <code>alsaucm</code>.<br />
Example:<br />
<source lang="shell>$ alsaucm -c wm8994aif1 set _verb HiFi set _enadev Headphones</source><br />
<br />
=== libhybris ===<br />
{{note|Might not work on some devices, which in this case providing logs to the maintainer is required, and debugging is also needed too.}}<br />
Alexey Min (minlexx) is currently packaging [pulseaudio-modules-droid https://gitlab.com/postmarketOS/pmaports/merge_requests/448] to the repository.<br />
<br />
Build and install pulseaudio-modules-droid package first, then add this to <code>/etc/pulse/default.pa</code> before the line that loads module-alsa-sink:<br />
<pre><br />
load-module module-droid-card<br />
load-module module-droid-sink<br />
load-module module-droid-source<br />
</pre><br />
<br />
Start pulseaudio in verbose mode to make sure you can get to see if the module loads successfully. If it does then you should be able to play sound files using <code>paplay</code> from pulseaudio-utils package.<br />
<br />
If you hear sounds coming from it, it works perfectly fine, if not, check dmesg, pulseaudio log and logcat.<br />
<br />
You might also want to install alsa-plugins-pulse for ALSA backend on PulseAudio.<br />
<br />
== alsactl method ==<br />
Cascardo reported having success with the following method on Debian, this should work for postmarketOS as well:<br />
<blockquote><br />
I ran a debian chroot on a cyanogenmod, set the volume up, then ran alsactl save on the chroot. booted into debian, then after alsactl restore was run, I had audio working<br />
<br />
so, in summary, it's hard to know which mixer settings will make it work, so my strategy was running some android stack that correctly set the mixer, then saving the state with a chroot or any other tool that would allow you to save, copy and restore that state later on a gnu stack<br />
</blockquote><br />
<br />
This method may work for non-Android devices as well, as long as you see an audio device in <code>alsamixer</code>. Just boot the normal OS, save the volume settings somehow, then restore them.<br />
<br />
== WM1811 ==<br />
<br />
This audio chip is present in several Samsung devices that are based on the Exynos 4412 platform. There is a configuration for the Samsung Galaxy Note 10.1 available at [https://code.google.com/archive/p/opensgn/source/default/source the opensgn project]. Have a look at the files in <code>opensgn/data/n8000/usr/share/alsa/ucm/Midas_WM1811/</code>.<br />
In <code>opensgn/data/n8000/etc/rc.local</code> there are the commands to use the configuration:<br />
<br />
<pre><br />
# restore alsa sinitial tate<br />
/usr/sbin/alsactl restore -f /usr/share/alsa/ucm/Midas_WM1811/init.state<br />
<br />
# enable speaker for output and builtin mic for input<br />
/usr/bin/alsaucm -c Midas_WM1811 set _verb HiFi set _enadev Speaker<br />
/usr/bin/alsaucm -c Midas_WM1811 set _verb HiFi set _enadev Mic<br />
</pre><br />
<br />
For other devices the configuration might need to be adapted. On the Samsung Galaxy Note 8.0 for example, the audio device is named "Kona_WM1811". Replacing all occurrences in file names and file contents of <code>Midas</code> by <code>Kona</code> worked.<br />
<br />
== Mainline ==<br />
<br />
=== Troubleshooting audio input ===<br />
<br />
A nice way to troubleshoot audio input is to run arecord in a terminal to get realtime audio levels of the default alsa input:<br />
<br />
<source lang="shell"><br />
$ arecord -vv --format=dat /dev/null<br />
Recording WAVE '/dev/null' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo<br />
ALSA <-> PulseAudio PCM I/O Plugin<br />
Its setup is:<br />
stream : CAPTURE<br />
access : RW_INTERLEAVED<br />
format : S16_LE<br />
subformat : STD<br />
channels : 2<br />
rate : 48000<br />
exact rate : 48000 (48000/1)<br />
msbits : 16<br />
buffer_size : 24000<br />
period_size : 6000<br />
period_time : 125000<br />
tstamp_mode : NONE<br />
tstamp_type : GETTIMEOFDAY<br />
period_step : 1<br />
avail_min : 6000<br />
period_event : 0<br />
start_threshold : 1<br />
stop_threshold : 24000<br />
silence_threshold: 0<br />
silence_size : 0<br />
boundary : 6755399441055744000<br />
#+ | 00%<br />
<br />
</source><br />
<br />
== See also ==<br />
* {{github|1328}} Audio added to samsung-p4wifi with udev rules for redirecting audio to headphones when plugging them in<br />
* [https://arunraghavan.net/2016/01/audio-devices-and-configuration/ How to convert Android Audio configurations to alsa/pulseaudio]<br />
* {{MR|238|pmaports}} Audio added to samsung-i927, running close to mainline<br />
<br />
[[Category:Technical Reference]]</div>Asrielhttps://wiki.postmarketos.org/index.php?title=Audio&diff=7312Audio2019-06-29T12:17:35Z<p>Asriel: Added ADSP subsystem bring up and PulseAudio droid module.</p>
<hr />
<div>{{note|If you're trying out anything and learn something that would have helped, please extend this wiki page.}}<br />
<br />
== Audio on Android ==<br />
<br />
=== Mixer configuration ===<br />
<br />
This provides a brief overview of how Android audio HALs configure the ALSA mixer.<br />
<br />
Android devices can have an assortment mixer configurations such as headphones, speakers, or microphones. For a particular device the audio route configurations are defined in <code>mixer_paths.xml</code>. [https://android.googlesource.com/device/lge/hammerhead/+/kitkat-release/mixer_paths.xml For an example see the mixer path XML for Nexus 5 (hammerhead).]<br />
<br />
Android audio HALs make use of [https://android.googlesource.com/platform/external/tinyalsa/ tinyalsa] and [https://android.googlesource.com/platform/system/media/+/kitkat-release/audio_route/ audio_route]. Tinyalsa is a small standalone library to interface with ALSA in the Linux kernel. Audio HALs call the <code>audio_route</code> library which loads audio routes from an XML and controls the mixer through <code>tinyalsa</code>.<br />
<br />
==== Format of mixer_paths.xml ====<br />
* ALSA controls are defined by <code>ctl</code> elements.<br />
* Audio routes are defined by <code>path</code> elements. A <code>path</code> element contains a collection of <code>ctl</code> elements as well as other <code>path</code> elements.<br />
* The path <code>name</code> attribute is used to select an audio route.<br />
<br />
=== Headphone jack ===<br />
<br />
Android kernels use <code>switch_class</code> kernel driver to notify the Android frameworks of headphone jack events. The driver source code can be located at:<br />
<code>drivers/switch/switch_class.c</code><br />
or<br />
<code>drivers/staging/android/switch/switch_class.c</code>. Note that the switch class driver is an Android specific driver. It has not been upstreamed to the mainline kernel.<br />
<br />
In userspace the [https://android.googlesource.com/platform/frameworks/base/+/kitkat-release/services/java/com/android/server/WiredAccessoryManager.java WiredAccessoryManager] monitors the <code>/sys/class/switch/h2w</code> for uevents when the headphone is (un)plugged.<br />
<br />
Udev rules can be used to detect if headphones are plugged in, example for this is from [https://gitlab.com/postmarketOS/pmaports/blob/195114e48e0997d060036feef4965cd0e3c07ccc/device/device-xiaomi-santoni/90-device-xiaomi-santoni-audio.rules xiaomi-santoni]<br />
<br />
== Getting Audio to work on non-Android userspace ==<br />
<br />
=== Bring up Android DSP subsystem ===<br />
{{note|This is most likely for downstream kernels, if you're using a mainline kernel, this is pointless.}}<br />
{{note|This was only tested on Qualcomm MSM8937, this might also work on other chipset too, but this is untested.}}<br />
ADSP needs to be powered on before audio could work on downstream kernels. To do that, you'll have to supply firmware files that is available on your internal MMC.<br />
<br />
On a shell prompt inside postmarketOS, type <code>fdisk -l /dev/mmcblk0</code> (replace mmcblk0 with the correct device name for internal MMC). At this point you should get a familiar partition layout of a Android device.<br />
<br />
Now, the only thing that is important is the partition with <code>modem</code> label on it, which on my device it's mmcblk0p1. Mount the partition as read-only to /mnt using:<br />
<br />
<pre><br />
# mount -o ro /dev/mmcblk0p1 /mnt<br />
</pre><br />
<br />
Inside /mnt, there is a folder named <code>image</code> which has a bunch of firmware files for different parts of the device, like wcnss (for wlan), DRM contents and so on, the only thing that needs to be extracted is all the files that named <code>adsp.*</code>:<br />
<br />
<pre><br />
// Create /lib/firmware/postmarketos if it doesn't exist<br />
# mkdir -p /lib/firmware/postmarketos<br />
<br />
// Copy all adsp.* to the postmarketOS firmware directory<br />
# cp -v /mnt/image/adsp.* /lib/firmware/postmarketos<br />
</pre><br />
<br />
After that, you should be able to bring up the ADSP subsystem by running:<br />
<pre><br />
# echo 1 > /dev/subsys_adsp<br />
</pre><br />
<br />
You should check dmesg and /var/log/firmwareload.log to make sure there aren't firmwares failing to load.<br />
<br />
If it goes fine, you should see a bunch of playback devices by typing <code>aplay -l</code><br />
<br />
=== Convert XML audio to UCM ===<br />
{{note|This section is incomplete. It requires a reference to more complete documentation of the device config XML format.}}<br />
<br />
The audio routes in Linux userspace can be defined in ALSA UCM configuration files. There is a tool called [https://github.com/ford-prefect/xml2ucm xml2ucm] which will convert the Android <code>mixer_paths.xml</code> and a device config XML to UCM files. The <code>xml2ucm</code> tool introduces the device config XML which provides necessary routing information that was hardcoded in the audio HAL on Android.<br />
<br />
The <code>mixer_path.xml</code> is commonly found in the Android device repository. (e.g. <code>android_device_lge_hammerhead</code>). You must write the device config XML for your device.<br />
<br />
==== Format of device config XML ====<br />
<br />
A device config XML describes a sound card with use cases and sets of audio routes. In the examples available at the moment there is only one use case named HiFi. Under each <code><use-case></code> there are multiple <code><device></code> elements. In this context a <code><device></code> means audio route(s) which comprise a logical audio device (e.g. Headphone, Headset, Speaker).<br />
<br />
Android audio HALs can and do select multiple audio routes at once. For example a headset can have a headphone output route and a microphone input route. To handle this a <code><device></code> element (the headset) can contain multiple <code><path></code> elements (audio routes). Example device config XML files are provided in the <code>xml2ucm</code> repository.<br />
<br />
The <code>ctl-device</code> must be the name of the sound card which can be obtained using <code>aplay</code>. In the following example from the Samsung p4wifi the <code>ctl-device</code> is the sound card named <code>wm8994aif1</code>.<br />
<source lang="shell">$ aplay -L<br />
null<br />
Discard all samples (playback) or generate zero samples (capture)<br />
default:CARD=wm8994aif1<br />
wm8994-aif1, <br />
Default Audio Device<br />
sysdefault:CARD=wm8994aif1<br />
wm8994-aif1, <br />
Default Audio Device<br />
</source><br />
<br />
Once the <code>mixer_path.xml</code> and device config XML are converted to UCM format then an audio route can be set by using <code>alsaucm</code>.<br />
Example:<br />
<source lang="shell>$ alsaucm -c wm8994aif1 set _verb HiFi set _enadev Headphones</source><br />
<br />
=== libhybris ===<br />
{{note|Might not work on some devices, which in this case providing logs to the maintainer is required, and debugging is also needed too.}}<br />
Alexey Min (minlexx) is currently packaging [pulseaudio-modules-droid https://gitlab.com/postmarketOS/pmaports/merge_requests/448] to the repository.<br />
<br />
Build and install pulseaudio-modules-droid package first, then add this to <code>/etc/pulse/default.pa</code> before the line that loads module-alsa-sink:<br />
<pre><br />
load-module module-droid-card<br />
load-module module-droid-sink<br />
load-module module-droid-source<br />
</pre><br />
<br />
Start pulseaudio in verbose mode to make sure you can get to see if the module loads successfully. If it does then you should be able to play sound files using <code>paplay</code> from pulseaudio-utils package.<br />
<br />
If you hear sounds coming from it, it works perfectly fine, if not, check dmesg, pulseaudio log and logcat.<br />
<br />
You might also want to install alsa-plugins-pulse for ALSA backend on PulseAudio.<br />
<br />
== alsactl method ==<br />
Cascardo reported having success with the following method on Debian, this should work for postmarketOS as well:<br />
<blockquote><br />
I ran a debian chroot on a cyanogenmod, set the volume up, then ran alsactl save on the chroot. booted into debian, then after alsactl restore was run, I had audio working<br />
<br />
so, in summary, it's hard to know which mixer settings will make it work, so my strategy was running some android stack that correctly set the mixer, then saving the state with a chroot or any other tool that would allow you to save, copy and restore that state later on a gnu stack<br />
</blockquote><br />
<br />
This method may work for non-Android devices as well, as long as you see an audio device in <code>alsamixer</code>. Just boot the normal OS, save the volume settings somehow, then restore them.<br />
<br />
== WM1811 ==<br />
<br />
This audio chip is present in several Samsung devices that are based on the Exynos 4412 platform. There is a configuration for the Samsung Galaxy Note 10.1 available at [https://code.google.com/archive/p/opensgn/source/default/source the opensgn project]. Have a look at the files in <code>opensgn/data/n8000/usr/share/alsa/ucm/Midas_WM1811/</code>.<br />
In <code>opensgn/data/n8000/etc/rc.local</code> there are the commands to use the configuration:<br />
<br />
<pre><br />
# restore alsa sinitial tate<br />
/usr/sbin/alsactl restore -f /usr/share/alsa/ucm/Midas_WM1811/init.state<br />
<br />
# enable speaker for output and builtin mic for input<br />
/usr/bin/alsaucm -c Midas_WM1811 set _verb HiFi set _enadev Speaker<br />
/usr/bin/alsaucm -c Midas_WM1811 set _verb HiFi set _enadev Mic<br />
</pre><br />
<br />
For other devices the configuration might need to be adapted. On the Samsung Galaxy Note 8.0 for example, the audio device is named "Kona_WM1811". Replacing all occurrences in file names and file contents of <code>Midas</code> by <code>Kona</code> worked.<br />
<br />
== Mainline ==<br />
<br />
=== Troubleshooting audio input ===<br />
<br />
A nice way to troubleshoot audio input is to run arecord in a terminal to get realtime audio levels of the default alsa input:<br />
<br />
<source lang="shell"><br />
$ arecord -vv --format=dat /dev/null<br />
Recording WAVE '/dev/null' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo<br />
ALSA <-> PulseAudio PCM I/O Plugin<br />
Its setup is:<br />
stream : CAPTURE<br />
access : RW_INTERLEAVED<br />
format : S16_LE<br />
subformat : STD<br />
channels : 2<br />
rate : 48000<br />
exact rate : 48000 (48000/1)<br />
msbits : 16<br />
buffer_size : 24000<br />
period_size : 6000<br />
period_time : 125000<br />
tstamp_mode : NONE<br />
tstamp_type : GETTIMEOFDAY<br />
period_step : 1<br />
avail_min : 6000<br />
period_event : 0<br />
start_threshold : 1<br />
stop_threshold : 24000<br />
silence_threshold: 0<br />
silence_size : 0<br />
boundary : 6755399441055744000<br />
#+ | 00%<br />
<br />
</source><br />
<br />
== See also ==<br />
* {{github|1328}} Audio added to samsung-p4wifi with udev rules for redirecting audio to headphones when plugging them in<br />
* [https://arunraghavan.net/2016/01/audio-devices-and-configuration/ How to convert Android Audio configurations to alsa/pulseaudio]<br />
* {{MR|238|pmaports}} Audio added to samsung-i927, running close to mainline<br />
<br />
[[Category:Technical Reference]]</div>Asriel