Chirs,
不好意思,demo代码编辑的有问题。。。。
#define WORD_LEN 8 #define READ_SAMPLE 1152//2560//5120 long long device_capture( snd_pcm_t *c, snd_pcm_t *p, int rate, int secs, int port, int idx) { int frames = rate/25; int channels = port*2; char *data = buff0; long long total_len = 0; long long wave_buf_len = rate*WORD_LEN*secs; int frame_len = 2*channels; int r_frames = 0; int w_frames = 0; int err, i = 0,j=0; int try = 0; audio_frame_l_t *lframe; audio_frame_s_t *sframe; FILE *fpcapture=NULL; int count = 0; signed char *singlebuf=(signed char*)malloc(BS); signed char *singlebuf1=(signed char*)malloc(BS); printf("audio_frame_l_t=%d, audio_frame_s_t=%d\n", sizeof(audio_frame_l_t), sizeof(audio_frame_s_t)); fpcapture = fopen("/home/buffer/48k","wb+"); if(fpcapture == NULL){ printf("fopen file failed\n"); return -1; } while ( total_len < wave_buf_len ){ struct timeval birthsec,birthsec1; gettimeofday(&birthsec, NULL); try_again: //printf("1-------------\n"); memset(buff0,0,sizeof(buff0)); memset(singlebuf,0,sizeof(singlebuf)); memset(singlebuf1,0,sizeof(singlebuf1)); r_frames = snd_pcm_readi(c, (void*)buff0, READ_SAMPLE); printf(" snd_pcm_readi (%d) frames=%d, birthsec.tv_sec(%lu.%06lu)\n", i, r_frames, birthsec.tv_sec, birthsec.tv_usec); if(r_frames > 0) { total_len += r_frames * 8;//frame_len; #if defined(SAMPLE_48K)||defined(SAMPLE_8K)||defined(SAMPLE_16K) for(j=0;j<r_frames;j++){ #ifdef SAVE_FILE memcpy(singlebuf+j*2,(void*)(buff0+j*8+2),2); #endif #ifdef LOOP memcpy(singlebuf1+j*8,buff0+j*8,4); memcpy(singlebuf1+j*8+4,buff0+j*8,4); #endif } #endif #ifdef SAMPLE_64K for(j=0;j<r_frames;j++){ #ifdef SAVE_FILE memcpy(singlebuf+j*2,(void*)(buff0+j*8+1),2); #endif #ifdef LOOP memcpy(singlebuf1+j*8,buff0+j*8,4); memcpy(singlebuf1+j*8+4,buff0+j*8,4); #endif } #endif #ifdef SAVE_FILE count = fwrite(singlebuf, 1, r_frames*2, fpcapture); //printf("fwrite file %d bytes count %d==========>\n",r_frames*WORD_LEN,count); if(count != 2*r_frames){ printf("fwrite file failed\n"); fclose(fpcapture); free(singlebuf); free(singlebuf1); singlebuf = NULL; singlebuf1 = NULL; } #endif #ifdef LOOP try = 0; do{ usleep(100); printf(" snd_pcm_writei (%d) frames=%d\n", i, r_frames); if((w_frames = snd_pcm_writei(p, singlebuf1, r_frames) < 0)) //if((w_frames = snd_pcm_writei(p, buff0, r_frames) < 0)) { printf("2-------------\n"); err = w_frames; printf("w_frames %d========\n",err); if(err == -EPIPE) { try++; snd_pcm_prepare (p); fprintf (stderr, "snd_pcm_writei(%d) error, and try(%d)\n", i, try); } else { try = 0; } } else { printf("3-------------\n"); try = 0; } } while(try); #endif } else { printf("4-------------\n"); err = r_frames; if(err == -EPIPE) { snd_pcm_prepare (c); fprintf (stderr, "snd_pcm_readi error(%s)\n", snd_strerror(err)); goto try_again; } break; } i++; usleep(1000); } if(fpcapture != NULL) fclose(fpcapture); if(singlebuf != NULL){ free(singlebuf); singlebuf = NULL; } if(singlebuf1 != NULL){ free(singlebuf1); singlebuf1 = NULL; } return total_len; } int init_snd_pcm_hw_params(snd_pcm_t *handle, snd_pcm_hw_params_t *hw_params, int channels, int rate, int period_frames) { int err,dir,val; if ((err = snd_pcm_hw_params_any (handle, hw_params)) < 0) { fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n", snd_strerror (err)); return -1; } if ((err = snd_pcm_hw_params_set_access (handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { fprintf (stderr, "cannot set access type (%s)\n", snd_strerror (err)); return -2; } if ((err = snd_pcm_hw_params_set_format (handle, hw_params, SND_PCM_FORMAT_S32_LE)) < 0) { fprintf (stderr, "cannot set sample format (%s)\n", snd_strerror (err)); return -3; } if ((err = snd_pcm_hw_params_set_rate_near (handle, hw_params, &rate, 0)) < 0) { fprintf (stderr, "cannot set sample rate (%s)\n", snd_strerror (err)); return -4; } printf("snd_pcm_hw_params_set_rate_near rate=%d\n", rate); #if 1 if ((err = snd_pcm_hw_params_set_period_size_near (handle, hw_params, &period_frames, 0)) < 0) { fprintf (stderr, "cannot set sample period_size (%s)\n", snd_strerror (err)); return -6; } printf("snd_pcm_hw_params_set_period_frames_near frames=%d\n", period_frames); #endif if ((err = snd_pcm_hw_params_set_channels (handle, hw_params, channels)) < 0) { fprintf (stderr, "cannot set channel count (%s)\n", snd_strerror (err)); return -5; } #if 1 if ((err = snd_pcm_hw_params (handle, hw_params)) < 0) { fprintf (stderr, "cannot set parameters (%s)\n", snd_strerror (err)); return -6; } #endif snd_pcm_hw_params_get_channels(hw_params, &val); printf("AUDIO : channels = %d\n", val); snd_pcm_hw_params_get_period_size(hw_params, &period_frames, &dir); snd_pcm_hw_params_get_period_time(hw_params, &val, &dir); printf("AUDIO : period size = %d frames, dir = %d\n", (int)period_frames, dir); printf("AUDIO : period time = %d us, dir = %d\n", val, dir); snd_pcm_hw_params_get_buffer_size(hw_params, &val); snd_pcm_hw_params_get_buffer_time(hw_params, &val, &dir); printf("AUDIO : buffer size = %d frames, dir = %d\n", val, dir); printf("AUDIO : buffer time = %d us, dir = %d\n", val, dir); snd_pcm_hw_params_get_rate(hw_params, &val, 0); printf("AUDIO : rate = %d \n", val); return 0; } //#define FRAME_SIZE 1240//256 #define FRAME_SIZE 5120//256 int main(int argc, char *argv[]) { snd_pcm_sframes_t frames; snd_pcm_format_t format = SND_PCM_FORMAT_S32_LE; unsigned int channel = 2; //2 unsigned int c_rate = 48000; int loop_secs = 20; //char pcm_player[32] = "plughw:0,1"; char pcm_player[32] = "hw:0,1"; snd_pcm_t *player_handle = NULL; //char pcm_capture[32] = "plughw:0,3"; //char pcm_capture[32] = "plughw:0";//"default"; char pcm_capture[32] = "hw:0,0";//"default"; snd_pcm_t *capture_handle = NULL; snd_pcm_hw_params_t *hw_params0 = NULL, *hw_params1 = NULL; char file_name[50] = "alarm_1_16K.wav"; int i, ret, err; int port = 1, channels = 2, c_idx = 0; int ch; int buffer_time=0; while ((ch = getopt(argc, argv, "c:r:j:p:l:")) != -1) { switch(ch) { case 'c': snprintf(pcm_capture, sizeof(pcm_capture), "plughw:%s", optarg); break; case 'r': c_rate = atoi(optarg); break; case 'p': snprintf(pcm_player, sizeof(pcm_player), "plughw:%s", optarg); break; case 'j': c_idx = atoi(optarg); break; case 'l': loop_secs = atoi(optarg); break; case '?': printf("Unknown option: %c\n",(char)optopt); break; } } buff0 = (signed char *)malloc(BS); buff1 = (signed char *)malloc(BS); if(buff0 == NULL || buff1 == NULL) { goto out_err; } if ((err = snd_pcm_open (&capture_handle, pcm_capture, SND_PCM_STREAM_CAPTURE, 0)) < 0) { fprintf (stderr, "cannot open audio capture device %s (%s)\n", pcm_capture, snd_strerror(err)); goto out_err; } #ifdef LOOP if ((err = snd_pcm_open (&player_handle, pcm_player, SND_PCM_STREAM_PLAYBACK, 0)) < 0) { fprintf (stderr, "cannot open audio playback device %s (%s)\n", pcm_player, snd_strerror(err)); goto out_err; } fprintf (stdout, "Step1: Open audio capture device[%s] and play device[%s] Success\n", pcm_capture, pcm_player); #endif snd_pcm_hw_params_malloc(&hw_params0); snd_pcm_hw_params_malloc(&hw_params1); if(strcmp(pcm_capture, "plughw:0,3") == 0) { port = 4; channels = 8; } else { port = 1; channels =2; } //printf("port =%d, channels =%d\n", port, channels); ret = init_snd_pcm_hw_params(capture_handle, hw_params0, channels, c_rate, FRAME_SIZE); //printf("ret1 = %d, c_rate = %d\n", ret, c_rate); sleep(1); #ifdef LOOP ret = init_snd_pcm_hw_params(player_handle, hw_params1, channels, c_rate, FRAME_SIZE); snd_pcm_hw_params_get_rate(hw_params1, &c_rate, 0); printf("ret2 = %d, c_rate set = %d\n", ret, c_rate); #endif snd_pcm_hw_params_get_buffer_time_max(hw_params0, &buffer_time, 0); //printf("buffer_time is %d========>\n",buffer_time); #ifdef LOOP if ((err = snd_pcm_prepare (capture_handle)) < 0 || (err = snd_pcm_prepare (player_handle)) < 0) { fprintf (stderr, "cannot prepare audio interface for use (%s)\n", snd_strerror (err)); goto out_err; } #endif #ifdef SAVE_FILE if ((err = snd_pcm_prepare (capture_handle)) < 0 ) { fprintf (stderr, "cannot prepare audio interface for use (%s)\n", snd_strerror (err)); goto out_err; } #endif sleep(1); //fprintf (stdout, "Start Capture(%s) => Player(%s) loop_secs=%d\n", pcm_capture, pcm_player, loop_secs); //device_capture_loop_2_play(capture_handle, player_handle, c_rate, loop_secs, port, c_idx); device_capture(capture_handle, player_handle, c_rate, loop_secs, port, c_idx); #ifdef LOOP snd_pcm_drain(player_handle); snd_pcm_close(player_handle); #endif snd_pcm_drain(capture_handle); snd_pcm_close(capture_handle); //fprintf (stdout, "End OK\n"); out_err: if(buff0) free(buff0); if(buff1) free(buff1); if(hw_params0) snd_pcm_hw_params_free(hw_params0); if(hw_params1) snd_pcm_hw_params_free(hw_params1); return 0; }