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;
}