使用 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可以直 ...
随机推荐
- Smarty使用-模版中编写js
在smarty模版中编写js使用literal标签, Literal 标签区域内的数据将被当作文本处理,此时模板将忽略其内部的所有字符信息. 该特性用于显示有可能包含大括号等字符信息的 javas ...
- ROS中的日志(log)消息
学会使用日志(log)系统,做ROS大型项目的主治医生 通过显示进程的运行状态是好的习惯,但需要确定这样做不会影响到软件的运行效率和输出的清晰度.ROS 日志 (log) 系统的功能就是让进程生成一些 ...
- [LC] 345. Reverse Vowels of a String
Write a function that takes a string as input and reverse only the vowels of a string. Example 1: In ...
- Tarjan模板——求强连通分量
Tarjan求强连通分量的流程在这个博客讲的很清楚,再加上我也没理解透,这里就不写了. 缩点:将同一个连通块内的点视为同一个点. 扔一道模板题:codeVS2822爱在心中 第一问很显然就是求点数大于 ...
- cs231n spring 2017 lecture8 Deep Learning Networks
1. CPU vs. GPU: CPU核心少(几个),更擅长串行任务.GPU有很多核心(几千个),每一个核都弱,有自己的内存(几个G),很适合并行任务.GPU最典型的应用是矩阵运算. GPU编程:1) ...
- ionic2踩坑之兼容android4.3及以下版本
一个命令就行了 ionic plugin add cordova-plugin-crosswalk-webview --save 执行完之后重新打包. 但是如果要兼容4.0及以下的话.... 帮不了你 ...
- 介绍vue-cli脚手架config目录下index.js配置文件
1.config/index.js var path = require('path') module.exports = { build: { // production 环境 env: requi ...
- 最简化的DirectX 11开发环境的配置 VS2010
转载自:http://blog.csdn.net/zhmxy555/article/details/7672101 在编写基于DirectX 11的应用程序之前,我们当然需要在IDE中加入Direct ...
- 双股同时上市!小米IPO是想要玩场大的?
近日,据相关媒体报道,有相关人士称小米IPO最终可能敲定A+H股两地发行.但目前还未得到小米官方证实.此前关于小米要上市的消息已经流传已久了,从雷军刚开始的矢口否认到后来的默认,再到后来相关消息愈来 ...
- liubo.im
elite-lessons (37) --> 1025 精英水平的道歉 29/10/2016 1027 听大脑说话.给大脑编程 27/10/2016 1022 美国两党政治为什么越来越极化? 2 ...