linux获取音频及播放代码实例

来源:互联网 发布:一小时编程 编辑:程序博客网 时间:2024/05/23 11:55

代码功能:采集441帧然后播放出来

详细功能参考代码:

  1 #include <stdio.h>  2 #include <stdlib.h>  3 #include <alsa/asoundlib.h>  4   5   6 int main(void){  7         /*Name of the PCM device ,like "default"*/  8         char    *dev_name;  9         int     rate = 44100;/*Sample rate*/ 10         int     exact_rate;/*Sample rate returned by*/ 11         int     dir;/*(1)exact_rate == rate --> dir=0,(2)exact_rate < rate --> dir=-1,(3)exact_rate > rate*/ 12         int     periods = 3;/*Number of periods*/ 13         int     err; 14         int     size; 15         int     pcmreturn; 16 //      snd_pcm_uframes_t       periodsize = 8192; 17         snd_pcm_uframes_t       periodsize = 441; 18         snd_pcm_t       *play_handle; 19         snd_pcm_t       *capture_handle; 20         snd_pcm_stream_t        play_stream = SND_PCM_STREAM_PLAYBACK; 21         snd_pcm_stream_t        capture_stream = SND_PCM_STREAM_CAPTURE; 22         /*This structure contains information about */ 23         /*the hardware and can be used to specify the */ 24         /*configuration to be used for the PCM stream*/ 25         snd_pcm_hw_params_t     *hwparams; 26         snd_pcm_hw_params_t     *c_hwparams; 27         /*Init dev_name, Of course, later you will make this configure*/ 28         dev_name = strdup("default"); 29         /*Allocate the snd_pcm_hw_params_t structure on the stack*/ 30         snd_pcm_hw_params_alloca(&hwparams); 31         snd_pcm_hw_params_alloca(&c_hwparams); 32         /* Open PCM. The last parameter of this function is the mode. */ 33         /* If this is set to 0, the standard mode is used. Possible   */ 34         /* other values are SND_PCM_NONBLOCK and SND_PCM_ASYNC.       */ 35         /* If SND_PCM_NONBLOCK is used, read / write access to the    */ 36         /* PCM device will return immediately. If SND_PCM_ASYNC is    */ 37         /* specified, SIGIO will be emitted whenever a period has     */ 38         /* been completely processed by the soundcard.                */ 39         if (snd_pcm_open(&play_handle, dev_name, play_stream, 0) < 0) { 40                 fprintf(stderr, "Error opening PCM device %s\n", dev_name); 41                 return(-1); 42         } 43         if (snd_pcm_open(&capture_handle, dev_name, capture_stream, 0) < 0) { 44                 fprintf(stderr, "Error opening PCM device %s\n", dev_name); 45                 return(-1); 46         } 47         /* Init hwparams with full configuration space */ 48         if (snd_pcm_hw_params_any(play_handle, hwparams) < 0) { 49                 fprintf(stderr, "Can not configure this PCM device.\n"); 50                 return(-1); 51         } 52         if (snd_pcm_hw_params_any(capture_handle, c_hwparams) < 0) { 53                 fprintf(stderr, "Can not configure this PCM device.\n"); 54                 return(-1); 55         } 56         /* Set access type. This can be either    */ 57         /* SND_PCM_ACCESS_RW_INTERLEAVED or       */ 58         /* SND_PCM_ACCESS_RW_NONINTERLEAVED.      */ 59         /* There are also access types for MMAPed */ 60         /* access, but this is beyond the scope   */ 61         /* of this introduction.                  */ 62         if (snd_pcm_hw_params_set_access(play_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) { 63                 fprintf(stderr, "Error setting access.\n"); 64                 return(-1); 65         } 66         if (snd_pcm_hw_params_set_access(capture_handle, c_hwparams, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) { 67                 fprintf(stderr, "Error setting access.\n"); 68                 return(-1); 69         } 70         /* Set sample format */ 71         if (snd_pcm_hw_params_set_format(play_handle, hwparams, SND_PCM_FORMAT_S16_LE) < 0) { 72                 fprintf(stderr, "Error setting format.\n"); 73                 return(-1); 74         } 75         if (snd_pcm_hw_params_set_format(capture_handle, c_hwparams, SND_PCM_FORMAT_S16_LE) < 0) { 76                 fprintf(stderr, "Error setting format.\n"); 77                 return(-1); 78         } 79         exact_rate = rate; 80         if (snd_pcm_hw_params_set_rate_near(play_handle, hwparams, &exact_rate, 0) < 0) { 81                 fprintf(stderr, "Error setting rate.\n"); 82                 return(-1); 83         } 84         if (rate != exact_rate) { 85                 fprintf(stderr, "The rate %d Hz is not supported by your hardware.\ 86                        ==> Using %d Hz instead.\n", rate, exact_rate); 87         } 88         exact_rate = rate; 89         if (snd_pcm_hw_params_set_rate_near(capture_handle, c_hwparams, &exact_rate, 0) < 0) { 90                 fprintf(stderr, "Error setting rate.\n"); 91                 return(-1); 92         } 93         if (rate != exact_rate) { 94                 fprintf(stderr, "The rate %d Hz is not supported by your hardware.\ 95                        ==> Using %d Hz instead.\n", rate, exact_rate); 96         } 97  98         /* Set number of channels */ 99         if (snd_pcm_hw_params_set_channels(play_handle, hwparams, 2) < 0) {100                 fprintf(stderr, "Error setting channels.\n");101                 return(-1);102         }103         if (snd_pcm_hw_params_set_channels(capture_handle, c_hwparams, 2) < 0) {104                 fprintf(stderr, "Error setting channels.\n");105                 return(-1);106         }107 108         /* Set number of periods. Periods used to be called fragments. */109         if (snd_pcm_hw_params_set_periods(play_handle, hwparams, periods, 0) < 0) {110                 fprintf(stderr, "Error setting periods.\n");111                 return(-1);112         }113         if (snd_pcm_hw_params_set_periods(capture_handle, c_hwparams, periods, 0) < 0) {114                 fprintf(stderr, "Error setting periods.\n");115                 return(-1);116         }117         /* Set buffer size (in frames). The resulting latency is given by */118         /* latency = periodsize * periods / (rate * bytes_per_frame)     */119 //      if(snd_pcm_hw_params_get_buffer_size_max(hwparams,&periodsize) < 0)120 //      {121 //              fprintf(stderr,"Error get buffer size\n");122 //      }123 //      printf("periodsize=%lu\n",periodsize);124 125         if (snd_pcm_hw_params_set_buffer_size(play_handle, hwparams, (periodsize * periods)) < 0) {126                 fprintf(stderr, "Error setting buffersize.\n");127                 return(-1);128         }129         if (snd_pcm_hw_params_set_buffer_size(capture_handle, c_hwparams, (periodsize * periods)) < 0) {130                 fprintf(stderr, "Error setting buffersize.\n");131                 return(-1);132         }133         /* Apply HW parameter settings to */134         /* PCM device and prepare device  */135         if (snd_pcm_hw_params(play_handle, hwparams) < 0) {136                 fprintf(stderr, "Error setting HW params.\n");137                 return(-1);138         }139         if (snd_pcm_hw_params(capture_handle, c_hwparams) < 0) {140                 fprintf(stderr, "Error setting HW params.\n");141                 return(-1);142         }143 //      snd_pcm_hw_params_free(hwparams);144 //      snd_pcm_hw_params_free(c_hwparams);145         if ((err = snd_pcm_prepare (play_handle)) < 0) {146                 fprintf (stderr, "cannot prepare audio interface for use (%s)\n",147                                  snd_strerror (err));148                 exit (1);149         }150         if ((err = snd_pcm_prepare (capture_handle)) < 0) {151                 fprintf (stderr, "cannot prepare audio interface for use (%s)\n",152                                  snd_strerror (err));153                 exit (1);154         }155         snd_pcm_hw_params_get_period_size(c_hwparams, &periods,0);156         printf("periods=%d\n",periods);157         char *data_buf = (char*)malloc(periods*4);158         if(!data_buf){159                 fprintf(stderr, "Cannot malloc buffer for data\n");160         }161         while(1)162 163         {164                 pcmreturn = snd_pcm_readi( capture_handle, data_buf, periodsize);165                 if( pcmreturn == -EPIPE )166                 {167                         snd_pcm_prepare( capture_handle );168                         fprintf (stderr, "<<<<<<<<<<<<<<<<<<< Buffer Overrun >>>>>>>>>>>>>>>>>\n");169                         continue;170                 }else if( pcmreturn == -EBADFD ){171                         fprintf(stderr, "<<<<<<<<<<<<<<<<<<<< readi error -EBADFD >>>>>>>>>>>>>\n");172                         continue;173                 }else if( pcmreturn == -ESTRPIPE ){174                         fprintf(stderr, "<<<<<<<<<<<<<<<<<<<< readi error -ESTRPIPE >>>>>>>>>>>>>\n");175                 }else{176                         pcmreturn = snd_pcm_writei(play_handle, data_buf, pcmreturn);177                         if( pcmreturn == -EPIPE ){178                                 fprintf(stderr, "<<<<<<<<<<<< Buffer Underrun >>>>>>>>>>>>>>\n");179                                 snd_pcm_prepare( play_handle );180                 //              continue;181                         }else if( pcmreturn == -ESTRPIPE ){182                                 fprintf(stderr, "<<<<<<<<<<<< writei error -ESTRPIPE >>>>>>>>>>>\n");183                         }else if( pcmreturn == -EBADFD ){184                                 fprintf(stderr, "<<<<<<<<<<<< writei error -EABDFD >>>>>>>>>>>>\n");185                         }186                 }187                 printf("pcmreturn = %d\n",pcmreturn);188 189 190         }191 192 193 }


1 0