from :上海尚观嵌入式培训 http://www.uplooking.sh.cn/embedded_training/tecnews/2012/1117/1456_1.html
说明:
1)音频设备只能以O_WRONLY或者O_RDONLY方式打开,不能使用O_RDWR方式打开,因为不支持同时录音和放音。
2)使用方法举例"./oss /tmp/test.wav 22050" ,会自动录音2MB,再将其播放出来。
3)支持调整音频采样率:支持44100、22050、11025和8000四种采样率。
4)驱动使用方法:将sep4020-uda1341.c替换sound/oss目录下同名文件。
以下为测试程序源码
==================================================================================
//注意!音频设备只能以O_WRONLY或者O_RDONLY方式打开,不能使用O_RDWR方式打开,因为不支持同时录音和放音。
#include <sys/ioctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/soundcard.h>
#define BUF_SIZE 4096
#define DEVICE_NAME "/dev/dsp"
int audio_fd; //声卡
FILE *file_fd; //文件
int file_len; //文件长度
const char *file_name = "test.wav";
unsigned char audio_buffer[BUF_SIZE];
unsigned char *file_name_creat;
unsigned int audio_rate;
void delay(long x)
{
unsigned long i;
for(i=0; i<x; i++);
}
int main(int argc, char *argv[])
{
printf("This is an I2S record & play program.\n");
printf("Please add a file name and the audio rate! such as \"./oss test.wav 44100\" \n\n\n");
delay(100000);
file_name_creat = argv[1];
sscanf(argv[2],"%d", &audio_rate);
printf("the file name is %s audio rate is %d \n",file_name_creat,audio_rate);
delay(100000);
/*打开音频设备,准备录音*/
if ((audio_fd = open(DEVICE_NAME, O_RDONLY)) == -1)
{
printf("open error\n");
return -1;
}
/*设置采样速率*/
int speed = audio_rate;
if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &speed)==-1)
{
/* Fatal error */
printf("SNDCTL_DSP_SPEED error\n");
return -1;
}
printf("the wav speed is %d\n",speed);
/*录音*/
int i=0;
unsigned long loops_record = 500; //500*4KB=2MB
file_fd = fopen(file_name_creat, "w");
printf("recording...\n");
for(i=0;i<loops_record;i++)
{
read(audio_fd,audio_buffer,4096);
fwrite(audio_buffer, 4096, 1, file_fd);
}
printf("recording...over\n");
/*关闭设备和文件*/
fclose(file_fd);
close(audio_fd);
delay(100000);
/*打开音频设备,准备放音*/
if ((audio_fd = open(DEVICE_NAME, O_WRONLY)) == -1)
{
printf("open error\n");
return -1;
}
/*设置采样格式*/
int format;
format = AFMT_S16_LE;
if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format) == -1)
{
/* fatal error */
printf("SNDCTL_DSP_SETFMT error\n");
return -1;
}
if (format != AFMT_S16_LE)
{
/* 本设备不支持选择的采样格式. */
printf("sep4020 oss driver does not support AFMT_S16_LE");
}
/*设置通道数*/
int channels = 2; /* 1=mono, 2=stereo */
if (ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &channels) == -1)
{
/* Fatal error */
printf("SNDCTL_DSP_CHANNELS error");
return -1;
}
if (channels != 2)
{
/* 本设备不支持立体声模式 ... */
printf("sep4020 oss driver does ");
}
/*设置采样速率*/
speed = audio_rate;
if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &speed)==-1)
{
/* Fatal error */
printf("SNDCTL_DSP_SPEED error\n");
return -1;
}
printf("the wav speed is %d\n",speed);
/*打开并计算文件长度*/
file_fd = fopen(file_name_creat, "r");
fseek(file_fd,0,SEEK_END); //定位到文件末
file_len = ftell(file_fd); //文件长度
int loops = file_len/4096;
/*重新定位到文件头*/
fclose(file_fd);
file_fd = fopen(file_name_creat, "r");
/*播放wav文件*/
for(i=0;i<loops;i++)
{
fread(audio_buffer, 4096, 1, file_fd);
write(audio_fd,audio_buffer,4096);
}
/*关闭设备和文件*/
fclose(file_fd);
close(audio_fd);
return 0;
}
//AUTHOR("aokikyon@gmail.com");
//DESCRIPTION("sep4020 uda1341 sound card test program");