使用 ALSAlib 播放 wav
在 ARM 2440 开发板上正常播放 16bit 44100 采样率的wav , 为了程序简单,没有判断返回值。
补充,在 ubunto 上也能正常播放。

编译方法: arm-linux-gcc -lasound wplay.c -o wplay 或在 ubuntu 上编译 gcc -lasound wplay.c -o wplay
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <alsa/asoundlib.h>
#ifndef WORD
#define WORD unsigned short
#endif #ifndef DWORD
#define DWORD unsigned int
#endif struct RIFF_HEADER
{
char szRiffID[]; // 'R','I','F','F'
DWORD dwRiffSize;
char szRiffFormat[]; // 'W','A','V','E'
}; struct WAVE_FORMAT
{
WORD wFormatTag;
WORD wChannels;
DWORD dwSamplesPerSec;
DWORD dwAvgBytesPerSec;
WORD wBlockAlign;
WORD wBitsPerSample;
}; struct FMT_BLOCK
{
char szFmtID[]; // 'f','m','t',' '
DWORD dwFmtSize;
struct WAVE_FORMAT wavFormat;
}; struct DATA_BLOCK
{
char szDataID[]; // 'd','a','t','a'
DWORD dwDataSize;
}; void read_wav(unsigned char *wav_buf, int *fs, int *channels, int *bits_per_sample, int *wav_size, int *file_size)
{
struct RIFF_HEADER *headblk;
struct FMT_BLOCK *fmtblk;
struct DATA_BLOCK *datblk; headblk = (struct RIFF_HEADER *) wav_buf;
fmtblk = (struct FMT_BLOCK *) &headblk[];
datblk = (struct DATA_BLOCK *) &fmtblk[]; *file_size = headblk->dwRiffSize; //采样频率
*fs = fmtblk->wavFormat.dwSamplesPerSec; //通道数
*channels = fmtblk->wavFormat.wChannels; *wav_size = datblk->dwDataSize;
//采样bit数 16 24
*bits_per_sample = fmtblk->wavFormat.wBitsPerSample;
} int main(int argc, char ** argv)
{
int fs, channels, bits_per_sample, wav_size, file_size;
unsigned char *wav_buf;
unsigned char *audio_buf;
unsigned char *audio_p;
int fd;
struct stat stat; int size;
snd_pcm_t *playback_handle;
snd_pcm_hw_params_t *hw_params;//硬件信息和PCM流配置 snd_pcm_uframes_t chunk_size = ;
unsigned int rate;
snd_pcm_format_t format; if( != argc)
{
printf("usage:%s wav file\n", argv[]);
return -;
} fd = open(argv[], O_RDONLY);
fstat(fd, &stat);
wav_buf = mmap(NULL, stat.st_size, PROT_READ, MAP_SHARED, fd, );
read_wav(wav_buf, &fs, &channels, &bits_per_sample, &wav_size, &file_size);
printf("wav format: fs = %d, channels = %d, bits_per_sample = %d, wav_size = %d file_size = %d\n\r", fs, channels, bits_per_sample, wav_size, file_size); //真实wav 跳过头部
audio_buf = wav_buf + sizeof(struct RIFF_HEADER) + sizeof(struct FMT_BLOCK) + sizeof(struct DATA_BLOCK); rate = fs;
//初始化声卡
//1. 打开PCM,最后一个参数为0意味着标准配置
if ( > snd_pcm_open(&playback_handle, "default", SND_PCM_STREAM_PLAYBACK, ))
{
printf("snd_pcm_open err\n");
return -;
}
//2. 分配snd_pcm_hw_params_t结构体
if( > snd_pcm_hw_params_malloc (&hw_params))
{
printf("snd_pcm_hw_params_malloc err\n");
return -;
}
//3. 初始化hw_params
if( > snd_pcm_hw_params_any (playback_handle, hw_params))
{
printf("snd_pcm_hw_params_any err\n");
return -;
}
//4. 初始化访问权限
if ( > snd_pcm_hw_params_set_access (playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED))
{
printf("snd_pcm_hw_params_any err\n");
return -;
}
//5. 初始化采样格式SND_PCM_FORMAT_U8,8位
if( == bits_per_sample)
{
if ( > snd_pcm_hw_params_set_format (playback_handle, hw_params, SND_PCM_FORMAT_U8))
{
printf("snd_pcm_hw_params_set_format err\n");
return -;
}
format = SND_PCM_FORMAT_U8;
} if( == bits_per_sample)
{
if ( > snd_pcm_hw_params_set_format (playback_handle, hw_params, SND_PCM_FORMAT_S16_LE))
{
printf("snd_pcm_hw_params_set_format err\n");
return -;
}
format = SND_PCM_FORMAT_S16_LE;
}
//6. 设置采样率
if ( > snd_pcm_hw_params_set_rate_near (playback_handle, hw_params, &rate, ))
{
printf("snd_pcm_hw_params_set_rate_near err\n");
return -;
}
//7. 设置通道数量
if ( > snd_pcm_hw_params_set_channels(playback_handle, hw_params, ))
{
printf("snd_pcm_hw_params_set_channels err\n");
return -;
} //8. 设置hw_params
if ( > snd_pcm_hw_params (playback_handle, hw_params))
{
printf("snd_pcm_hw_params err\n");
return -;
} snd_pcm_hw_params_get_period_size(hw_params, &chunk_size, ); snd_pcm_hw_params_free (hw_params);
if ( > snd_pcm_prepare (playback_handle))
{
printf("snd_pcm_prepare err\n");
return -;
}
//chunk_size = ?;
printf("chunk_size:%ld \n", chunk_size);
audio_p = audio_buf;
while((audio_p - audio_buf) <= stat.st_size)
{
snd_pcm_writei(playback_handle, audio_p, chunk_size);
audio_p += chunk_size * ; //16位 双声道
}
printf("play ok \n");
snd_pcm_close(playback_handle);
return ;
}
使用 ALSAlib 播放 wav的更多相关文章
- C#播放wav文件
C#使用HWQPlayer类播放wav文件 类的代码: using System.IO; using System.Runtime.InteropServices; namespace HoverTr ...
- python 播放 wav 文件
未使用其他库, 只是使用 pywin32 调用系统底层 API 播放 wav 文件. # Our raison d'etre - playing sounds import pywintypes im ...
- MmSystem播放Wav格式声音
//MmSystem播放Wav格式声音 //MmSystem 支持 *.wav声音格式 snd ->SoundRecorderuses MmSystem; //引用MmSystem//播放系统声 ...
- 1.1.6-学习Opencv与MFC混合编程之---播放WAV音乐和 alpha融合功能
源代码:http://download.csdn.net/detail/nuptboyzhb/3961698 Alpha融合菜单项 1. 增加alpha融合菜单项,修改相应的属性,建立类向导 ...
- 多浏览器播放wav格式的音频文件
html5的audio标签只在火狐下支持wav格式的音频播放,无法兼容IE和google , 使用audioplayer.js 基本上能支持大部分浏览器播放wav音频文件,经测试IE.火狐.googl ...
- WinAPI: sndPlaySound - 播放 wav 文件
WinAPI: sndPlaySound - 播放 wav 文件 //声明: sndPlaySound( lpszSoundName: PChar; {声音文件} uFlags: UINT{播 ...
- C++播放wav音乐和音效
1. #include <mmsystem.h>#pragma comment(lib,"winmm.lib")PlaySound(TEXT("c:\\te ...
- 用 Qt 的 QAudioOutput 类播放 WAV 音频文件
用 Qt 的 QAudioOutput 类播放 WAV 音频文件 最近有一个项目,需要同时控制 4 个声卡播放不同的声音,声音文件很简单就是没有任何压缩的 wav 文件. 如果只是播放 wav 文件, ...
- 8086汇编语言 调用声卡播放wav文件(sound blaster)
开更 大概最后做了一个能播放无损音乐(无压缩.不需解码)的播放器 原理是基于dosbox的模拟声卡,通过硬件之间的相互通讯做到的 关于详细内容接下来再讲. 一.从dosbox入手 我们知道cpu可以直 ...
随机推荐
- 对kotlin和java中的synchronized的浅谈
synchronized在java中是一个关键字,但是在kotlin中是一个内联函数.假如分别在java和kotlin代码锁住同一个对象,会发生什么呢,今天写了代码试了试.首先定义people类 12 ...
- CentOS换yum源和epel源为国内源
CentOS换源 YUM源 备份原来的repo文件 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bac ...
- perf4j+logback配置 非spring 可使用注解
最近项目打算使用perf4j进行性能监控,由于项目没有使用spring,而又不想对代码入侵过高,打算使用注解的方式进行接入.perf4j采用AspectJ库实现AOP. 具体接入方法如下: logba ...
- IoC容器设计
本文主要摘录于 Spring技术内幕-深入即系Spring架构和设计原理(许文柯著). IoC是根据两个核心BeanFactory和ApplicationContext来设计的,这里先放一张Spri ...
- Docker 安装 CentOS
Docker 安装 CentOS CentOS(Community Enterprise Operating System)是 Linux 发行版之一,它是来自于 Red Hat Enterprise ...
- get 传中文,可以通过下面这种方式
window.location.href=encodeURI("<%=path%>/XXX.XXX?name=中文"); 然后在后台通过new String(reque ...
- MongoDB的图形化连接工具MongoDB VUE
MongoDB的图形化连接工具MongoDB VUE 类似mysql的navicat.
- 【clientX,offsetX,screenX】 【scrollWidth,clientWidth,offsetWidth】的区别
一.深刻认识clientX,offsetX,screenX 概念(来源于网络): clientX 设置或获取鼠标指针位置相对于当前窗口的 x 坐标,其中客户区域不包括窗口自身的控件和滚动条. clie ...
- Jenkins 2 如何使用 PowerShell 以及自定 build fail (指定 exit code)
Jenkins 除了用來做為 CI(持續性整合) 工具外,也可以與其他 plugin 配合達成其他目的(e.g.IIS restart.檔案壓縮備份-),今天就來看看可以怎麼與 PowerShell ...
- python 学员管理系统
需求: 用户角色,讲师\学员, 用户登陆后根据角色不同,能做的事情不同,分别如下 讲师视图 管理班级,可创建班级,根据学员qq号把学员加入班级 可创建指定班级的上课纪录,注意一节上课纪录对应多条学员的 ...