#include #include #include #include #include #include #include #include #include #include #include #include #include #include #define ALSA_PCM_NEW_HW_PARAMS_API #define SAMPLE_RATE (16000) #define FRAMES_INIT (640*4) #define CHANNEL (4) #define FRAMES_SIZE ((16/8) *CHANNEL) #define PCM_STREAM_CAPTURE_DEVICE "hw:2,0" //#define PCM_STREAM_CAPTURE_DEVICE "default" typedef struct{ int dir; int size; unsigned int val; snd_pcm_t *handle; snd_pcm_uframes_t frames; snd_pcm_hw_params_t *params; }rec_config_t; static rec_config_t *s_index = NULL; typedef struct _pcm_header_t { char pcm_header[4]; size_t pcm_length; char format[8]; int bit_rate; short pcm; short channel; int sample_rate; int byte_rate; short block_align; short bits_per_sample; char fix_data[4]; size_t data_length; } pcm_header_t; static pcm_header_t s_pcm_header = { {'R', 'I', 'F', 'F'}, (size_t)-1, {'W', 'A', 'V', 'E', 'f', 'm', 't', ' '}, 0x10, 0x01, 0x01, #if 1 //def SAMPLE_RATE_16K 0x3E80, 0x7D00, #else //8k 0x1F40, 0x3E80, #endif // SAMPLE_RATE_16K 0x02, 0x10, {'d', 'a', 't', 'a'}, (size_t)-1 }; typedef struct _REC_FILE{ FILE *_file; pcm_header_t _hdr; }REC_FILE; REC_FILE *s_rec_files[CHANNEL+1]; REC_FILE * duer_store_voice_start(int channel_id) { REC_FILE *file=NULL; printf("start"); file = (REC_FILE*)malloc(sizeof(REC_FILE)); if(file==NULL){ return NULL; } char _name[64]; snprintf(_name, sizeof(_name), "./channel-%d.wav", channel_id); file->_file = fopen(_name, "wb"); if (!file->_file ) { printf("can't open file %s", _name); return NULL; } else { printf("begin write to file:%s", _name); } memcpy(&file->_hdr,&s_pcm_header,sizeof(s_pcm_header)); fwrite(&s_pcm_header, 1, sizeof(s_pcm_header), file->_file); file->_hdr.data_length = 0; file->_hdr.pcm_length = sizeof(s_pcm_header) - 8; return file; } int duer_store_voice_write(REC_FILE *file,const void *data, uint32_t size) { if (file&&file->_file) { fwrite(data, 1, size, file->_file); file->_hdr.data_length += size; } return 0; } int duer_store_voice_end(REC_FILE *file) { if (file&&file->_file) { file->_hdr.pcm_length += s_pcm_header.data_length; fseek(file->_file, 0, SEEK_SET); fwrite(&file->_hdr, 1, sizeof(file->_hdr), file->_file); fclose(file->_file); file->_file = NULL; } return 0; } int read_pcm_mono_data(int16_t *in,int ilen,int16_t *out,int channel_cnt) { int i=0; if((ilen%channel_cnt)){ printf("invalid pcm data lenght!\n"); return -1; } for(i=0;i=channel_cnt){ printf("please input invalid channel id \n"); return -1; } for(i=0;iparams, &(s_index->frames), &(s_index->dir)); if (s_index->frames < 0) { printf("Get period size failed!"); return; } printf("frames %d dir %d\n",s_index->frames,s_index->dir); s_index->size = s_index->frames * FRAMES_SIZE; if (buffer) { free(buffer); buffer = NULL; } buffer = (int16_t *)malloc(s_index->size); if (!buffer) { printf("malloc buffer failed!\n"); } else { memset(buffer, 0, s_index->size); } mono_buffer = (int16_t *)malloc(s_index->size); if (!mono_buffer) { printf("malloc buffer failed!\n"); } else { memset(mono_buffer, 0, s_index->size); } while (1) { int i=0; int ret = snd_pcm_readi(s_index->handle, buffer, s_index->frames); if (ret == -EPIPE) { printf("an overrun occurred!\n"); snd_pcm_prepare(s_index->handle); continue; } else if (ret < 0) { printf("read: %s\n", snd_strerror(ret)); continue; } else if (ret != (int)s_index->frames) { printf("read %d frames!\n", ret); continue; } else { // do nothing printf("ret=%d %d\n",ret,s_index->size); } for(i=0;isize>>1,mono_buffer,CHANNEL); }else{ mono_data_size = read_pcm_channel_data(buffer,s_index->size>>1,mono_buffer,i,CHANNEL); } duer_store_voice_write(s_rec_files[i],mono_buffer,mono_data_size<<1); } } if (buffer) { free(buffer); buffer = NULL; } if(mono_buffer){ free(mono_buffer); mono_buffer=NULL; } snd_pcm_drain(s_index->handle); snd_pcm_close(s_index->handle); if(s_index) { free(s_index); s_index = NULL; } return; } static int duer_open_alsa_pcm() { int ret = 0; s_index = (rec_config_t *)malloc(sizeof(rec_config_t)); if (!s_index) { printf("malloc fail\n"); return -1; } memset(s_index, 0, sizeof(rec_config_t)); s_index->frames = FRAMES_INIT; s_index->val = SAMPLE_RATE; // pcm sample rate int result = (snd_pcm_open(&(s_index->handle), PCM_STREAM_CAPTURE_DEVICE, SND_PCM_STREAM_CAPTURE, 0)); if (result < 0){ printf("\n\n****unable to open pcm device: %s*********\n\n", snd_strerror(ret)); ret = -1; } return ret; } static int duer_set_pcm_params() { int ret = 0; snd_pcm_hw_params_alloca(&(s_index->params)); snd_pcm_hw_params_any(s_index->handle, s_index->params); snd_pcm_hw_params_set_access(s_index->handle, s_index->params, SND_PCM_ACCESS_RW_INTERLEAVED); snd_pcm_hw_params_set_format(s_index->handle, s_index->params, SND_PCM_FORMAT_S16_LE); snd_pcm_hw_params_set_channels(s_index->handle, s_index->params, CHANNEL); snd_pcm_hw_params_set_rate_near(s_index->handle, s_index->params, &(s_index->val), &(s_index->dir)); snd_pcm_hw_params_set_period_size_near(s_index->handle, s_index->params, &(s_index->frames), &(s_index->dir)); int result = snd_pcm_hw_params(s_index->handle, s_index->params); if (result < 0) { printf("unable to set hw parameters: %s\n", snd_strerror(result)); ret = -1; } return ret; } void record_stop(int signo) { int i=0; printf("oops! stop!!!\n"); for(i=0;i