关于ALSA,网上也有介绍,但是我在看的时候看的也是一脸懵逼,不是介绍的不好,是因为我之前对于嵌入式软件这一块实在没什么了解,之前一直学的JAVA,整个体系跟JAVA还是有很大的区别,要学的也完全是我之前没了解过的,所以以下有说错的请及时纠正。

功能

实现在linux中通过编程.C文件播放一个.wav格式的音频文件

播放: 将音频文件进行解码(Decode)生成PCM数据, 并将其送入音频设备中播出.

录音: 本程序暂时不涉及录音功能

ALSA

关于ALSA我不过多介绍,这篇笔记主要是记录我如何成功播放音乐,主要是怕误导别人,在我看来就是向上提供了接口供我们使用,向下控制了硬件播放音乐,跟JAVA中的JDK提供的接口函数类似,你只管使用就可以了。

  • Linux ALSA声卡驱动之一:ALSA架构简介

还有一个是ALSA的官方的教程好像是,播放音乐整体顺序我也是参考的这篇文章来写的。

  • ALSA Programming HOWTO

术语

关于ALSA中有一些术语着实是让我懵逼的一批,有几个术语我到现在还不知道理解的对不对,所以在正式编程之前一定要先知道,等自己编程的时候再理解一下。

因为声音是连续模拟量,计算机将它离散化之后用数字表示,就有了以下几个名词术语

  • 样本长度(sample):样本是记录音频数据最基本的单位,计算机对每个通道采样量化时数字比特位数,常见的有8位和16位。

这个样本长度后面编程时会用到的,按照字面意思理解的话,就是取出来8bit或者16bit的数据做样本;就理解成一个样本就可以,只不过一个样本的大小是8bit或者16bit,或者其他大小。

  • 通道(channel):该参数为1表示单声道,2则是立体声。

这个术语也好理解,单声道应该就是只有一个左耳机或右出声音,而立体就是左右耳机都出声的意思;每一个通道都有一个样本长度,单声道的数据就是一个样本长度(样本),立体声道的话2个样本长度(样本)。

  • 帧(frame):帧记录了一个声音单元,其长度为样本长度与通道数的乘积,一段音频数据就是由苦干帧组成的。

帧单位,把所有通道中的数据加在一起叫做一帧,所以单声道:一帧 = 样本长度 * 1;双声道:一帧 = 样本长度 * 2

  • 采样率(rate):每秒钟采样次数,该次数是针对帧而言,常用的采样率如8KHz的人声,44.1KHz的mp3音乐, 96Khz的蓝光音频。

这个在编程时也比较好设置,没什么混淆的,固定的值也就那么几个,一般没有随便乱设置的数值

  • 周期(period):音频设备一次处理所需要的桢数,对于音频设备的数据访问以及音频数据的存储,都是以此为单位。

一个周期用来存放若干个帧的单元,ALSA函数是以一个周期为单位来读取音频数据的,其实这个周期现在我也没很好的理解到底什么个意思,
是说ALSA向硬件输入数据时,是以时间为周期,在这个时间周期中输入若干个帧呢?
还是说就是一个固定存储空间大小叫做周期,然后这个周期大小的空间放入若干个帧? 真是让人头大!!!!!!!

  • 缓冲区(buffer): 用来存放将要被输入到硬件的数据,我这么理解也不知道对还是不对

一个缓冲区一般有两个周期,缓冲区是循环读取的,比如一个缓冲区有两个周期,那么硬件在读取一个缓冲区时便会产生两次中断,当第一个周期的音频数据被取走就准备取第二个周期的音频数据,同时第三个周期的音频数据会填充到第一个音频数据的位置,以此循环

  • 交错模式(interleaved):是一种音频数据的记录方式,分为交错模式和非交错模式

交错模式与非交错模式只是音频数据存放在缓冲区时的一种方式,
在交错模式下,数据以连续桢的形式存放,即首先记录完桢1的左声道样本和右声道样本(假设为立体声格式),再开始桢2的记录。
而在非交错模式下,首先记录的是一个周期内所有桢的左声道样本,再记录右声道样本,数据是以连续通道的方式存储。

看到上面的术语真是让人头大,但是不理解这些,等编程的时候也是瞎子摸象–一通乱摸,所以务必要先理解了这些术语,如果实在看不下去这术语,可以编程的时候走到哪一步时再回过来一一对照理解也可以。

ALSA编程

在用户空间使用ALSA需要安装依赖

