Linux驱动——ALSA

article/2025/10/3 2:27:51

Linux驱动——ALSA

小狼@http://blog.csdn.net/xiaolangyangyang


 Control宏定义:

SOC_SINGLE_VALUE
SOC_SINGLE_VALUE_EXT
SOC_SINGLE
SOC_SINGLE_TLV
SOC_DOUBLE
SOC_DOUBLE_R
SOC_DOUBLE_TLV
SOC_DOUBLE_R_TLV
SOC_DOUBLE_S8_TLV
SOC_ENUM_DOUBLE
SOC_ENUM_SINGLE
SOC_ENUM_SINGLE_EXT
SOC_VALUE_ENUM_DOUBLE
SOC_VALUE_ENUM_SINGLE
SOC_ENUM
SOC_VALUE_ENUM
SOC_SINGLE_EXT
SOC_DOUBLE_EXT
SOC_SINGLE_EXT_TLV
SOC_DOUBLE_EXT_TLV
SOC_DOUBLE_R_EXT_TLV
SOC_SINGLE_BOOL_EXT
SOC_ENUM_EXT
SOC_DOUBLE_R_SX_TLV
SOC_ENUM_DOUBLE_DECL
SOC_ENUM_SINGLE_DECL
SOC_ENUM_SINGLE_EXT_DECL
SOC_VALUE_ENUM_DOUBLE_DECL
SOC_VALUE_ENUM_SINGLE_DECL

DAPM宏定义:

SND_SOC_DAPM_VMID
SND_SOC_DAPM_INPUT
SND_SOC_DAPM_OUTPUT
SND_SOC_DAPM_MIC
SND_SOC_DAPM_HP
SND_SOC_DAPM_SPK
SND_SOC_DAPM_LINE
SND_SOC_DAPM_PGA
SND_SOC_DAPM_OUT_DRV
SND_SOC_DAPM_MIXER
SND_SOC_DAPM_MIXER_NAMED_CTL
SND_SOC_DAPM_MICBIAS
SND_SOC_DAPM_SWITCH
SND_SOC_DAPM_MUX
SND_SOC_DAPM_VIRT_MUX
SND_SOC_DAPM_VALUE_MUX
SOC_PGA_ARRAY
SOC_MIXER_ARRAY
SOC_MIXER_NAMED_CTL_ARRAY
SND_SOC_DAPM_PGA_E
SND_SOC_DAPM_OUT_DRV_E
SND_SOC_DAPM_MIXER_E
SND_SOC_DAPM_MIXER_NAMED_CTL_E
SND_SOC_DAPM_MICBIAS_E
SND_SOC_DAPM_SWITCH_E
SND_SOC_DAPM_MUX_E
SND_SOC_DAPM_VIRT_MUX_E
SND_SOC_DAPM_PGA_S
SND_SOC_DAPM_SUPPLY_S
SOC_PGA_E_ARRAY
SOC_MIXER_E_ARRAY
SOC_MIXER_NAMED_CTL_E_ARRAY
SND_SOC_DAPM_PRE
SND_SOC_DAPM_POST
SND_SOC_DAPM_AIF_IN
SND_SOC_DAPM_AIF_IN_E
SND_SOC_DAPM_AIF_OUT
SND_SOC_DAPM_AIF_OUT_E
SND_SOC_DAPM_DAC
SND_SOC_DAPM_DAC_E
SND_SOC_DAPM_ADC
SND_SOC_DAPM_ADC_E
SND_SOC_DAPM_REG
SND_SOC_DAPM_SUPPLY
SOC_DAPM_SINGLE
SOC_DAPM_SINGLE_TLV
SOC_DAPM_ENUM
SOC_DAPM_ENUM_VIRT
SOC_DAPM_VALUE_ENUM
SOC_DAPM_PIN_SWITCH

