高通Linux 音频指南(三)

Platform Adaptation Layer (PAL)

平台适配层(PAL)提供更高层次的音频特定API,以访问底层音频硬件和驱动程序,从而启用丰富的音频用例。

PulseAudio使用相同的PAL API来处理不同的音频用例。PAL模块的源代码位于:
build-qcom-wayland/workspace/sources/pal/opensource/arpal-lx
PAL模块所暴露的所有API均在以下文件中声明:
build-qcom-wayland/workspace/sources/pal/opensource/arpal-lx/inc/PalApi.h

以下是一些常用的PAL API。

pal_init

初始化PAL,解析相关的配置文件,并将其存储在本地结构中,以便在使用案例期间使用。

int32_t pal_init()

参数

返回值

成功返回0
失败返回错误代码
pal_deinit

反初始化PAL,并释放在初始化期间分配的资源。

void pal_deinit()

参数

返回值

成功返回0
失败返回错误代码
pal_stream_open

使用指定的配置(如源/接收器设备、媒体配置等)打开一个流。在成功执行时返回流句柄。

int32_t pal_stream_open(
     struct pal_stream_attributes *attributes, 
     uint32_t no_of_devices, 
     struct pal_device *devices, 
     uint32_t no_of_modifiers, 
     struct modifier_kv *modifiers, 
     pal_stream_callback cb, 
     uint64_t cookie, 
     pal_stream_handle_t **stream_handle)

参数

attributes:从 pal_stream_open 获得的有效流属性
no_of_devices:与流初始启动的音频设备数量
devices:pal_devices的数组。数组的大小基于客户端指定的 no_of_devices。
no_of_modifiers:修饰符的数量
modifiers:修饰符数组。修饰符用于添加额外的键值对。
cb:与流关联的回调函数。任何事件将通过此回调函数通知。
cookie:与流关联的客户端数据。此cookie将在回调函数中返回。
stream_handle:如果操作成功,更新为有效流句柄。

返回值

成功返回0
失败返回错误代码
pal_stream_start

启动一个流。

int32_t pal_stream_start(
     pal_stream_handle_t *stream_handle)

参数

stream_handle:从 pal_stream_open 获得的有效流句柄

返回值

成功返回0
失败返回错误代码
pal_stream_read

读取从音频源设备捕获的音频缓冲区。

ssize_t pal_stream_read(
     pal_stream_handle_t *stream_handle, 
     struct pal_buffer *buf)

参数

stream_handle:从 pal_stream_open 获得的有效流句柄
buf:指向包含音频样本和元数据的pal_buffer的指针

返回值

读取的字节数
失败返回错误代码
pal_stream_write

为流渲染写入音频缓冲区到接收器设备。

ssize_t pal_stream_write(
     pal_stream_handle_t *stream_handle, 
     struct pal_buffer *buf)

参数

stream_handle:从 pal_stream_open 获得的有效流句柄
buf:指向包含音频样本和元数据的pal_buffer的指针

返回值

写入的字节数
失败返回错误代码
pal_stream_stop

停止一个流。

int32_t pal_stream_stop(
     pal_stream_handle_t *stream_handle)

参数

stream_handle:从 pal_stream_open 获得的有效流句柄

返回值

成功返回0
失败返回错误代码
pal_stream_close

关闭一个流。

int32_t pal_stream_close(
     pal_stream_handle_t *stream_handle)

参数

stream_handle:从 pal_stream_open 获得的有效流句柄

返回值

成功返回0
失败返回错误代码
TinyALSA

TinyALSA 是一个库,将ALSA内核接口封装为客户端可以调用的API,并提供一个插件接口来模拟ALSA API。

TinyALSA 的源代码可以在以下位置找到:

build-qcom-wayland/workspace/sources/tinyalsa/opensource/tinyalsa
build-qcom-wayland/workspace/sources/tinyalsa/opensource/tinycompress

以下是一些常用的TinyALSA API,完整的API描述请参见开源TinyALSA文档。

pcm_open

用于打开一个PCM音频设备以进行输入和输出操作。初始化PCM设备以便于通信,允许后续进行音频数据的读写操作。