alsa-lib: 用户空间函数库, 封装驱动提供的抽象接口, 通过文件libasound.so提供API给应用程序使用

alsa-utils: 实用工具包,通过调用alsa-lib实现播放音频(aplay)、录音(arecord) 等工具

安装

ubuntu 安装

$ sudo apt-get update
$ sudo apt-get install alsa-lib alsa-utils

Arch 安装

$ sudo pacman -Sy alsa-lib alsa-utils glibc

安装好以后需要运行 aplay -l 确认当前用户可以使用声卡设备

$ aplay -l

如果没有显示图片中的内容,可以切换到root用户试一下,或者把当前用户加入到音频组也可以

$ gpasswd -a [user_name] audio
# 记得注销一下,或者切换用户后再切换回来,通过下面的命令可以查看当前用户是否已经加入audio组
$ groups [user_name]
# 再运行查看声卡设备是否有了
$ aplay -l

编程

代码我已经上传到github,可自行下载后运行。

  • GIthub ALSA 源码

文件分为:

  • Makefile:make 的配置文件
  • 1.wav:音频文件
  • alsa-myself-rw-wav-file-paly-music.c:C源码文件
  • const.h:C头文件

C源码文件中我每一步都有注释,使用的函数都可以在参考中的函数接口文档中找到。

在源码中我有一些自己的理解,如果觉得我的注释对你起不到辅助作用可以删除。

buff_size 和 frame 的关系

alsa中有这么两个函数 snd_pcm_hw_params_set_buffer_size函数 和 snd_pcm_writei 函数,在这之前我对这两个函数的第三个参数就特别混淆,不知道该设置什么,现在我有点明白了

首先这两个函数的第三个参数都是传入以 帧 为单位的值,所以根本就是同一个值,第一个函数设置的是每次硬件可以向多大的缓存中拿数据,第二个是应用层向多大的缓存输入多少数据,这里的数据都是 帧,所以我输入的就是你拿的数据,那可不就是一个东西嘛

所以buff_size大小就无所谓了,通常为 buffer_size = period_size * periods

最主要的是第三个参数frame如何计算,也特别好计算,就好像 RMB和美元的换算是一个道理

buffer_size = RMB

frame(帧) = 美元

钱的是1:7,在计算机中按照字节换算,首先要知道一帧(frame)等于到少字节,才能换算,以下使用16bit采样长度换算,如果是其他采样长度换掉采样长度即可。

# 这里除以8 是因为 1字节 = 8bit
1 帧(frame) = 采样长度 * 通道数 = 16 * 2 / 8 = 4
# 知道一帧的大小后,就可以计算总共的帧大小了,右移两位相当于除以4
frames = buffer_size >> 2;

经过计算的frames 就是要传入两个函数的第三个参数的值了。

使用

我自己是在树莓派4上编译使用的,进入到文件夹后,直接运行 make 命令即可在本目录出现可执行文件 alsa

$ git clone https://github.com/ywhs/rpi-arm64.git
$ cd ALSA
$ make
# -m 参数的意思音乐文件,-f 是术语中提到的样本长度,-r 是术语中提到的采样率
$ ./alsa -m 1.wav -f 161 -r 44
# 161 是 S16_LE 162 是 S16_BE,以此类推,或者直接运行 ./alsa 查看都可以设置什么值
$ ./alsa
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Either 1'st, 2'nd, 3'th or all parameters were missing 1'st : -m [music_filename] music_filename.wav 2'nd : -f [format 241bit or 16bit or 32bit] 161 for S16_LE, 162 for S16_BE 241 for S24_LE, 242 for S24_BE 2431 for S24_3LE, 2432 for S24_3BE 321 for S32_LE, 322 for S32_BE 3'th : -r [rate,44 or 88] 44 for 44100hz 82 for 88200hz For example: alsa -m 1.wav -f 161 -r 44
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++

一般不报错的话把耳机插入树莓派的耳机插口就可以听到音乐了

参考

  • ALSA project C 函数接口文档
  • Linux音频编程

