CirrusLogic / tinyhal

Configurable audio HAL for Android
Apache License 2.0
31 stars 17 forks source link

Selecting output stream for specific devices ? #16

Open vknecht opened 1 year ago

vknecht commented 1 year ago

Hello,

my phone has an external codec for headphone and don't see how to select the correct PCM output stream on jack insertion. I see tinyhal : adev_set_parameters 'connect=8' in logs but not sure how to manage it. At worse, some code should be written, but maybe that's doable from XML config ?

For reference, the Linux/postmarketOS working UCM, and my current tinyhal xml & audio policy : https://github.com/msm8916-mainline/alsa-ucm-conf/blob/master/ucm2/alcatel-idol3/HiFi.conf https://github.com/GloDroidCommunity/qcom-msm8916-series/blob/main/aosptree/vendor/devices-community/idol347/etc/audio.idol347.xml https://github.com/GloDroidCommunity/qcom-msm8916-series/blob/main/aosptree/vendor/devices-community/idol347/etc/audio_policy_configuration.xml

Thank you

vknecht commented 1 year ago

Hi @rfvirgil, would you have any idea about how to proceed ? Thank you

rfvirgil commented 1 year ago

Device 8 is AUDIO_DEVICE_OUT_WIRED_HEADPHONE so you need a section in your config file for the "headphone" device.

<device name="headphone">
        <path name="on">
                <!-- controls to enable output -->
        </path>
        <path name="off">
                <!-- controls to disable output -->
        </path>
        <path name="on_pcm">
                <!-- Control settings when PCM output is routed to headphone-->
        </path>
        <path name="off_pcm">
                <!-- Control settings when PCM output is disconnected from headphone-->
        </path>
</device>
vknecht commented 1 year ago

Hi @rfvirgil and thank you for your answer. I've tried quite a few combinations with paths, but iiuc my problem is that headphone output is to be sent to a dedicated ALSA PCM output device/stream and afaik there's no mixer control setting to do that. In my case, device 0 is external codec (ak4375) for headphone, and device 2 is another external codec (tfa9897) for speaker/earpiece :

idol347:/ # tinypcminfo -D 0 -d 0                                                                                   
Info for card 0, device 0:

PCM out:
      Access:   0x000009
   Format[0]:   0x000044
   Format[1]:   00000000
 Format Name:   S16_LE, S24_LE
   Subformat:   0x000001
        Rate:   min=8000Hz  max=192000Hz
    Channels:   min=1       max=8
 Sample bits:   min=16      max=32
 Period size:   min=4       max=32768
Period count:   min=2       max=8

PCM in:
cannot open device 0 for card 0
pcm_hw_open: cannot open device '/dev/snd/pcmC0D0c'Device does not exist.

idol347:/ # tinypcminfo -D 0 -d 2                                                                                   
Info for card 0, device 2:

PCM out:
      Access:   0x000009
   Format[0]:   0x000044
   Format[1]:   00000000
 Format Name:   S16_LE, S24_LE
   Subformat:   0x000001
        Rate:   min=8000Hz  max=192000Hz
    Channels:   min=1       max=8
 Sample bits:   min=16      max=32
 Period size:   min=4       max=32768
Period count:   min=2       max=8

PCM in:
cannot open device 2 for card 0
pcm_hw_open: cannot open device '/dev/snd/pcmC0D2c'Device does not exist.

With Linux UCM files, like the one linked previously, the mapping is very explicit.

Am I wrong when I declare 2 pcm streams in tinyhal, like this ?

    <!-- headphone/headset, PlaybackPCM "hw:${CardId},0" -->
    <stream type="pcm" dir="out" cardname="alcatelidol3" device="0" />

    <!-- speakers/earpiece, PlaybackPCM "hw:${CardId},2" -->
    <stream type="pcm" dir="out" cardname="alcatelidol3" device="2" />

I'm under the impression that tinyhal only uses/manages one PCM output stream, and would have to manually open/select device 0 in adev_set_parameters() when connect=8 is received. But maybe something could be done either on device or stream config to do that automatically ? Or I'm missing something ? Like perhaps I'd have to tweak audio_policy_configuration.xml with a new mixPort and a distinct route ?

Thank you

rfvirgil commented 1 year ago

It looks like this needs a small extension to tinyhal. The card/device are currently associated with a stream not the transducer. At the time tinyhal was written this was how the available hardware worked. Changes needed: 1) Change the configmgr parser so that the card/device attributes can be added to a block and store these in struct device. 2) Add an API to configmgr so to get the card/device attribute associated with a device. 3) Change audio_hw.c so that start_output_pcm() and start_input_pcm() use this new API to lookup the card/device attribute for the selected and use that if it exists. If it doesn't exist fallback to the default in the hw_stream. 4) You'll also need to update out_set_parameters() and in_pcm_set_parameters() so that when Android changes the routing of audio the next pcm_open() will use the card/device attributes of the new