这里贴上虚拟机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(&params);  
/* 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(&params);  
/* 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 录音和播放程序的更多相关文章

  1. 基于Linux ALSA音频驱动的wav文件解析及播放程序 2012

    本设计思路:先打开一个普通wav音频文件,从定义的文件头前面的44个字节中,取出文件头的定义消息,置于一个文件头的结构体中.然后打开alsa音频驱动,从文件头结构体取出采样精度,声道数,采样频率三个重 ...

  2. windows phone 7 通过麦克风录音,并且播放

    原文:windows phone 7 通过麦克风录音,并且播放 //模拟XNA的框架(凡是在wp7中应用xna的都必须先模拟此类) public class XNAAsyncDispatcher : ...

  3. Android 录音和播放

    今天工作上需要做一个一边录音一边播放的功能,大致原因是有一个外部设备输入音频到我们机器,然后我们机器需要马上把音频播放出来.所以了解了一些有关录音和播放的知识.接到这个任务的第一反应就是看看Andro ...

  4. [Android] 录音与播放录音实现

    http://blog.csdn.net/cxf7394373/article/details/8313980 android开发文档中有一个关于录音的类MediaRecord,一张图介绍了基本的流程 ...

  5. Apworks框架实战(四):使用Visual Studio开发面向经典分层架构的应用程序:从EasyMemo案例开始

    时隔一年,继续我们的Apworks框架之旅.在接下来的文章中,我将逐渐向大家介绍如何在Visual Studio中结合Apworks框架,使用ASP.NET Web API和MVC来开发面向经典分层架 ...

  6. IOS关于录音,播放实现总结

    //音频录制(标准过程5,9更新) 准备:导入AVFoundation框架及头文件 1 设置会话类型,允许播放及录音AVAudioSession *audioSession = [AVAudioSes ...

  7. Android开发教程 录音和播放

    首先要了解andriod开发中andriod多媒体框架包含了什么,它包含了获取和编码多种音频格式的支持,因此你几耍轻松把音频合并到你的应用中,若设备支持,使用MediaRecorder APIs便可以 ...

  8. Android平台下实现录音及播放录音功能的简介

    录音及播放的方法如下: package com.example.audiorecord; import java.io.File; import java.io.IOException; import ...

  9. iOS 实时录音和播放

    需求:最近公司需要做一个楼宇对讲的功能:门口机(连接WIFI)拨号对室内机(对应的WIFI)的设备进行呼叫,室内机收到呼叫之后将对收到的数据进行UDP广播的转发,手机(连接对应的WIFI)收到视频流之 ...

随机推荐

  1. plsql developer ini

    plsql developer ini [Colors] GradientEnabled=True VerticalGradient=True DefaultGradient=True Gradien ...

  2. 全栈JavaScript之路( 二十 )HTML5 插入 html标记 ( 二 )insertAdjacentHTML

    insertAdjacentHTML(),  这种方法也是在IE中最早出现的.如今已纳入html5规范,它接受两个參数,一个是下列的标记之中的一个,一个是要写入的 html 代码文本. beforeb ...

  3. Codeforces Round #256 (Div. 2) B

    B. Suffix Structures Bizon the Champion isn't just a bison. He also is a favorite of the "Bizon ...

  4. java异常 之 异常的层次结构

    一:起因 (1)近期在用java处理分析各种数据,碰到了一些异常,如parse()异常 ParseException,valueOf()NumberFormatException  IllegalAr ...

  5. 基于ActiveMQ的消息中间件系统逻辑与物理架构设计具体解释

    1. 基本介绍与组件架构图 维基百科对消息中间件的定义是"Message-oriented Middleware is software infrastructure focused on ...

  6. hdu 5411 CRB and Puzzle 矩阵高速幂

    链接 题解链接:http://www.cygmasot.com/index.php/2015/08/20/hdu_5411/ 给定n个点 常数m 以下n行第i行第一个数字表示i点的出边数.后面给出这些 ...

  7. wpf Command canExecute 更新

    可以调用以下语句通知 CommandManager.InvalidateRequerySuggested();

  8. Maven—Windows操作系统中安装配置Maven环境

    今天难得的周末,借此难的机会总结一下关于maven的一些操作: 1.在安装maven之前要确认计算机已经安装并配置了JDK. 2.下载maven: maven-3.0.3:http://downloa ...

  9. Makefile中用宏定义进行条件编译(gcc -D)/在Makefile中进行宏定义-D【转】

    本文转载自:http://blog.csdn.net/maopig/article/details/7230311 在源代码里面如果这样是定义的:#ifdef   MACRONAME//可选代码#en ...

  10. bzoj2958: 序列染色&&3269: 序列染色

    DP这种东西,考场上就只能看命了.. #include<cstdio> #include<iostream> #include<cstring> #include& ...