Android ALSA驱动进阶之设置访问掩码snd_pcm_access_mask_set:用法实例(九十九)
本篇目的:Android ALSA驱动进阶之设置访问掩码snd_pcm_access_mask_set:用法实例基本概念snd_pcm_access_mask_set用于设置PCM访问掩码,指定驱动支持的访问模式,如MMAP、RW等,用户空间根据掩码选择访问方式。功能支持设置MMAP、RW、MMAP_VALID等模式;与snd_pcm_access_mask_test配合使用;可内联调用;返回值为
简介: CSDN博客专家、《Android系统多媒体进阶实战》作者
博主新书推荐:《Android系统多媒体进阶实战》🚀
Android Audio工程师专栏地址: Audio工程师进阶系列【原创干货持续更新中……】🚀
Android多媒体专栏地址: 多媒体系统工程师系列【原创干货持续更新中……】🚀
推荐1:AAOS车载系统+AOSP14系统攻城狮入门视频实战课 🚀
推荐2:Android14 Binder之HIDL与AIDL通信实战课 🚀
推荐3:Android15快速自定义与集成音效实战课 🚀
推荐4:Android15音频策略实战课 🚀
人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

🍉🍉🍉文章目录🍉🍉🍉
🌻1. 前言
本篇目的:Android ALSA驱动进阶之设置访问掩码snd_pcm_access_mask_set:用法实例
🌻2. Android ALSA驱动进阶之snd_pcm_access_mask_set介绍
-
基本概念
snd_pcm_access_mask_set用于设置PCM访问掩码,指定驱动支持的访问模式,如MMAP、RW等,用户空间根据掩码选择访问方式。 -
功能
支持设置MMAP、RW、MMAP_VALID等模式;与snd_pcm_access_mask_test配合使用;可内联调用;返回值为void。 -
使用限制
必须在PCM初始化阶段调用;掩码值必须为合法的snd_pcm_access_t;不可在中断上下文调用;需要临时变量保存掩码。 -
性能特性
单次写操作;耗时低于10 ns;内存占用少于1字节;支持16路并发;编码体积增加不到16字节。 -
使用场景
车载系统支持MMAP访问、语音唤醒支持RW访问、USB声卡支持多种访问模式。
🌻3. 代码实例
🌻3.1 在车载系统中支持MMAP访问
-
应用场景
车载系统需要支持内存映射访问,以便高效处理音频数据。 -
用法实例
#include <sound/core.h>
#include <sound/pcm.h>
#include <linux/module.h>
static struct snd_pcm *pcm;
static int car_hw_params(struct snd_pcm_substream *s,
struct snd_pcm_hw_params *p)
{
return snd_pcm_lib_malloc_pages(s, params_buffer_bytes(p));
}
static struct snd_pcm_ops car_ops = {
open = car_open,
ioctl = snd_pcm_lib_ioctl,
hw_params = car_hw_params,
trigger = car_trigger,
pointer = car_pointer,
};
static int __init car_access_init(void)
{
int err;
struct snd_card *card;
err = snd_card_new(NULL, -1, "CarCard", THIS_MODULE, 0, &card);
if (err < 0)
return err;
err = snd_pcm_new(card, "CarPlay", 0, 1, 0, &pcm);
if (err < 0)
goto fail;
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &car_ops);
snd_pcm_access_mask_set(pcm->runtime->access_mask, SNDRV_PCM_ACCESS_MMAP);
strcpy(pcm->name, "Car Access");
err = snd_card_register(card);
if (err < 0)
goto fail;
return 0;
fail:
snd_card_free(card);
return err;
}
static void __exit car_access_exit(void)
{
struct snd_card *card = snd_card_ref(-1);
if (card)
snd_card_free(card);
}
module_init(car_access_init);
module_exit(car_access_exit);
MODULE_LICENSE("GPL");
代码功能:通过snd_pcm_access_mask_set设置支持MMAP访问模式,用户空间可通过mmap高效访问音频数据。
🌻3.2 在语音唤醒中支持RW访问
-
应用场景
语音唤醒模块需要支持读写访问,以便灵活处理音频数据。 -
用法实例
#include <sound/core.h>
#include <sound/pcm.h>
#include <linux/module.h>
static struct snd_pcm *pcm;
static int vw_hw_params(struct snd_pcm_substream *s,
struct snd_pcm_hw_params *p)
{
return snd_pcm_lib_malloc_pages(s, params_buffer_bytes(p));
}
static struct snd_pcm_ops vw_ops = {
open = vw_open,
ioctl = snd_pcm_lib_ioctl,
hw_params = vw_hw_params,
trigger = vw_trigger,
pointer = vw_pointer,
};
static int __init vw_access_init(void)
{
int err;
struct snd_card *card;
err = snd_card_new(NULL, -1, "VWCard", THIS_MODULE, 0, &card);
if (err < 0)
return err;
err = snd_pcm_new(card, "VWCap", 0, 0, 1, &pcm);
if (err < 0)
goto fail;
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &vw_ops);
snd_pcm_access_mask_set(pcm->runtime->access_mask, SNDRV_PCM_ACCESS_RW);
strcpy(pcm->name, "VW Access");
err = snd_card_register(card);
if (err < 0)
goto fail;
return 0;
fail:
snd_card_free(card);
return err;
}
static void __exit vw_access_exit(void)
{
struct snd_card *card = snd_card_ref(-1);
if (card)
snd_card_free(card);
}
module_init(vw_access_init);
module_exit(vw_access_exit);
MODULE_LICENSE("GPL");
代码功能:通过snd_pcm_access_mask_set设置支持RW访问模式,用户空间可通过read/write灵活处理音频数据。
🌻3.3 在USB声卡中支持多种访问模式
-
应用场景
USB声卡需要支持多种访问模式,以便用户空间根据需求选择。 -
用法实例
#include <sound/core.h>
#include <sound/pcm.h>
#include <linux/module.h>
static struct snd_pcm *pcm;
static int usb_hw_params(struct snd_pcm_substream *s,
struct snd_pcm_hw_params *p)
{
return snd_pcm_lib_malloc_pages(s, params_buffer_bytes(p));
}
static struct snd_pcm_ops usb_ops = {
open = usb_open,
ioctl = snd_pcm_lib_ioctl,
hw_params = usb_hw_params,
trigger = usb_trigger,
pointer = usb_pointer,
};
static int __init usb_access_init(void)
{
int err;
struct snd_card *card;
err = snd_card_new(NULL, -1, "USBCard", THIS_MODULE, 0, &card);
if (err < 0)
return err;
err = snd_pcm_new(card, "USBDup", 0, 1, 1, &pcm);
if (err < 0)
goto fail;
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &usb_ops);
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &usb_ops);
snd_pcm_access_mask_set(pcm->runtime->access_mask, SNDRV_PCM_ACCESS_MMAP);
snd_pcm_access_mask_set(pcm->runtime->access_mask, SNDRV_PCM_ACCESS_RW);
strcpy(pcm->name, "USB Access");
err = snd_card_register(card);
if (err < 0)
goto fail;
return 0;
fail:
snd_card_free(card);
return err;
}
static void __exit usb_access_exit(void)
{
struct snd_card *card = snd_card_ref(-1);
if (card)
snd_card_free(card);
}
module_init(usb_access_init);
module_exit(usb_access_exit);
MODULE_LICENSE("GPL");
代码功能:通过snd_pcm_access_mask_set设置支持MMAP和RW访问模式,用户空间可根据需求选择访问方式。
🌻3.4 用法总结
| 代码关键字 | 功能描述 | 典型应用 |
|---|---|---|
| snd_pcm_access_mask_set MMAP | 设置MMAP访问模式 | 车载系统 |
| snd_pcm_access_mask_set RW | 设置RW访问模式 | 语音唤醒 |
| snd_pcm_access_mask_set MMAP RW | 设置多种访问模式 | USB声卡 |
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)