经典alsa 录音和播放程序
这里贴上虚拟机ubuntu下alsa的录音程序(capture.c)和播放程序(playback.c)的源码。
首先要测试一下自己的ubuntu是否打开了声音。这个可以打开/系统/首选项/声音 来调节。另外也可以在终端下输入alsaMixer 来调节,之前我的耳机就是只能放音不能录音,因为没有打开一些设置,在进入alsamixer界面后,按F4也就是capture选项,把声音调大就可以录音了。其中有两种模式测验,一种是使用fread和fwrite以读写文件的方式操作,把声卡里的采集到的frame通过dma发送到应用程序的缓存中,先./capture 录音再./playback 放音。另一种是read和write来操作,把输入输出重定向到标准输入和标准输出,下面的程序就可以用./capture > sound.wav 把输出定向到sound.wav文件中,然后./playback < sound.wav 把声音文件传输到playback的输入端。
另外playback只能播放原始的wav文件。不能播放如MP3类型的编码过的音频文件。
capture.c
/*
This example reads from the default PCM device
and writes to standard output for 5 seconds of data.
*/
/* Use the newer ALSA API */
#include <stdio.h>
#define ALSA_PCM_NEW_HW_PARAMS_API
#include <alsa/asoundlib.h>
int main() {
long loops;
int rc,i = 0;
int size;
FILE *fp ;
snd_pcm_t *handle;
snd_pcm_hw_params_t *params;
unsigned int val,val2;
int dir;
snd_pcm_uframes_t frames;
char *buffer;
if( (fp =fopen("sound.wav","w")) < 0)
printf("open sound.wav fial\n");
/* Open PCM device for recording (capture). */
rc = snd_pcm_open(&handle, "default",
SND_PCM_STREAM_CAPTURE, 0);
if (rc < 0) {
fprintf(stderr, "unable to open pcm device: %s/n", snd_strerror(rc));
exit(1);
}
/* Allocate a hardware parameters object. */
snd_pcm_hw_params_alloca(¶ms);
/* Fill it in with default values. */
snd_pcm_hw_params_any(handle, params);
/* Set the desired hardware parameters. */
/* Interleaved mode */
snd_pcm_hw_params_set_access(handle, params,
SND_PCM_ACCESS_RW_INTERLEAVED);
/* Signed 16-bit little-endian format */
snd_pcm_hw_params_set_format(handle, params,
SND_PCM_FORMAT_S16_LE);
/* Two channels (stereo) */
snd_pcm_hw_params_set_channels(handle, params, 2);
/* 44100 bits/second sampling rate (CD quality) */
val = 44100;
snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir);
/* Set period size to 32 frames. */
frames = 32;
snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir);
/* Write the parameters to the driver */
rc = snd_pcm_hw_params(handle, params);
if (rc < 0) {
fprintf(stderr, "unable to set hw parameters: %s/n",
snd_strerror(rc));
exit(1);
}
/* Use a buffer large enough to hold one period */
snd_pcm_hw_params_get_period_size(params, &frames, &dir);
size = frames * 4; /* 2 bytes/sample, 2 channels */
printf("size = %d\n",size);
buffer = (char *) malloc(size);
/* We want to loop for 5 seconds */
snd_pcm_hw_params_get_period_time(params, &val, &dir);
loops = 10000000 / val;
while (loops > 0) {
loops--;
rc = snd_pcm_readi(handle, buffer, frames);
printf("%d\n",i++);
if (rc == -EPIPE) {
/* EPIPE means overrun */
fprintf(stderr, "overrun occurred/n");
snd_pcm_prepare(handle);
} else if (rc < 0) {
fprintf(stderr,
"error from read: %s/n",
snd_strerror(rc));
} else if (rc != (int)frames) {
fprintf(stderr, "short read, read %d frames/n", rc);
}
//rc = fwrite( buffer,1, size,fp);
rc = write(1,buffer,size);
if (rc != size)
fprintf(stderr, "short write: wrote %d bytes/n", rc);
else printf("fwrite buffer success\n");
}
/******************打印参数*********************/
snd_pcm_hw_params_get_channels(params, &val);
printf("channels = %d\n", val);
snd_pcm_hw_params_get_rate(params, &val, &dir);
printf("rate = %d bps\n", val);
snd_pcm_hw_params_get_period_time(params,
&val, &dir);
printf("period time = %d us\n", val);
snd_pcm_hw_params_get_period_size(params,
&frames, &dir);
printf("period size = %d frames\n", (int)frames);
snd_pcm_hw_params_get_buffer_time(params,
&val, &dir);
printf("buffer time = %d us\n", val);
snd_pcm_hw_params_get_buffer_size(params,
(snd_pcm_uframes_t *) &val);
printf("buffer size = %d frames\n", val);
snd_pcm_hw_params_get_periods(params, &val, &dir);
printf("periods per buffer = %d frames\n", val);
snd_pcm_hw_params_get_rate_numden(params,
&val, &val2);
printf("exact rate = %d/%d bps\n", val, val2);
val = snd_pcm_hw_params_get_sbits(params);
printf("significant bits = %d\n", val);
//snd_pcm_hw_params_get_tick_time(params, &val, &dir);
printf("tick time = %d us\n", val);
val = snd_pcm_hw_params_is_batch(params);
printf("is batch = %d\n", val);
val = snd_pcm_hw_params_is_block_transfer(params);
printf("is block transfer = %d\n", val);
val = snd_pcm_hw_params_is_double(params);
printf("is double = %d\n", val);
val = snd_pcm_hw_params_is_half_duplex(params);
printf("is half duplex = %d\n", val);
val = snd_pcm_hw_params_is_joint_duplex(params);
printf("is joint duplex = %d\n", val);
val = snd_pcm_hw_params_can_overrange(params);
printf("can overrange = %d\n", val);
val = snd_pcm_hw_params_can_mmap_sample_resolution(params);
printf("can mmap = %d\n", val);
val = snd_pcm_hw_params_can_pause(params);
printf("can pause = %d\n", val);
val = snd_pcm_hw_params_can_resume(params);
printf("can resume = %d\n", val);
val = snd_pcm_hw_params_can_sync_start(params);
printf("can sync start = %d\n", val);
/*******************************************************************/
snd_pcm_drain(handle);
snd_pcm_close(handle);
fclose(fp);
free(buffer);
return 0
}
playback.c
/*
This example reads standard from input and writes
to the default PCM device for 5 seconds of data.
*/
/* Use the newer ALSA API */
#define ALSA_PCM_NEW_HW_PARAMS_API
#include <alsa/asoundlib.h>
#include <stdio.h>
int main() {
long loops;
int rc,j = 0;
int size;
snd_pcm_t *handle;
snd_pcm_hw_params_t *params;
unsigned int val,val2;
int dir;
snd_pcm_uframes_t frames;
char *buffer;
FILE *fp ;
if( (fp = fopen("sound.wav","r")) < 0)//南拳妈妈 - 你不像她.wav
printf("open sound.wav fial\n");
//if(fseek(fp,0,SEEK_SET) < 0)
// printf("put fp start to first error\n ");
/* Open PCM device for playback. */
rc = snd_pcm_open(&handle, "default",
SND_PCM_STREAM_PLAYBACK, 0);
if (rc < 0) {
fprintf(stderr, "unable to open pcm device: %s/n",
snd_strerror(rc));
exit(1);
}
/* Allocate a hardware parameters object. */
snd_pcm_hw_params_alloca(¶ms);
/* Fill it in with default values. */
snd_pcm_hw_params_any(handle, params);
/* Set the desired hardware parameters. */
/* Interleaved mode */
snd_pcm_hw_params_set_access(handle, params,
SND_PCM_ACCESS_RW_INTERLEAVED);
/* Signed 16-bit little-endian format */
snd_pcm_hw_params_set_format(handle, params,
SND_PCM_FORMAT_S16_LE);
/* Two channels (stereo) */
snd_pcm_hw_params_set_channels(handle, params, 2);
/* 44100 bits/second sampling rate (CD quality) */
val = 44100;
snd_pcm_hw_params_set_rate_near(handle, params,
&val, &dir);
/* Set period size to 32 frames. */
frames = 16; //设置的值没有反应
snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir); //
printf("frames is %d\n",(int)frames);
/* Write the parameters to the driver */
rc = snd_pcm_hw_params(handle, params);
if (rc < 0) {
fprintf(stderr, "unable to set hw parameters: %s/n", snd_strerror(rc));
exit(1);
}
/* Use a buffer large enough to hold one period */
snd_pcm_hw_params_get_period_size(params, &frames,
&dir);
size = frames * 4; /* 2 bytes/sample, 2 channels */
buffer = (char *) malloc(size);
/* We want to loop for 5 seconds */
snd_pcm_hw_params_get_period_time(params, &val, &dir);
/* 5 seconds in microseconds divided by * period time */
loops = 10000000 / val;
while (loops > 0) {
loops--;
//rc = fread(buffer,1, size,fp);
rc = read(0,buffer,size);
//printf("%d\n",j++);
if (rc == 0) {
fprintf(stderr, "end of file on input\n");
break;
} else if (rc != size) {
fprintf(stderr, "short read: read %d bytes\n", rc);
}
//else printf("fread to buffer success\n");
rc = snd_pcm_writei(handle, buffer, frames);
if (rc == -EPIPE) {
/* EPIPE means underrun */
fprintf(stderr, "underrun occurred\n");
snd_pcm_prepare(handle);
} else if (rc < 0) {
fprintf(stderr, "error from writei: %s\n",
snd_strerror(rc));
} else if (rc != (int)frames) {
fprintf(stderr, "short write, write %d frames\n", rc);
}
}
/******************打印参数*********************/
snd_pcm_hw_params_get_channels(params, &val);
printf("channels = %d\n", val);
snd_pcm_hw_params_get_rate(params, &val, &dir);
printf("rate = %d bps\n", val);
snd_pcm_hw_params_get_period_time(params,
&val, &dir);
printf("period time = %d us\n", val);
snd_pcm_hw_params_get_period_size(params,
&frames, &dir);
printf("period size = %d frames\n", (int)frames);
snd_pcm_hw_params_get_buffer_time(params,
&val, &dir);
printf("buffer time = %d us\n", val);
snd_pcm_hw_params_get_buffer_size(params,
(snd_pcm_uframes_t *) &val);
printf("buffer size = %d frames\n", val);
snd_pcm_hw_params_get_periods(params, &val, &dir);
printf("periods per buffer = %d frames\n", val);
snd_pcm_hw_params_get_rate_numden(params,
&val, &val2);
printf("exact rate = %d/%d bps\n", val, val2);
val = snd_pcm_hw_params_get_sbits(params);
printf("significant bits = %d\n", val);
//snd_pcm_hw_params_get_tick_time(params, &val, &dir);
printf("tick time = %d us\n", val);
val = snd_pcm_hw_params_is_batch(params);
printf("is batch = %d\n", val);
val = snd_pcm_hw_params_is_block_transfer(params);
printf("is block transfer = %d\n", val);
val = snd_pcm_hw_params_is_double(params);
printf("is double = %d\n", val);
val = snd_pcm_hw_params_is_half_duplex(params);
printf("is half duplex = %d\n", val);
val = snd_pcm_hw_params_is_joint_duplex(params);
printf("is joint duplex = %d\n", val);
val = snd_pcm_hw_params_can_overrange(params);
printf("can overrange = %d\n", val);
val = snd_pcm_hw_params_can_mmap_sample_resolution(params);
printf("can mmap = %d\n", val);
val = snd_pcm_hw_params_can_pause(params);
printf("can pause = %d\n", val);
val = snd_pcm_hw_params_can_resume(params);
printf("can resume = %d\n", val);
val = snd_pcm_hw_params_can_sync_start(params);
printf("can sync start = %d\n", val);
/*******************************************************************/
snd_pcm_drain(handle);
snd_pcm_close(handle);
free(buf);
fclose(fp);
return 0;
}
经典alsa 录音和播放程序的更多相关文章
- 基于Linux ALSA音频驱动的wav文件解析及播放程序 2012
本设计思路:先打开一个普通wav音频文件,从定义的文件头前面的44个字节中,取出文件头的定义消息,置于一个文件头的结构体中.然后打开alsa音频驱动,从文件头结构体取出采样精度,声道数,采样频率三个重 ...
- windows phone 7 通过麦克风录音,并且播放
原文:windows phone 7 通过麦克风录音,并且播放 //模拟XNA的框架(凡是在wp7中应用xna的都必须先模拟此类) public class XNAAsyncDispatcher : ...
- Android 录音和播放
今天工作上需要做一个一边录音一边播放的功能,大致原因是有一个外部设备输入音频到我们机器,然后我们机器需要马上把音频播放出来.所以了解了一些有关录音和播放的知识.接到这个任务的第一反应就是看看Andro ...
- [Android] 录音与播放录音实现
http://blog.csdn.net/cxf7394373/article/details/8313980 android开发文档中有一个关于录音的类MediaRecord,一张图介绍了基本的流程 ...
- Apworks框架实战(四):使用Visual Studio开发面向经典分层架构的应用程序:从EasyMemo案例开始
时隔一年,继续我们的Apworks框架之旅.在接下来的文章中,我将逐渐向大家介绍如何在Visual Studio中结合Apworks框架,使用ASP.NET Web API和MVC来开发面向经典分层架 ...
- IOS关于录音,播放实现总结
//音频录制(标准过程5,9更新) 准备:导入AVFoundation框架及头文件 1 设置会话类型,允许播放及录音AVAudioSession *audioSession = [AVAudioSes ...
- Android开发教程 录音和播放
首先要了解andriod开发中andriod多媒体框架包含了什么,它包含了获取和编码多种音频格式的支持,因此你几耍轻松把音频合并到你的应用中,若设备支持,使用MediaRecorder APIs便可以 ...
- Android平台下实现录音及播放录音功能的简介
录音及播放的方法如下: package com.example.audiorecord; import java.io.File; import java.io.IOException; import ...
- iOS 实时录音和播放
需求:最近公司需要做一个楼宇对讲的功能:门口机(连接WIFI)拨号对室内机(对应的WIFI)的设备进行呼叫,室内机收到呼叫之后将对收到的数据进行UDP广播的转发,手机(连接对应的WIFI)收到视频流之 ...
随机推荐
- installed jre指向jdk而非jre位置&
1.eclipse菜单 - Window - Preferences- Java - Installed JREs 将配置的JRE定位到JDK,例如JRE home:D:\Program Files ...
- [Project]微信项目感悟
一定要先考虑好可复用部分,可以复制粘贴的地方 一定要先想好了在动 前台不同插件之间的兼容性问题可能是dom加载顺序的问题,有的代码可能要卸载其中一个插件的某个事件里
- HDU 4513 manacher
Manacher算法,相当于求回文串. 关于Manacher,转 http://blog.sina.com.cn/s/blog_70811e1a01014esn.html 现在进入正题:首先,在字符串 ...
- Android Studio 编译Gradle提示编码错误
在Android Studio中,假设我们的代码有中文凝视.显示的时候全然正常,而编译的时候Gradle就会报错,可是又能够编译成功,并且Gradle报的错误信息,也是乱码! 这样我们就不好寻找错误原 ...
- 《ASP.NET》数据绑定——GridView
GirdView简单介绍: 名称:网络视图. 来源:GridView 是 DataGrid的后继控件.在.net framework 2 中,尽管还存在DataGrid,可是GridView已经走上了 ...
- ubuntu14.04 安装LNMP
新书上市<深入解析Android 5.0系统> 通常我们使用centos来组建LNMP,可是我们开发时多使用ubuntu的桌面版本号来调试,以下将具体介绍怎样在ubuntu上安装一套LNM ...
- Linux命令(七)——网络配置和网络通信
在使用网络前,需要对linux主机进行基本的网络配置,配置后可以使该主机能够同其他主机进行正常的通信. 一.网络配置 1.ifcfg-ethn网络配置文件 所有的网络接口配置文件均存放在/etc/sy ...
- poj 2135 Farm Tour 【无向图最小费用最大流】
题目:id=2135" target="_blank">poj 2135 Farm Tour 题意:给出一个无向图,问从 1 点到 n 点然后又回到一点总共的最短路 ...
- CSS Flexbox 弹性盒子模型
CSS Flexbox 弹性盒子模型 设置元素样式为 display: flex 或 display: inline-flex, 让元素变成flex容器, 从而可以通过flex模式布局它的子元素. f ...
- All Metro Apps on Windows 8.1 Do Not Work
所有的Metro Apps不能够正常打开,表现为打开后自动最小化到任务栏,并且不能恢复正常状态.在Event Viewer\Application中相应的错误信息为: Activation of ap ...