static const struct snd_kcontrol_new wmxx_mix1_controls[] = {SOC_DAPM_SINGLE("SW1", WMXX_REG_SW, 1, 1, 0),SOC_DAPM_SINGLE("SW2", WMXX_REG_SW, 2, 0, 0),SOC_DAPM_SINGLE("SW3", WMXX_REG_SW, 3, 0, 0),SOC_DAPM_SINGLE("SW4", WMXX_REG_SW, 4, 0, 0)
};static const struct snd_kcontrol_new wmxx_mix2_controls[] = {SOC_DAPM_SINGLE("SW5", WMXX_REG_SW, 5, 1, 0),SOC_DAPM_SINGLE("SW6", WMXX_REG_SW, 6, 0, 0),SOC_DAPM_SINGLE("SW7", WMXX_REG_SW, 7, 0, 0),SOC_DAPM_SINGLE("SW8", WMXX_REG_SW, 8, 0, 0)
};static const struct snd_soc_dapm_widget wm8900_dapm_widgets[] = {SND_SOC_DAPM_MIXER("MIX1", WMXX_REG_MIX, 1, 0, wmxx_mix1_controls, ARRAY_SIZE(wmxx_mix1_controls)),SND_SOC_DAPM_MIXER("MIX2", WMXX_REG_MIX, 2, 0, wmxx_mix2_controls, ARRAY_SIZE(wmxx_mix2_controls))
};static const struct snd_soc_dapm_route audio_map[] = {{"MIX1", "SW2", "ADC"},{"MIX2", "SW6", "MIX1"},
};

 播放器代码

