c语言madplay播放音乐函数,声卡驱动程序-xiao_yan123-ChinaUnix博客
声卡驱动程序
15年6月22日09:01:18
在linux系统中,有3种音频设备的框架:OSS,ALSA和ASoC。
(一)音频设备硬件接口
(1)PCM接口
(2)IIS接口
IIS接口最先由PHILIPS采用,在一个LRCLK的信号机制中经过多路转换,将两路音频信号变成单一的数据队列,当LRCLK为高时,左声道数据被传输,LRCLK为低时,右声道数据被传输,IIS接口适合用于立体声系统。
(3)AC‘97接口
这里的声卡传输数据用的是IIS接口。别的暂时不看。
(二)OSS标准中有两个最基本的音频设备:mixer(混音器)和dsp(数字信号处理器)。
/dev/mixer和 /dev/dsp设备文件分别是应用程序对 mixer和dsp进行操作的软件接口。
(三)2440开发板里面,mini2440和TQ2440用的是 uda1341芯片,JZ2440用的是wm8976芯片。具体可以去看电路原理图。其中这两个芯片都用IIS接口来传输数据,并且IIS接口只是用来传输声音数据,而这两者的控制接口不同,其中,UDA1341用L3接口来控制,wm8976芯片用I2C或者3线接口来控制。
先讲 uda1341芯片,在内核中有对于uda1341的支持,详见s3c2410-uda1341.c。
在s3c2410_uda1341_init函数中,用driver_register(&s3c2410iis_driver);来向内核注册驱动程序。在s3c2410iis_driver 这个结构体中,如果名字对应的话,将要调用probe函数。
在probe函数中,比较重要的函数有以下几个:
init_s3c2410_iis_bus();
init_uda1341();
audio_dev_dsp = register_sound_dsp(&smdk2410_audio_fops, -1);
audio_dev_mixer = register_sound_mixer(&smdk2410_mixer_fops, -1);
int register_sound_mixer(const struct file_operations *fops, int dev);
上述函数用于注册一个混音器,第一个参数fops是 file_operations结构体,第二个参数dev是设备编号,如果填入-1,则系统自动分配一个设备编号。mixer是一个典型的字符设备,因此编码的主要工作是用来实现 file_operations结构体中的open(), ioctl()等函数。
int register_sound_dsp(const struct file_operations *fops, int dev);
上述函数用于注册一个dsp设备,第一个参数fops是 file_operations结构体,第二个参数dev是设备编号,如果填入-1,则系统自动分配一个设备编号。编码的主要工作是实现 file_operations结构体中的read(), write(), ioctl()等函数。
(四)OSS用户空间编程。
(四.1)dsp编程:
(1)打开设备文件/dev/dsp。
(2)如果有需要,设置缓冲区大小。调用ioctl()函数来对它的尺寸进行恰当的设置。一般默认即可。
(3)设置声道数量。可以设置为单声道和立体声。
(4)设置采样格式和采样频率。
(5)读/dev/dsp实现录音, 写/dev/dsp实现播放。
(四.2)mixer编程:对混音器的操作一般通过ioctl()系统调用来完成,所以的控制命令都以SOUND_MIXER或者MIXER开头。
对声卡的输入增益和输出增益进行调节是混音器的一个主要作用,目前大部分声卡采用的是8位或者16位的增益控制器,声卡驱动程序会将他们变换成百分比的形式,也就是说无论是输入增益还是输出增益,其取值范围都是0~100。
(五)关于这部分的讲解,还是看笔记吧:
(六)下面写wm8976的驱动程序:
就在uda1341驱动程序上面修改,看笔记可以知道,iis部分相同,只需要写出控制部分即可。
修改probe函数里面的 init_wm8976(void)函数。
写这个函数需要用到写寄存器函数,先将这个函数写出来:
static void wm8976_write_reg(unsigned char reg, unsigned int data)
{
int i;
unsigned long flags;
unsigned short val = (reg << 9) | (data & 0x1ff);
s3c2410_gpio_setpin(S3C2410_GPB2,1);
s3c2410_gpio_setpin(S3C2410_GPB3,1);
s3c2410_gpio_setpin(S3C2410_GPB4,1);
local_irq_save(flags);
for (i = 0; i < 16; i++)
{
if (val & (1 << 15))
{
s3c2410_gpio_setpin(S3C2410_GPB4,0);
s3c2410_gpio_setpin(S3C2410_GPB3,1);
udelay(1);
s3c2410_gpio_setpin(S3C2410_GPB4,1);
}
else
{
s3c2410_gpio_setpin(S3C2410_GPB4,0);
s3c2410_gpio_setpin(S3C2410_GPB3,0);
udelay(1);
s3c2410_gpio_setpin(S3C2410_GPB4,1);
}
val = val << 1;
}
s3c2410_gpio_setpin(S3C2410_GPB2,0);
udelay(1);
s3c2410_gpio_setpin(S3C2410_GPB2,1);
s3c2410_gpio_setpin(S3C2410_GPB3,1);
s3c2410_gpio_setpin(S3C2410_GPB4,1);
local_irq_restore(flags);
}
这个函数就是参考图3的时序图写出来的。
static void init_wm8976(void)
{
uda1341_volume = 57;
uda1341_boost = 0;
/* software reset */
wm8976_write_reg(0, 0);
wm8976_write_reg(0x3, 0x6f);
wm8976_write_reg(0x1, 0x1f);//biasen,BUFIOEN.VMIDSEL=11b
wm8976_write_reg(0x2, 0x185);//ROUT1EN LOUT1EN, inpu PGA enable ,ADC enable
wm8976_write_reg(0x6, 0x0);//SYSCLK=MCLK
wm8976_write_reg(0x4, 0x10);//16bit
wm8976_write_reg(0x2B,0x10);//BTL OUTPUT
wm8976_write_reg(0x9, 0x50);//Jack detect enable
wm8976_write_reg(0xD, 0x21);//Jack detect
wm8976_write_reg(0x7, 0x01);//Jack detect
}
(七)写出来以后,需要测试声卡驱动程序能不能用:
测试WM8976:
1. 确定内核里已经配置了sound\soc\s3c24xx\s3c2410-uda1341.c
-> Device Drivers
-> Sound
-> Advanced Linux Sound Architecture // 兼容OSS
-> Advanced Linux Sound Architecture
-> System on Chip audio support
I2S of the Samsung S3C24XX chips
2. 修改sound/soc/s3c24xx/Makefile
obj-y += s3c2410-uda1341.o
改为:
obj-y += s3c-wm8976.o
3. make uImage
使用新内核启动
4. ls -l /dev/dsp /dev/mixer
5. 播放:
在WINDOWS PC里找一个wav文件,放到开发板根文件系统里
cat Windows.wav > /dev/dsp
6. 录音:
cat /dev/dsp > sound.bin
然后对着麦克风说话
ctrl+c退出
cat sound.bin > /dev/dsp // 就可以听到录下的声音
使用madplay测试声卡:
1. 解压:
tar xzf libid3tag-0.15.1b.tar.gz // 库
tar xzf libmad-0.15.1b.tar.gz // 库
tar xzf madplay-0.15.2b.tar.gz // APP
2. 编译 libid3tag-0.15.1b
mkdir tmp
cd libid3tag-0.15.1b
./configure --host=arm-linux --prefix=/work/drivers_and_test/21th_sound/tmp CPPFLAGS=-I/work/drivers_and_test/21th_sound/tmp/include LDFLAGS=-L/work/drivers_and_test/21th_sound/tmp/lib
make
make install
/* 在编译这个的过程中,需要先安装zlib库,参考网上的一个帖子安装的,那个帖子也复制下来了 */
3. 编译 libmad-0.15.1b
cd libmad-0.15.1b
./configure --host=arm-linux --prefix=/work/drivers_and_test/21th_sound/tmp
make
make install
4. 编译madplay
cd madplay-0.15.2b/
d./configure --host=arm-linux --prefix=/work/drivers_and_test/21th_sound/tmp LDFLAGS="-L/work/drivers_and_test/21th_sound/app/tmp/lib" CFLAGS="-I /work/drivers_and_test/21th_sound/app/tmp/include"
make
make install
5. 把tmp/bin/* tmp/lib/*so* 复制到根文件系统:
6. 把一个mp3文件复制到根文件系统
7. madplay --tty-control /1.mp3
播放过程中不断按小键盘的减号("-")会降低音量
不断按小键盘的加号("+")会降低音量
阅读(799) | 评论(0) | 转发(0) |
c语言madplay播放音乐函数,声卡驱动程序-xiao_yan123-ChinaUnix博客相关推荐
- c并非所有的代码路径都返回值_两行C语言代码播放音乐,就这么so easy!你学到了吗?...
函数介绍 为了实现用C语言播放音乐,我们需要用到windows的一个API,mciSendString. 函数原型为: MCIERROR mciSendStringA( LPCSTR lpstrCom ...
- C/C++里面使用loadimage导入图片和使用miSendString播放音乐函数运行不显示图片不播放音乐的解决问题
1.查看图片格式是否与代码里面的一样是否已.jpe. jpeg.png等图片后缀名,可以选种图片右键属性查看.(https://img-blog.csdnimg.cn/3bbe80f956324a9e ...
- 乐乐音乐:Android音乐播放器及动感(KTV)歌词相关博客汇总
相关简介 Java Swing PC版本乐乐音乐播放器 乐乐音乐PC播放器单机版本,支持ape,wav,flac,mp3等多种格式,支持动态ksc.hrc.krc歌词文件和支持和显示翻译歌词和音译歌词 ...
- php bloginfo templatedirectory,WordPress函数:bloginfo(显示博客信息)
描述 显示你的博客信息,大部分都是显示WordPress管理界面的 用户资料 和 常规设置 中的信息.它可以在模板文件的任何地方使用.一般 bloginfo() 都是用来直接在浏览器中输出内容的.如果 ...
- c语言调用鼠标驱动函数,鼠标驱动程序
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 #include #include #include #include #include #include "graphics.h" ...
- c语言每轮for循环初始化i,十三.Linux博客-2016年8月18日while、for特殊用法、selet循环与菜单、函数...
格式说明: 操作 概念 命令 说明及举例 十三.while.for特殊用法.selet循环与菜单.函数 while特殊用法 while循环的特殊用法(遍历文件的每一行): while read lin ...
- c语言 dec2oct函数,【Excel函数】DEC2OCT函数 - 曹海峰个人博客
本文介绍Microsoft Excel中DEC2OCT函数的语法和用法. DEC2OCT函数适用于:Excel2003.Excel2007.Excel2010.Excel2013.Excel2016. ...
- C语言中的转义字符【转ce123的技术博客】
C语言中的转义字符 简介 在字符集中,有一类字符具有这样的特性:当从键盘上输入这个字符时,显示器上就可以显示这个字符,即输入什么就显示什么.这类字符称为可显示字符,如a.b.c.$.+和空格符等都是可 ...
- matlab2张图用蒙太奇函数,我想在论坛博客上贴图
推荐你使用拍拍乐万能贴 介绍下: 1. 第一个完全使用客户端进行高效稳定管理的网络相册2.0平台 相册管理全部使用客户端实现,其它人知道相册URL地址后直接查看. 支持拖动式的图片批量高速上传. 支持 ...
最新文章
- springboot 日志 log4j
- 多线程Java Socket编程示例(转)
- 使用internal(com.android.internal)和hidden(@hide)APIs – Part 5
- 士兵杀敌(二)(线段树+树状数组)
- [深度学习]人脸检测-Tensorflow2.x keras代码实现
- 原始套接字与抓包过滤规则setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, ...)
- 63.Linux/Unix 系统编程手册(下) -- 其他备选的IO模型
- 《硅谷钢铁侠》---- 读书笔记
- 超级好用的KeyBoard WPF软键盘
- Fiddler抓包配置
- MacBook Pro M1 安装 VMware Fusion 及 CentOS 8
- 清华大学计算机考研经历,2020清华大学计算机考研经验,相信梦想的力量
- 143578-65-8,CYCLO(-D-PHE-HIS-TRP-ALA-VAL-GLY-HIS-LEU-LEU)
- java计算机毕业设计吉他库存管理源码+mysql数据库+系统+lw文档+部署
- 深入理解iOS App的启动过程
- 西门子博图PLC程序无法下载到PLCSIM
- Life feelings--10--inspiration and inner motivation
- 俏江南“倒闭”真相:对员工好坏,直接决定了企业的生死!
- 计算机道德导论,道德哲学导论.PDF
- Chrome浏览器不提示保存密码了怎么办?
热门文章
- (附源码)计算机毕业设计SSM基于vue的图书管理系统2022
- JUnit5学习之三:Assertions类,2021年一起努力应对互联网寒冬吧
- 腾讯员工似乎不喜欢mateXS,刚到手就在闲鱼抛售
- Ionic2的发布模式和开发模式,--prod参数
- C# /.net 返回上一级目录
- 描述时序的好帮手——UML序列图
- 第七章:vector类
- windows7光驱找不到的解决办法
- Using a physical whiteboard is more effective than virtual tools in the stand-up meeting.
- Django零基础(三)