在 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的更多相关文章

  1. C#播放wav文件

    C#使用HWQPlayer类播放wav文件 类的代码: using System.IO; using System.Runtime.InteropServices; namespace HoverTr ...

  2. python 播放 wav 文件

    未使用其他库, 只是使用 pywin32 调用系统底层 API 播放 wav 文件. # Our raison d'etre - playing sounds import pywintypes im ...

  3. MmSystem播放Wav格式声音

    //MmSystem播放Wav格式声音 //MmSystem 支持 *.wav声音格式 snd ->SoundRecorderuses MmSystem; //引用MmSystem//播放系统声 ...

  4. 1.1.6-学习Opencv与MFC混合编程之---播放WAV音乐和 alpha融合功能

    源代码:http://download.csdn.net/detail/nuptboyzhb/3961698 Alpha融合菜单项 1.      增加alpha融合菜单项,修改相应的属性,建立类向导 ...

  5. 多浏览器播放wav格式的音频文件

    html5的audio标签只在火狐下支持wav格式的音频播放,无法兼容IE和google , 使用audioplayer.js 基本上能支持大部分浏览器播放wav音频文件,经测试IE.火狐.googl ...

  6. WinAPI: sndPlaySound - 播放 wav 文件

    WinAPI: sndPlaySound - 播放 wav 文件 //声明: sndPlaySound(   lpszSoundName: PChar; {声音文件}   uFlags: UINT{播 ...

  7. C++播放wav音乐和音效

    1.  #include <mmsystem.h>#pragma comment(lib,"winmm.lib")PlaySound(TEXT("c:\\te ...

  8. 用 Qt 的 QAudioOutput 类播放 WAV 音频文件

    用 Qt 的 QAudioOutput 类播放 WAV 音频文件 最近有一个项目,需要同时控制 4 个声卡播放不同的声音,声音文件很简单就是没有任何压缩的 wav 文件. 如果只是播放 wav 文件, ...

  9. 8086汇编语言 调用声卡播放wav文件(sound blaster)

    开更 大概最后做了一个能播放无损音乐(无压缩.不需解码)的播放器 原理是基于dosbox的模拟声卡,通过硬件之间的相互通讯做到的 关于详细内容接下来再讲. 一.从dosbox入手 我们知道cpu可以直 ...

随机推荐

  1. 成为一名PHP专家其实并不难

    本文作者Bruno Skvorc是一名资深的Web开发者.在这篇文章里主要是讲述成为一名专业的PHP专家所要经历的过程,以及在这个过程里要如何学习掌握技巧和对工具的舍取.(以下为编译内容) 当阅读各种 ...

  2. [LC] 39. Combination Sum

    Given a set of candidate numbers (candidates) (without duplicates) and a target number (target), fin ...

  3. 吴裕雄 python 神经网络——TensorFlow 卷积神经网络水果图片识别

    #-*- coding:utf- -*- import time import keras import skimage import numpy as np import tensorflow as ...

  4. 学习python-20191230(1)-Python Flask高级编程开发鱼书_第04章_应用、蓝图与视图函数

    视频06: 1.自动导包快捷键——默认为alt + enter 键组合          选中的字符由小写变为大写——Ctrl + Shift + U键组合 2.DataRequired()——防止用 ...

  5. Spring中Bean的不同配置方式

    Bean的配置方式一共分为三种: 1.基于XML(适用于第三方类库,无法在类中写注解以及写命名空间的配置等情况) 2.基于注解(适用于大部分情况) 3.基于Java类 以下是三种不同情况的配置方式   ...

  6. deeplearning.ai 构建机器学习项目 Week 2 机器学习策略 II

    1. 误差分析(Error analysis) 误差分析的目的是找到不同误差源的比重,从而指引我们接下来往哪个方向努力改进.NG建议手工统计随机100个错误的误差源,比如对于猫分类器,错误的照片可能是 ...

  7. 公式化学习requests(第二卷)

    请求浏览器分为两种一种是不需要用户登录验证直接请求 另一种是需要用户登陆验证请求,现在说一下利用COOKIE实现,COOKIE在前端开发时有很多的作用,要熟练使用, 直接上代码了: 第一步:访问页面, ...

  8. [LC] 235. Lowest Common Ancestor of a Binary Search Tree

    Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BS ...

  9. 吴裕雄--天生自然HTML学习笔记:HTML 列表

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  10. IDEA无法启动:Failed to create JVM:error code -1

    转自:https://blog.csdn.net/u013243986/article/details/52296944 随便设置把内存加大了, 结果idea就奔溃了,再打开时就提示这样的错误,Fai ...