struct pcm *pcm_open(
     unsigned int card, 
     unsigned int device, 
     unsigned int flags, 
     struct pcm_config *config)

参数

card:指定卡号
device:指定所选卡中的设备号
flags:配置PCM设备的各种方面的标志
config:用于指定音频流参数的结构变量

返回值

pcm* 句柄
pcm_is_ready

用于检查PCM设备是否准备好进行输入/输出操作。

int pcm_is_ready(struct pcm *pcm)

参数

pcm:指向打开的PCM设备的指针

返回值

成功返回0
失败返回错误代码
pcm_prepare

准备音频设备的输入和输出操作。

int pcm_prepare(struct pcm *pcm)

参数

pcm:指向打开的PCM设备的指针

返回值

成功返回0
失败返回错误代码
pcm_start

用于启动PCM音频设备进行输入和输出操作。

int pcm_start(struct pcm *pcm)

参数

pcm:指向已打开的PCM设备的指针

返回值

成功返回0
失败返回错误代码
pcm_write

用于将音频数据写入音频PCM设备。接受音频数据作为输入,并将其发送到PCM设备进行播放或处理。

int pcm_write(struct pcm *pcm, const void *data, unsigned int count)

参数

pcm:指向已打开的PCM设备的指针
data:要写入的音频数据
count:要写入的音频帧数

返回值

成功返回0
失败返回错误代码
pcm_read

从PCM设备获取音频数据,允许应用程序从麦克风捕获音频数据。

int pcm_read(struct pcm *pcm, void *data, unsigned int count)

参数

pcm:指向已打开的PCM设备的指针
data:要读取的音频数据
count:要读取的音频帧数

返回值

成功返回0
失败返回错误代码
pcm_stop

用于停止PCM音频设备的进一步输入和输出操作。

int pcm_stop(struct pcm *pcm)

参数

pcm:指向已打开的PCM设备的指针

返回值

成功返回0
失败返回错误代码
pcm_close

用于关闭PCM音频设备。这会释放与PCM设备相关的资源并释放内存。

int pcm_close(struct pcm *pcm)

参数

pcm:指向已打开的PCM设备的指针

返回值

成功返回0
失败返回错误代码
基于TinyALSA的应用

要实现TinyALSA的音频用例,请配置虚拟混音器控制。这些控制由混音插件创建,用于设置音频用例图和模块。大多数是基于字节数组,并使用 mixer_ctl_set_array API 进行配置。元数据(称为“PCM100元数据”)使用键值(KV)对进行设置。有关实现细节,请查看 set_agm_audio_intf_metadata API,在以下位置:

build-qcom-wayland/workspace/sources/agm/opensource/agm/plugins/tinyalsa/test/agmmixer.c
/**
 * 键值对
 */
struct agm_key_value {
    uint32_t key; /**< 键 */
    uint32_t value; /**< 值 */
};
/*键值对的示例分配*/
gkv = calloc(num_gkv, sizeof(struct agm_key_value));
ckv = calloc(num_ckv, sizeof(struct agm_key_value));

按照以下设置顺序实现和执行音频用例。基于TinyALSA的agmplay和agmcap工具的示例代码可以在以下位置找到:

