针对特定的开发板,ALSA内核中的ASoC通过codec class、platform class和machine class完成开发板上的硬件驱动,对接到ALSA中,供应用层调用。为了方便用户使用ALSA的功能,ALSA提供了alsa-lib供用户使用。
1 alsa-lib简介
alsa-lib是ALSA驱动的接口函数库,开发者通过调用接口函数可以直接调用ALSA的接口实现自身的应用需求。
2 alsa-lib的安装
alsa-lib属于独立的模块,不包含在内核代码中,需要额外安装。首先在官网下载alsa-lib的源码。
将下载的源码解压
tar -vxjf alsa-lib-1.2.13.tar.bz2
进入解压出来的文件夹,对源码进行配置
cd alsa-lib-1.2.13
./configure --host=aarch64-none-linux-gnu --prefix=/home/ept/alsalib --with-configdir=/usr/share/alsalib
--host指定编译使用的交叉编译器,--prefix指定存放编译好的lib文件,--with-configdir指定系统配置文件夹。完成上述操作后,执行编译和安装指令
make
sudo make install
安装完成后在--prefix指定的文件夹中lib文件夹中,有一个pkgconfig文件夹,其中的文件是用于管理alsa-lib库的。在PKG_CONFIG_PATH
环境变量中添加这一pkgconfig的路径。这样在makefile中就可以引用alsa-lib库。
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/home/ept/elf2fs/lib/pkgconfig
export PKG_CONFIG_PATH
至此,完成了alsa-lib的开发环境的安装。
3 alsa-lib应用程序
使用alsa-lib库编写程序,实现播放音乐的功能。
下面是程序源码
#include <stdio.h>
#include <stdlib.h>
#include <alsa/asoundlib.h>
int main(int argc, char *argv[])
{
int i;
int err;
int buf[128];
snd_pcm_t *playback_handle;
snd_pcm_hw_params_t *hw_params;
FILE *fin;
size_t nread;
unsigned int rate = 44100;
if (argc != 3) {
fprintf(stderr, "Usage: %s card file\n", argv[0]);
exit(1);
}
if ((err = snd_pcm_open (&playback_handle, argv[1], SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
fprintf (stderr, "cannot open audio device %s (%s)\n",
argv[1],
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params_any (playback_handle, hw_params)) < 0) {
fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params_set_access (playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
fprintf (stderr, "cannot set access type (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params_set_format (playback_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
fprintf (stderr, "cannot set sample format (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params_set_rate_near (playback_handle, hw_params, &rate, 0)) < 0) {
fprintf (stderr, "cannot set sample rate (%s)\n",
snd_strerror (err));
exit (1);
}
printf("Rate set to %d\n", rate);
if ((err = snd_pcm_hw_params_set_channels (playback_handle, hw_params, 2)) < 0) {
fprintf (stderr, "cannot set channel count (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params (playback_handle, hw_params)) < 0) {
fprintf (stderr, "cannot set parameters (%s)\n",
snd_strerror (err));
exit (1);
}
snd_pcm_hw_params_free (hw_params);
if ((fin = fopen(argv[2], "r")) == NULL) {
fprintf(stderr, "Can't open %s for reading\n", argv[2]);
exit(1);
}
while ((nread = fread(buf, sizeof(int), 128, fin)) > 0) {
if ((err = snd_pcm_writei (playback_handle, buf, nread)) != nread) {
fprintf (stderr, "write to audio interface failed (%s)\n",
snd_strerror (err));
snd_pcm_prepare(playback_handle);
}
}
snd_pcm_drain(playback_handle);
snd_pcm_close (playback_handle);
exit (0);
}
makefile文件
CC = aarch64-none-linux-gnu-gcc
LDLIBS = $(shell pkg-config --libs alsa) -lm
CFLAGS = -g $(shell pkg-config --cflags alsa)
SRC = alsa_playback.c
EXE = alsa_playback
all : $(EXE)
执行make指令后即可得到可执行文件alsa_playback
4 应用程序测试
通过FileZilla使用FTP传输编译好的alsa_playback和测试使用的test2.wav文件到开发板,执行下列脚本指令。开发板外接音箱后即可播放音乐。
./alsa_playback hw:1 /usrdata/media/audio/test2.wav
附件为程序源码、可执行文件以及测试音频文件,可以直接在开发板上运行可执行文件。
*附件:07.7z