#include <alsa/asoundlib.h>
#include <stdio.h>
#include <termios.h> 
#include <unistd.h>
#include <stdlib.h>#define int8_t		char
#define int16_t		short
#define int32_t		int
#define int64_t		long
#define uint8_t		unsigned char
#define uint16_t	unsigned short
#define uint32_t	unsigned int
#define uint64_t	unsigned long/* para of wav file */
typedef struct {uint32_t dwSize;uint16_t wFormatTag;uint16_t wChannels;uint32_t dwSamplesPerSec;uint32_t dwAvgBytesPerSec;uint16_t wBlockAlign;uint16_t wBitsPerSample;
} WAVEFORMAT;/* format of wav file header */
typedef struct {uint8_t RiffID [4];uint32_t RiffSize;uint8_t WaveID[4];uint8_t FmtID[4];uint32_t FmtSize;uint16_t wFormatTag;uint16_t nChannels;uint32_t nSamplesPerSec;uint32_t nAvgBytesPerSec;uint16_t nBlockAlign;uint16_t wBitsPerSample;uint8_t DataID[4];uint32_t nDataBytes;
} WAVE_HEADER;/* set hwparams */
static int32_t set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params, snd_pcm_access_t access, uint32_t ch, snd_pcm_format_t format, uint32_t rate, snd_pcm_sframes_t *period_size)
{snd_pcm_uframes_t size;uint32_t rrate;int32_t err, dir;uint32_t buffer_time = 500000;	/* ring buffer length in us */uint32_t period_time = 100000;	/* period time in us */int32_t resample = 1;	/* enable alsa-lib resampling *//* choose all parameters */err = snd_pcm_hw_params_any(handle, params);if (err < 0){printf("Broken configuration for playback: no configurations available: %s\n", snd_strerror(err));return err;}/* set hardware resampling */err = snd_pcm_hw_params_set_rate_resample(handle, params, resample);if (err < 0){printf("Resampling setup failed for playback: %s\n", snd_strerror(err));return err;}/* set the interleaved read/write format */err = snd_pcm_hw_params_set_access(handle, params, access);if (err < 0){printf("Access type not available for playback: %s\n", snd_strerror(err));return err;}/* set the sample format */err = snd_pcm_hw_params_set_format(handle, params, format);if (err < 0){printf("Sample format not available for playback: %s\n", snd_strerror(err));return err;}/* set the count of channels */err = snd_pcm_hw_params_set_channels(handle, params, ch);if (err < 0){printf("Channels count (%u) not available for playbacks: %s\n", ch, snd_strerror(err));return err;}/* set the stream rate */rrate = rate;err = snd_pcm_hw_params_set_rate_near(handle, params, &rrate, 0);if (err < 0){printf("Rate %uHz not available for playback: %s\n", rate, snd_strerror(err));return err;}if (rrate != rate){printf("Rate doesn't match (requested %uHz, get %iHz)\n", rate, err);return -EINVAL;}/* set the buffer time */err = snd_pcm_hw_params_set_buffer_time_near(handle, params, &buffer_time, &dir);if (err < 0){printf("Unable to set buffer time %u for playback: %s\n", buffer_time, snd_strerror(err));return err;}err = snd_pcm_hw_params_get_buffer_size(params, &size);if (err < 0){printf("Unable to get buffer size for playback: %s\n", snd_strerror(err));return err;}printf("buffer_size = %ld\n", size);/* set the period time */ err = snd_pcm_hw_params_set_period_time_near(handle, params, &period_time, &dir);if (err < 0){printf("Unable to set period time %u for playback: %s\n", period_time, snd_strerror(err));return err;}err = snd_pcm_hw_params_get_period_size(params, &size, &dir);if (err < 0){printf("Unable to get period size for playback: %s\n", snd_strerror(err));return err;}*period_size = size;printf("period_size = %ld\n", size);/* write the parameters to device */err = snd_pcm_hw_params(handle, params);if (err < 0){printf("Unable to set hw params for playback: %s\n", snd_strerror(err));return err;}return 0;
}/* read wav file header*/
FILE * open_and_print_file_params(int8_t *file_name, WAVE_HEADER *g_wave_header)
{FILE * fp = fopen(file_name, "r");if (fp == NULL){printf("can't open wav file\n");return NULL;}memset(g_wave_header, 0, sizeof(WAVE_HEADER));fread(g_wave_header, 1, sizeof(WAVE_HEADER), fp);printf(">> RiffID : %c%c%c%c\n", g_wave_header->RiffID[0], g_wave_header->RiffID[1], g_wave_header->RiffID[2], g_wave_header->RiffID[3]);printf(">> RiffSize : %d\n", g_wave_header->RiffSize);printf(">> WaveID : %c%c%c%c\n", g_wave_header->WaveID[0], g_wave_header->WaveID[1], g_wave_header->WaveID[2], g_wave_header->WaveID[3]);printf(">> FmtID : %c%c%c%c\n", g_wave_header->FmtID[0], g_wave_header->FmtID[1], g_wave_header->FmtID[2], g_wave_header->FmtID[3]);printf(">> FmtSize : %d\n", g_wave_header->FmtSize);printf(">> wFormatTag : %d\n", g_wave_header->wFormatTag);printf(">> nChannels : %d\n", g_wave_header->nChannels);printf(">> nSamplesPerSec : %d\n", g_wave_header->nSamplesPerSec);printf(">> nAvgBytesPerSec : %d\n", g_wave_header->nAvgBytesPerSec);printf(">> nBlockAlign : %d\n", g_wave_header->nBlockAlign);printf(">> wBitsPerSample : %d\n", g_wave_header->wBitsPerSample);printf(">> DataID : %c%c%c%c\n", g_wave_header->DataID[0], g_wave_header->DataID[1], g_wave_header->DataID[2], g_wave_header->DataID[3]);printf(">> nDataBytes : %d\n", g_wave_header->nDataBytes);return fp;
}char * sctrlstr = "Digital Playback Volume";int32_t main()
{int8_t *infile = "Back_to_Earth.wav";int8_t *device = "hw:0,0";snd_pcm_t *handle;snd_pcm_hw_params_t *hwparams;WAVE_HEADER g_wave_header;snd_pcm_format_t format;uint32_t ch;uint32_t rate;snd_pcm_sframes_t period_size;int16_t *samples;int32_t music_sec;int32_t err;int32_t size;int32_t rc;FILE *fp = open_and_print_file_params(infile, &g_wave_header);if (fp == NULL){printf("open_and_print_file_params error\n");return -1;}/* set sample rate */rate = g_wave_header.nSamplesPerSec;/* set sample bit */if (8 == g_wave_header.FmtSize){format = SND_PCM_FORMAT_U8;}else if (16 == g_wave_header.FmtSize){format = SND_PCM_FORMAT_S16_LE;}else if (24 == g_wave_header.FmtSize){format = SND_PCM_FORMAT_U24_LE;}else if (32 == g_wave_header.FmtSize){format = SND_PCM_FORMAT_U32_LE;}else{printf("SND_PCM_FORMAT_UNKNOWN.\n");format = SND_PCM_FORMAT_UNKNOWN;return -1; }/* set channel */ch = g_wave_header.nChannels;/* music time */music_sec = g_wave_header.nDataBytes / g_wave_header.nAvgBytesPerSec;printf("music_time : %d : %d\n", (int32_t)music_sec / 60, music_sec % 60);printf("Playback device is %s\n", device);printf("Stream parameters are %uHz, %s, %u channels\n", rate, snd_pcm_format_name(format), ch);err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0);if (err < 0) {printf("Playback open error: %s\n", snd_strerror(err));return 0;}snd_pcm_hw_params_alloca(&hwparams);err = set_hwparams(handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED, ch, format, rate, &period_size);if (err < 0) {printf("Setting of hwparams failed: %s\n", snd_strerror(err));return 0;}size = (period_size * ch * snd_pcm_format_physical_width(format)) / 8;samples = (int16_t *)malloc(size);while (1) {rc = fread(samples, sizeof(int16_t), size, fp);if (rc == 0){printf("end of file on input\n");break;} else if (rc != size){printf("short read: read %d bytes\n", rc);}rc = snd_pcm_writei(handle, samples, size);if (rc == -EPIPE){printf("underrun occurred\n");err = snd_pcm_prepare(handle);if( err < 0){printf("can not recover from underrun: %s\n", snd_strerror(err));}} else if (rc < 0){printf("error from writei: %s\n", snd_strerror(rc));}  else if (rc != (int32_t)size){printf("short write, write %d frames\n", rc);}}if (samples != NULL){free(samples);}snd_pcm_close(handle);return 0;
}

 # arm-fsl-linux-gnueabi-gcc player.c -o player -lasound -lm -I /var/alsa/include/ -L /var/alsa/lib/