build-qcom-wayland/workspace/sources/agm/opensource/agm/plugins/tinyalsa/test.
  1. 设置音频接口(后端)设备配置,包括采样率、通道、格式和数据格式。

    ‘CODEC_DMA-LPAIF_WSA-RX-0 rate ch fmt’ 48000 2 2(PCM_16)

  2. 设置元数据,包括图形键、设备的校准键和DevicePP。

    ‘CODEC_DMA-LPAIF_WSA-RX-0 metadata’ bytes

  3. 设置控制以指示后续混音器配置将设置流和StreamPP子图的元数据。零表示后续命令用于流。

    ‘PCM100 control’ Zero
    ‘PCM100 metadata’ bytes

  4. 设置控制以指示后续混音器配置将设置DevicePP和stream-device子图的参数。CODEC_DMA-LPAIF_WSA-RX-0表示后续命令用于stream-device。CODEC_DMA-LPAIF_WSA-RX-0 是注册到ALSA ASOC框架的音频接口之一。所有音频接口的列表可以在 /proc/asound/pcm 找到。

    ‘PCM100 control’ CODEC_DMA-LPAIF_WSA-RX-0
    ‘PCM100 metadata’ bytes

  5. 检索与流和音频接口之间的给定会话相关的所有标签、模块ID和实例ID。

    ‘PCM100 getTaggedInfo’ bytes

  6. 设置控制以指示后续混音器配置将为流子图上的模块设置参数。

    ‘PCM100 control’ Zero
    ‘PCM100 setParam’ bytes

  7. 设置控制以指示后续混音器配置将为StreamDevice和DevicePP子图上的模块设置参数。

    ‘PCM100 control’ CODEC_DMA-LPAIF_WSA-RX-0
    ‘PCM100 setParam’ bytes

  8. 将前端(流)与后端(编解码器/音频接口)连接。

    ‘PCM100 connect’ CODEC_DMA-LPAIF_WSA-RX-0

  9. 初始化PCM设备以进行通信。

    pcm_open

  10. 准备音频设备以进行输入和输出操作。

    pcm_prepare

  11. 启动PCM音频设备进行输入/输出操作。

    pcm_start

  12. 从音频PCM设备读/写音频数据。

    pcm_write/pcm_read

  13. 停止PCM设备进一步进行输入/输出操作。

    pcm_stop

  14. 关闭PCM音频设备。

    pcm_close

所有虚拟设备的混音器控制都可以使用以下命令获取:

ssh root@ip-addr
systemctl stop pulseaudio
tinymix set -D 100
TinyALSA级播放和录音测试

录音

  1. 要验证使用TinyALSA的录音功能:

    ssh root@ip-addr
    systemctl stop pulseaudio
    tinymix set 'VA DMIC MUX0' DMIC0
    tinymix set 'VA_AIF1_CAP Mixer DEC0' 1
    tinymix set 'VA_DEC0 Volume' 100
    agmcap /opt/test.wav -D 100 -d 101 -c 1 -r 48000 -b 16 -i CODEC_DMA-LPAIF_VA-TX-0 -dkv 0xA3000004 -skv 0xB1000009 -dppkv 0 -ikv 0 -T 10
    
  2. 要提取录制的文件,请在主机机器上运行以下命令:

    scp root@[ip-addr]:/data/test.wav
    

播放

  1. 要进行播放,首先使用以下命令将 .wav 文件推送到设备:

    scp test.wav root@[ip-addr]:/data/
    
  2. 运行以下命令以启动播放:

    ssh root@ip-addr 
    mount -o remount,rw /
    systemctl stop pulseaudio
    scp test.wav root@[ip-addr]:/data/
    ssh root@ip-addr
    tinymix set 'SpkrLeft PA Volume' 20
    tinymix set 'WSA RX0 MUX' AIF1_PB
    tinymix set 'WSA_RX0 INP0' RX0
    tinymix set 'WSA_COMP1 Switch' 1
    tinymix set 'SpkrLeft WSA MODE' 0
    tinymix set 'SpkrLeft COMP Switch' 1
    tinymix set 'SpkrLeft BOOST Switch' 1
    tinymix set 'SpkrLeft DAC Switch' 1
    tinymix set 'SpkrLeft VISENSE Switch' 0
    tinymix set 'WSA_RX0 Digital Volume'  85
    tinymix set 'SpkrRight WSA MODE' 0
    tinymix set 'SpkrRight PA Volume' 20
    tinymix set 'WSA RX1 MUX' AIF1_PB
    tinymix set 'WSA_RX1 INP0' RX1
    tinymix set 'WSA_COMP2 Switch' 1
    tinymix set 'SpkrRight COMP Switch' 1
    tinymix set 'SpkrRight BOOST Switch' 1
    tinymix set 'SpkrRight DAC Switch' 1
    tinymix set 'SpkrRight VISENSE Switch' 0
    tinymix set 'WSA_RX1 Digital Volume'  85
    agmplay /opt/test.wav -D 100 -d 100 -i CODEC_DMA-LPAIF_WSA-RX-0
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值