www.pudn.com > wav_mp3_recorder.rar > audiorec.c
//#define _REENTRANT
#include "audiorec.h"
/*
* 1. I use a thread to record audio
*/
/*global var*/
#define BUFFER_NUM 4
static struct ABUFFER *buffer_array[BUFFER_NUM];
static int free_index,full_index;
static int audio_fd=0;
static pthread_t a_thread=0;
static void* thread_ret;
static int thread_exit=0;
static void *audio_thread(void *arg);
static void Write32BitsLowHigh(int fd, int i);
static void Write16BitsLowHigh(int fd, int i);
static void init_buffer_array(void)
{
int i;
struct ABUFFER *buf;
for(i=0; ilen = 0;
buf->free =1;
buf->data = malloc(PCM_FRAME_LEN1);
if(buf->data == NULL){
free(buf);
buf = NULL;
}
}
buffer_array[i] = buf;
}
free_index = full_index = 0;
}
static void array_empty(void)
{
int i;
for(i=0; idata);
free(buffer_array[i]);
}
}
}
/*get a free or full buffer from buffer array*/
static struct ABUFFER *get_free_buffer()
{
struct ABUFFER *buf = buffer_array[free_index];
if(buf->free == 1)
{
// printf("%d free\n",free_index);
free_index++;
if(free_index == BUFFER_NUM) free_index = 0;
return buf;
}
return NULL;
}
static struct ABUFFER *get_full_buffer()
{
struct ABUFFER *buf = buffer_array[full_index];
if(buf->free == 0)
{
// printf("%d full\n",full_index);
full_index++;
if(full_index == BUFFER_NUM) full_index = 0;
return buf;
}
return NULL;
}
/*set buffer free or full */
static void put_buffer(struct ABUFFER *buf,int free)
{
buf->free = free;
}
/*actual functions*/
int audio_open(void)
{
if(audio_fd) return AUDIO_FAILURE;
audio_fd = open("/dev/dsp",O_RDONLY);
if(audio_fd<0) {
return AUDIO_FAILURE;
}
return AUDIO_SUCCESS;
}
int audio_config(unsigned char channels,unsigned char bits,unsigned int rate, int video_rate)
{
int ret;
int arg;
arg=channels;
ret = ioctl(audio_fd, SOUND_PCM_WRITE_CHANNELS, &arg);
if(ret<0) return AUDIO_FAILURE;
arg=bits;
ret = ioctl(audio_fd, SOUND_PCM_WRITE_BITS, &arg);
if(ret<0) return AUDIO_FAILURE;
arg=rate;
ret = ioctl(audio_fd, SOUND_PCM_WRITE_RATE, &arg);
if(ret<0) return AUDIO_FAILURE;
init_buffer_array();
return AUDIO_SUCCESS;
}
int audio_start(void)
{
int ret;
if(a_thread) return AUDIO_FAILURE;
ret = pthread_create(&a_thread, NULL, audio_thread, NULL);
if(ret != 0)
return AUDIO_FAILURE;
return AUDIO_SUCCESS;
}
struct ABUFFER *audio_get_frame(void)
{
return get_full_buffer();
}
void audio_put_frame(struct ABUFFER *buf)
{
put_buffer(buf,1);
}
int audio_end(int i)
{
if (i == 0) {
if(a_thread != 0)
{
thread_exit=1;
pthread_join(a_thread,&thread_ret);
a_thread = 0;
thread_exit=0;
}
array_empty();
}
if(audio_fd != 0)
{
close(audio_fd);
audio_fd = 0;
}
return AUDIO_SUCCESS;
}
void audio_set_volume(int vol)
{
int fd = open("/dev/mixer",O_RDWR);
int volume;
if(fd<0) return;
volume=vol;
volume|=volume<<8;
ioctl(fd,MIXER_WRITE(0),&volume);
close(fd);
}
void *audio_thread(void *arg)
{
struct ABUFFER *buf;
int readed;
while(1)
{
if(thread_exit) break;
buf = get_free_buffer();
if(!buf){
continue;
}
readed = read(audio_fd,buf->data,PCM_FRAME_LEN1);
if(readed>0){
buf->len = readed;
put_buffer(buf,0);
}
}
pthread_exit(NULL);
}
int audio_wave(void* pcm_buf)
{
int num;
num = read(audio_fd, pcm_buf, PCM_BUF_LEN);
return num;
}
static void Write32BitsLowHigh(int fd, int i)
{
Write16BitsLowHigh(fd,(int)(i&0xffffL));
Write16BitsLowHigh(fd,(int)((i>>16)&0xffffL));
}
static void Write16BitsLowHigh(int fd, int i)
{
//putc(i&0xff,fp);
unsigned char ch = i&0xff;
write(fd, &ch, 1);
ch = (i>>8)&0xff;
write(fd, &ch, 1);
//putc((i>>8)&0xff,fp);
}
int WriteWaveHeader(int fd, const long int pcmbytes,
const int freq, const int channels, const int bits)
{
int bytes = bits/8;
write(fd, "RIFF", 4);
Write32BitsLowHigh(fd, pcmbytes + 44 - 8);
write(fd, "WAVEfmt ", 8);
Write32BitsLowHigh(fd, 2 + 2 + 4 + 4 + 2 + 2);
Write16BitsLowHigh(fd, 1);
Write16BitsLowHigh(fd, channels);
Write32BitsLowHigh(fd, freq);
Write32BitsLowHigh(fd, freq * channels * bytes);
Write16BitsLowHigh(fd, channels * bytes);
Write16BitsLowHigh(fd, bits);
write(fd, "data", 4);
Write32BitsLowHigh(fd, pcmbytes);
return 0;
}