Linux/Android alsa codec音频路由dapm的配置详解

DAPM之二:audio paths与dapm kcontrol

ALSA声卡16_编写ALSA声卡应用程序_学习笔记

8.声卡驱动06-自己实现alsa驱动-虚拟声卡-widget

ALSA驱动asoc框架之machine(一)

ALSA驱动asoc框架之machine(二)

ALSA驱动asoc框架之Platform

ALSA驱动asoc框架之Codec

Linux ALSA 音频系统:物理链路篇

Linux ALSA 音频系统:逻辑设备篇


http://chatgpt.dhexx.cn/article/uEVJqx9A.shtml

相关文章

ALSA编译使用

ALSA ALSA下载alsa-lib 交叉编译alsa-utils 交叉编译alsa.confamixeramixer controlsamixer contents设置声卡获取声卡设置值使用 amixer 设置声卡使用 aplay 播放 WAV 格式音乐使用 arecord 录制音频 ALSA下载 下载alsa-lib 和 alsa-utils alsa下载地址 alsa-lib api文档地址…

ALSA 配置文件简介

参考自:asoundrc文件     asoundrc配置文件简单介绍     asound.conf 插件讲解 文章目录 1、Asoundrc1.1、什么是asoundrc文件?1.2、为什么需要asoundrc文件?1.3、asoundrc文件什么时候被加载的?2、Plugin(插件)2.1、Plugin: hw2.2、Slave 定义2.3、Plugin: Rate…

Linux ALSA 之五:ALSA Proc Info

ALSA Proc Info 一、概述二、Proc Files of Alsa Driver1、/proc/asound/xxx 简述2、创建 /proc/asound 目录树2.1 /proc/asound/version 文件2.2 /proc/asound/devices 文件2.3 /proc/asound/cards 文件2.4 /proc/asound/cardx 目录2.5 /proc/asound/pcm 文件 一、概述 Linux…

Linux ALSA 之二:ALSA 声卡与设备

ALSA 声卡与设备 一、ALSA Sound 初始化1、alsa_sound_init() 入口函数2、init_soundcore() 入口函数 二、声卡结构体与创建、注册1、struct snd_card2、声卡创建流程3、声卡创建过程使用举例 三、声卡之 Pcm 设备1、Pcm 设备简介2、ALSA Driver 的 Pcm 中间层3、Pcm 设备创建 …

ALSA音频编程

一、前序 这里了解一下各个参数的含义以及一些基本概念。 声音是连续模拟量&#xff0c;计算机将它离散化之后用数字表示&#xff0c;就有了以下几个名词术语。 样本长度(sample)&#xff1a;样本是记录音频数据最基本的单位&#xff0c;计算机对每个通道采样量化时数字比特…

alsa 驱动介绍

Machine 以装配有CS4270的一款android 智能电视的为例 /sound/soc/samsung/exynos.c Platform 以Samsung cpu exynos4412为例 /sound/soc/samsung/ Codec 以wolfson的Codec芯片cs4270为例 /sound/soc/codecs/cs4270.c ALSA 框架介绍 Alsa 太多太杂&#xff0c;很难整理的规整&a…

ALSA Configure

0. 前言 本文主要介绍alsa-lib配置文件相关代码的分析内容。 1. 配置文件的路径 在alsa-lib中&#xff0c;函数 snd_config_topdir 用于获取配置文件的路径&#xff0c;有两个方法可以进行配置&#xff1a; 使用环境变量 ALSA_CONFIG_DIR 进行配置。在生成configure时&…

ALSA应用层编程播放音乐

关于ALSA&#xff0c;网上也有介绍&#xff0c;但是我在看的时候看的也是一脸懵逼&#xff0c;不是介绍的不好&#xff0c;是因为我之前对于嵌入式软件这一块实在没什么了解&#xff0c;之前一直学的JAVA&#xff0c;整个体系跟JAVA还是有很大的区别&#xff0c;要学的也完全是…

ALSA系统简析