ALSA应用层编程播放音乐相关推荐

  1. linux内核之alsa,Linux操作系统Alsa音频编程

    一.前序 这里了解一下各个参数的含义以及一些基本概念. 声音是连续模拟量,计算机将它离散化之后用数字表示,就有了以下几个名词术语. 样本长度(sample):样本是记录音频数据最基本的单位,计算机对每 ...

  2. alsa 音频编程简单的例子 (总结)

    1.源代码安装alsa 库,否则编译例子不会通过.原文引用http://apps.hi.baidu.com/share/detail/17289294 2.编译简单的播放和录音的例子.   引用原文h ...

  3. alsa声音编程介绍

    http://blog.csdn.net/q553716434/article/details/7881552 period(周期):硬件中中断间的间隔时间.它表示输入延时. 声卡接口中有一个指针来指 ...

  4. c并非所有的代码路径都返回值_两行C语言代码播放音乐,就这么so easy!你学到了吗?...

    函数介绍 为了实现用C语言播放音乐,我们需要用到windows的一个API,mciSendString. 函数原型为: MCIERROR mciSendStringA( LPCSTR lpstrCom ...

  5. armbian 斐讯n1_尝试使用斐讯N1在armbian终端下播放音乐

    十年前刚开始玩linux的时候,记得用mocp和mplayer在linux终端下播放音乐和视频装过比,现在突然记起这些东西,想在N1上尝试下. N1刷的armbian5.67版本,无桌面,纯终端. 先 ...

  6. 基于arduino的火焰报警蜂鸣器播放音乐(外部中断)实验

    接线 按钮------D3 火焰传感器---D2 蜂鸣器-----D7 led灯-----D13 编程思路及目的 利用火焰传感器检测火焰,然后播放音乐,如果中途有人按下按钮,则停止音乐. 主程序 #i ...

  7. python写音乐_你想过用代码来写音乐吗?我用业余时间开发的一个可以编程写音乐的python库(一)...

    最近几个月学业繁忙,但是业余时间自己开发了很多python库,内容包括数学统计,各种游戏,还有音乐等等.其实还有试着写AI方面的,但是目前还是初期进度.今天我想先介绍一下我正在开发中的一个可以编程写音 ...

  8. 【FPGA】五、蜂鸣器播放音乐

    文章目录 前言 一.蜂鸣器简介 二.音频音符简介 三.任务要求 四.程序设计 1.设计思路 2.程序代码 总结 前言 蜂鸣器(Buzzer)是现代常用的一种电子发声器,主要用于产生声音信号.它是一种一 ...

  9. iPhone开发播放音乐与按钮声音

    1.背景音乐播放,支持mp3格式 循环播放长音乐. 这种播放音乐的方式导入框架#import <AVFoundation/AVFoundation.h>: NSString *musicF ...

最新文章

  1. 16~40K | 星猿哲科技招聘3D视觉算法工程师
  2. for表达式的语句执行顺序?
  3. Oracle发布Solaris 11 for Sparc/x86
  4. 联合利华搭上阿里云数据中台 精准营销新客提升2倍
  5. [Hadoop in China 2011] 华为 - NoSQL/NewSQL在传统IT产业的机遇和挑战
  6. 探索比特币源码4-JSON-RPC接口的其他调用方法
  7. MATLAB 三路频分复用通信系统
  8. java冒泡排序经典代码6_经典排序算法之冒泡排序
  9. mui 多文件上传至spring mvc 服务器
  10. chromedriver 与 chrome 版本对照表
  11. lingo入门教程之三 --- 文件数据处理
  12. java在线学习系统、基于javaweb的线上智能教育、ssm实现web版本学生在线学习考试、题库管理系统
  13. Linux cmd 常用快捷键(自用)
  14. 分享一个很容易实现的某大学的结构光源码【DIY自己的三维扫描仪】
  15. 美通社日历 | 媒体关注、会展信息、企业财报发布,节假日备忘(12月21日—12月27日)...
  16. lm75b 读取温度 c语言,STC单片机读取LM75A温度的代码,以及ADC读取电压。给大家分享一下把...
  17. 非科班、跨行业的如何走前端这条路?
  18. 委外采购订单 Subcontract PO
  19. php 鼠标 移动 手型,css各种手型集合(css禁止手型)
  20. Java项目:CRM客户关系管理系统(Spring+SpringMVC+MyBatis + maven)

热门文章

  1. CAS: 1260119-01-4, NO2-UIO-66, UIO-66-NO2
  2. 为什么运动控制器比PLC好?
  3. 且让我用花香润笔,用暖阳做墨
  4. 分布式电商项目 谷粒商城 学习笔记<2>
  5. 新氧在“看脸的时代”用精细化运营赋能医美产业
  6. JVM-整体结构深度解析(2)
  7. sklearn中的决策树(回归)
  8. C/C++重要知识点
  9. MSYS2 瘦身小攻略
  10. 用户登录之SHA1加密