一 音频架构 如图所示 是 嵌入式系统的音频连接 音频编解码器将数字音频信号 转换成 扬声器播放所需要的模拟声音信号。而通过麦克风时&#xff0c;则执行相反的过程。 数字音频信号通过 PCM技术对模拟信号以某个比特率采样得到的&#xff0c;编解码器的任务就是以支持的PCM…

ALSA编程精华

https://www.cnblogs.com/cslunatic/p/3677729.html 一、前序 这里了解一下各个参数的含义以及一些基本概念。 声音是连续模拟量&#xff0c;计算机将它离散化之后用数字表示&#xff0c;就有了以下几个名词术语。 样本长度(sample)&#xff1a;样本是记录音频数据最基本的…

ALSA学习笔记

文章目录 一、概述二、系统架构三、常用操作命令1、安装ALSA2、查看音频设备3、列出音频设备4、音量控制器 四、常见问题1、cannot open mixer: 没有那个文件或目录 一、概述 ALSA&#xff08;Advanced Linux Sound Architecture&#xff09;&#xff0c;高级Linux声音架构的简…

音频ALSA架构简介

一、ALSA架构 ALSA&#xff08;Advanced Linux Sound Architecture&#xff09;即高级 Linux 声音架构。 嵌入式移动设备的音频子系统目前主要是ALSA 驱动 asoc 框架&#xff0c;其中包括 codec driver、 platform driver、 machine driver 等。 codec driver只关心 codec 本身…

Linux ALSA 之一:ALSA 架构简介

一、概述 ALSA是 Advanced Linux Sound Architecture 的缩写&#xff0c;目前已经成为了linux的主流音频体系结构。 在 Linux 内核设备驱动层&#xff0c;ALSA 提供了 alsa-driver&#xff0c;在应用层&#xff0c;ALSA 为我们提供了 alsa-lib&#xff0c;故在其支持下&#…

ALSA (高级Linux声音架构)、ASOC基础知识

目录 第一节&#xff1a;什么是ALSA和ASOC 第二节&#xff1a;ALSA框架 第三节&#xff1a;ALSA的使用 第四节&#xff1a;ASOC的硬件框架 第四节&#xff1a;ASOC的软件框架 第一节&#xff1a;什么是ALSA和ASOC ALSA是Advanced Linux Sound Architecture&#xff0c;高级…

动态链接库dlopen的函数的使用

转自&#xff1a;http://blog.const.net.cn/a/17154.htm 编译时候要加入 -ldl (指定dl库) dlopen 基本定义 功能&#xff1a;打开一个动态链接库 [喝小酒的网摘]http://blog.const.net.cn/a/17154.htm 包含头文件&#xff1a; #include <dlfcn.h> 函数定义&#xff…

dlopen的用法

1、前言 为了使程序方便扩展&#xff0c;具备通用性&#xff0c;可以采用插件形式。采用异步事件驱动模型&#xff0c;保证主程序逻辑不变&#xff0c;将各个业务已动态链接库的形式加载进来&#xff0c;这就是所谓的插件。linux提供了加载和处理动态链接库的系统调用&#xff…

织梦上一篇下一篇没有了改为英文

织梦上一篇下一篇没有了改为英文 网站根目录找到 include/arc.archives.class.php 文件 打开找到 上一篇改为 Previous上一篇后面的“没有了” 改为 No Previous原图修改后 接着放下翻&#xff0c;紧贴着下面的“下一篇&#xff0c;没有了” 找到 下一篇改为 在这里插入…

在wordpress文章页中显示上一篇和下一篇文章

查看原文&#xff1a;http://www.hellonet8.com/1162.html 今天博主在看别人博客的时候发现他们的文章末尾会有显示上一篇和下一篇的文章链接&#xff0c;所以也想在自己的博客中添加这个功能。这么做顺便可以增加文章之间的相关性&#xff0c;对搜索引擎的蜘蛛也会友好些。废话…

js 实现 点击上一篇、下一篇功能

列表界面&#xff1a; 详细界面&#xff1a; 思路&#xff1a; 1. 首先目录列表渲染的数据是通过接口调用取到的值&#xff0c;然后点击具体某一条数据的时候&#xff0c;获取到他的 ID&#xff0c;然后通过路由跳转的时候带到详细信息页面。 2. 在详细页面中&#xff0c;先再…

Vue中 实现上一篇下一篇的功能

效果&#xff1a; 看下html页面 <div class"NewsDetails_cont_footer"><!-- 使用三目运算符判断 按钮是否可以点击 --><div click"last" :class"lastNoShow ? noClick : btn"><img src"../assets/img/newsDetail/公共…