zoukankan      html  css  js  c++  java
  • ALSA lib调用实例

    1. Display Some PCM Types and Formats

    #include <alsa/asoundlib.h>  
      
    int main() {  
      int val;  
      
      printf("ALSA library version: %s
    ",  
              SND_LIB_VERSION_STR);  
      
      printf("
    PCM stream types:
    ");  
      for (val = 0; val <= SND_PCM_STREAM_LAST; val++)  
        printf("  %s
    ",  
          snd_pcm_stream_name((snd_pcm_stream_t)val));  
      
      printf("
    PCM access types:
    ");  
      for (val = 0; val <= SND_PCM_ACCESS_LAST; val++)  
        printf("  %s
    ",  
          snd_pcm_access_name((snd_pcm_access_t)val));  
      
      printf("
    PCM formats:
    ");  
      for (val = 0; val <= SND_PCM_FORMAT_LAST; val++)  
        if (snd_pcm_format_name((snd_pcm_format_t)val)  
          != NULL)  
          printf("  %s (%s)
    ",  
            snd_pcm_format_name((snd_pcm_format_t)val),  
            snd_pcm_format_description(  
                               (snd_pcm_format_t)val));  
      
      printf("
    PCM subformats:
    ");  
      for (val = 0; val <= SND_PCM_SUBFORMAT_LAST;  
           val++)  
        printf("  %s (%s)
    ",  
          snd_pcm_subformat_name((  
            snd_pcm_subformat_t)val),  
          snd_pcm_subformat_description((  
            snd_pcm_subformat_t)val));  
      
      printf("
    PCM states:
    ");  
      for (val = 0; val <= SND_PCM_STATE_LAST; val++)  
        printf("  %s
    ",  
               snd_pcm_state_name((snd_pcm_state_t)val));  
      
      return 0;  
    }  


    2. Opening PCM Device and Setting Parameters

    /* 
     
    This example opens the default PCM device, sets 
    some parameters, and then displays the value 
    of most of the hardware parameters. It does not 
    perform any sound playback or recording. 
     
    */  
      
    /* Use the newer ALSA API */  
    #define ALSA_PCM_NEW_HW_PARAMS_API  
      
    /* All of the ALSA library API is defined 
     * in this header */  
    #include <alsa/asoundlib.h>  
      
    int main() {  
      int rc;  
      snd_pcm_t *handle;  
      snd_pcm_hw_params_t *params;  
      unsigned int val, val2;  
      int dir;  
      snd_pcm_uframes_t frames;  
      
      /* Open PCM device for playback. */  
      rc = snd_pcm_open(&handle, "default",  
                        SND_PCM_STREAM_PLAYBACK, 0);  
      if (rc < 0) {  
        fprintf(stderr,  
                "unable to open pcm device: %s
    ",  
                snd_strerror(rc));  
        exit(1);  
      }  
      
      /* Allocate a hardware parameters object. */  
      snd_pcm_hw_params_alloca(¶ms);  
      
      /* Fill it in with default values. */  
      snd_pcm_hw_params_any(handle, params);  
      
      /* Set the desired hardware parameters. */  
      
      /* Interleaved mode */  
      snd_pcm_hw_params_set_access(handle, params,  
                          SND_PCM_ACCESS_RW_INTERLEAVED);  
      
      /* Signed 16-bit little-endian format */  
      snd_pcm_hw_params_set_format(handle, params,  
                                  SND_PCM_FORMAT_S16_LE);  
      
      /* Two channels (stereo) */  
      snd_pcm_hw_params_set_channels(handle, params, 2);  
      
      /* 44100 bits/second sampling rate (CD quality) */  
      val = 44100;  
      snd_pcm_hw_params_set_rate_near(handle,  
                                     params, &val, &dir);  
      
      /* Write the parameters to the driver */  
      rc = snd_pcm_hw_params(handle, params);  
      if (rc < 0) {  
        fprintf(stderr,  
                "unable to set hw parameters: %s
    ",  
                snd_strerror(rc));  
        exit(1);  
      }  
      
      /* Display information about the PCM interface */  
      
      printf("PCM handle name = '%s'
    ",  
             snd_pcm_name(handle));  
      
      printf("PCM state = %s
    ",  
             snd_pcm_state_name(snd_pcm_state(handle)));  
      
      snd_pcm_hw_params_get_access(params,  
                              (snd_pcm_access_t *) &val);  
      printf("access type = %s
    ",  
             snd_pcm_access_name((snd_pcm_access_t)val));  
      
      snd_pcm_hw_params_get_format(params, &val);  
      printf("format = '%s' (%s)
    ",  
        snd_pcm_format_name((snd_pcm_format_t)val),  
        snd_pcm_format_description(  
                                 (snd_pcm_format_t)val));  
      
      snd_pcm_hw_params_get_subformat(params,  
                            (snd_pcm_subformat_t *)&val);  
      printf("subformat = '%s' (%s)
    ",  
        snd_pcm_subformat_name((snd_pcm_subformat_t)val),  
        snd_pcm_subformat_description(  
                              (snd_pcm_subformat_t)val));  
      
      snd_pcm_hw_params_get_channels(params, &val);  
      printf("channels = %d
    ", val);  
      
      snd_pcm_hw_params_get_rate(params, &val, &dir);  
      printf("rate = %d bps
    ", val);  
      
      snd_pcm_hw_params_get_period_time(params,  
                                        &val, &dir);  
      printf("period time = %d us
    ", val);  
      
      snd_pcm_hw_params_get_period_size(params,  
                                        &frames, &dir);  
      printf("period size = %d frames
    ", (int)frames);  
      
      snd_pcm_hw_params_get_buffer_time(params,  
                                        &val, &dir);  
      printf("buffer time = %d us
    ", val);  
      
      snd_pcm_hw_params_get_buffer_size(params,  
                             (snd_pcm_uframes_t *) &val);  
      printf("buffer size = %d frames
    ", val);  
      
      snd_pcm_hw_params_get_periods(params, &val, &dir);  
      printf("periods per buffer = %d frames
    ", val);  
      
      snd_pcm_hw_params_get_rate_numden(params,  
                                        &val, &val2);  
      printf("exact rate = %d/%d bps
    ", val, val2);  
      
      val = snd_pcm_hw_params_get_sbits(params);  
      printf("significant bits = %d
    ", val);  
      
      snd_pcm_hw_params_get_tick_time(params,  
                                      &val, &dir);  
      printf("tick time = %d us
    ", val);  
      
      val = snd_pcm_hw_params_is_batch(params);  
      printf("is batch = %d
    ", val);  
      
      val = snd_pcm_hw_params_is_block_transfer(params);  
      printf("is block transfer = %d
    ", val);  
      
      val = snd_pcm_hw_params_is_double(params);  
      printf("is double = %d
    ", val);  
      
      val = snd_pcm_hw_params_is_half_duplex(params);  
      printf("is half duplex = %d
    ", val);  
      
      val = snd_pcm_hw_params_is_joint_duplex(params);  
      printf("is joint duplex = %d
    ", val);  
      
      val = snd_pcm_hw_params_can_overrange(params);  
      printf("can overrange = %d
    ", val);  
      
      val = snd_pcm_hw_params_can_mmap_sample_resolution(params);  
      printf("can mmap = %d
    ", val);  
      
      val = snd_pcm_hw_params_can_pause(params);  
      printf("can pause = %d
    ", val);  
      
      val = snd_pcm_hw_params_can_resume(params);  
      printf("can resume = %d
    ", val);  
      
      val = snd_pcm_hw_params_can_sync_start(params);  
      printf("can sync start = %d
    ", val);  
      
      snd_pcm_close(handle);  
      
      return 0;  
    }  


    3. Simple Sound Playback

    /* 
     
    This example reads standard from input and writes 
    to the default PCM device for 5 seconds of data. 
     
    */  
      
    /* Use the newer ALSA API */  
    #define ALSA_PCM_NEW_HW_PARAMS_API  
      
    #include <alsa/asoundlib.h>  
      
    int main() {  
      long loops;  
      int rc;  
      int size;  
      snd_pcm_t *handle;  
      snd_pcm_hw_params_t *params;  
      unsigned int val;  
      int dir;  
      snd_pcm_uframes_t frames;  
      char *buffer;  
      
      /* Open PCM device for playback. */  
      rc = snd_pcm_open(&handle, "default",  
                        SND_PCM_STREAM_PLAYBACK, 0);  
      if (rc < 0) {  
        fprintf(stderr,  
                "unable to open pcm device: %s
    ",  
                snd_strerror(rc));  
        exit(1);  
      }  
      
      /* Allocate a hardware parameters object. */  
      snd_pcm_hw_params_alloca(¶ms);  
      
      /* Fill it in with default values. */  
      snd_pcm_hw_params_any(handle, params);  
      
      /* Set the desired hardware parameters. */  
      
      /* Interleaved mode */  
      snd_pcm_hw_params_set_access(handle, params,  
                          SND_PCM_ACCESS_RW_INTERLEAVED);  
      
      /* Signed 16-bit little-endian format */  
      snd_pcm_hw_params_set_format(handle, params,  
                                  SND_PCM_FORMAT_S16_LE);  
      
      /* Two channels (stereo) */  
      snd_pcm_hw_params_set_channels(handle, params, 2);  
      
      /* 44100 bits/second sampling rate (CD quality) */  
      val = 44100;  
      snd_pcm_hw_params_set_rate_near(handle, params,  
                                      &val, &dir);  
      
      /* Set period size to 32 frames. */  
      frames = 32;  
      snd_pcm_hw_params_set_period_size_near(handle,  
                                  params, &frames, &dir);  
      
      /* Write the parameters to the driver */  
      rc = snd_pcm_hw_params(handle, params);  
      if (rc < 0) {  
        fprintf(stderr,  
                "unable to set hw parameters: %s
    ",  
                snd_strerror(rc));  
        exit(1);  
      }  
      
      /* Use a buffer large enough to hold one period */  
      snd_pcm_hw_params_get_period_size(params, &frames,  
                                        &dir);  
      size = frames * 4; /* 2 bytes/sample, 2 channels */  
      buffer = (char *) malloc(size);  
      
      /* We want to loop for 5 seconds */  
      snd_pcm_hw_params_get_period_time(params,  
                                        &val, &dir);  
      /* 5 seconds in microseconds divided by 
       * period time */  
      loops = 5000000 / val;  
      
      while (loops > 0) {  
        loops--;  
        rc = read(0, buffer, size);  
        if (rc == 0) {  
          fprintf(stderr, "end of file on input
    ");  
          break;  
        } else if (rc != size) {  
          fprintf(stderr,  
                  "short read: read %d bytes
    ", rc);  
        }  
        rc = snd_pcm_writei(handle, buffer, frames);  
        if (rc == -EPIPE) {  
          /* EPIPE means underrun */  
          fprintf(stderr, "underrun occurred
    ");  
          snd_pcm_prepare(handle);  
        } else if (rc < 0) {  
          fprintf(stderr,  
                  "error from writei: %s
    ",  
                  snd_strerror(rc));  
        }  else if (rc != (int)frames) {  
          fprintf(stderr,  
                  "short write, write %d frames
    ", rc);  
        }  
      }  
      
      snd_pcm_drain(handle);  
      snd_pcm_close(handle);  
      free(buffer);  
      
      return 0;  
    }  
     

    编译之后,可以用下面的命令来测试:
    ./example3 < /dev/urandom

    4. Simple Sound Recording

    /* 
     
    This example reads from the default PCM device 
    and writes to standard output for 5 seconds of data. 
     
    */  
      
    /* Use the newer ALSA API */  
    #define ALSA_PCM_NEW_HW_PARAMS_API  
      
    #include <alsa/asoundlib.h>  
      
    int main() {  
      long loops;  
      int rc;  
      int size;  
      snd_pcm_t *handle;  
      snd_pcm_hw_params_t *params;  
      unsigned int val;  
      int dir;  
      snd_pcm_uframes_t frames;  
      char *buffer;  
      
      /* Open PCM device for recording (capture). */  
      rc = snd_pcm_open(&handle, "default",  
                        SND_PCM_STREAM_CAPTURE, 0);  
      if (rc < 0) {  
        fprintf(stderr,  
                "unable to open pcm device: %s
    ",  
                snd_strerror(rc));  
        exit(1);  
      }  
      
      /* Allocate a hardware parameters object. */  
      snd_pcm_hw_params_alloca(¶ms);  
      
      /* Fill it in with default values. */  
      snd_pcm_hw_params_any(handle, params);  
      
      /* Set the desired hardware parameters. */  
      
      /* Interleaved mode */  
      snd_pcm_hw_params_set_access(handle, params,  
                          SND_PCM_ACCESS_RW_INTERLEAVED);  
      
      /* Signed 16-bit little-endian format */  
      snd_pcm_hw_params_set_format(handle, params,  
                                  SND_PCM_FORMAT_S16_LE);  
      
      /* Two channels (stereo) */  
      snd_pcm_hw_params_set_channels(handle, params, 2);  
      
      /* 44100 bits/second sampling rate (CD quality) */  
      val = 44100;  
      snd_pcm_hw_params_set_rate_near(handle, params,  
                                      &val, &dir);  
      
      /* Set period size to 32 frames. */  
      frames = 32;  
      snd_pcm_hw_params_set_period_size_near(handle,  
                                  params, &frames, &dir);  
      
      /* Write the parameters to the driver */  
      rc = snd_pcm_hw_params(handle, params);  
      if (rc < 0) {  
        fprintf(stderr,  
                "unable to set hw parameters: %s
    ",  
                snd_strerror(rc));  
        exit(1);  
      }  
      
      /* Use a buffer large enough to hold one period */  
      snd_pcm_hw_params_get_period_size(params,  
                                          &frames, &dir);  
      size = frames * 4; /* 2 bytes/sample, 2 channels */  
      buffer = (char *) malloc(size);  
      
      /* We want to loop for 5 seconds */  
      snd_pcm_hw_params_get_period_time(params,  
                                             &val, &dir);  
      loops = 5000000 / val;  
      
      while (loops > 0) {  
        loops--;  
        rc = snd_pcm_readi(handle, buffer, frames);  
        if (rc == -EPIPE) {  
          /* EPIPE means overrun */  
          fprintf(stderr, "overrun occurred
    ");  
          snd_pcm_prepare(handle);  
        } else if (rc < 0) {  
          fprintf(stderr,  
                  "error from read: %s
    ",  
                  snd_strerror(rc));  
        } else if (rc != (int)frames) {  
          fprintf(stderr, "short read, read %d frames
    ", rc);  
        }  
        rc = write(1, buffer, size);  
        if (rc != size)  
          fprintf(stderr,  
                  "short write: wrote %d bytes
    ", rc);  
      }  
      
      snd_pcm_drain(handle);  
      snd_pcm_close(handle);  
      free(buffer);  
      
      return 0;  
    }  

    录音使用下面的命令测试:
    ./listing4 > sound.raw
    ./listing3 < sound.raw

    5. wav格式文件播放测试
    这个例子是我根据例子3修改而来的,用来播放wav格式音频文件,注意wav文件格式必须是44100、16bit, 2通道。

    #include <alsa/asoundlib.h>  
      
    int main(int argc, char *argv[])  
    {  
        int rc;  
        int size;  
        snd_pcm_t *handle;  
        snd_pcm_hw_params_t *params;  
        unsigned int val;  
        int dir;  
        snd_pcm_uframes_t frames;  
        char *buffer;  
        FILE *fp;  
          
        fp = fopen(argv[1], "rb");  
        if (!fp) {  
            fprintf(stderr,  
                "can't open sound file
    ");  
            exit(1);  
        }  
      
        /* Open PCM device for playback. */  
        rc = snd_pcm_open(&handle, "default",  
                SND_PCM_STREAM_PLAYBACK, 0);  
        if (rc < 0) {  
            fprintf(stderr,  
                "unable to open pcm device: %s
    ",  
                snd_strerror(rc));  
            exit(1);  
        }  
      
        /* Allocate a hardware parameters object. */  
        snd_pcm_hw_params_alloca(¶ms);  
      
        /* Fill it in with default values. */  
        snd_pcm_hw_params_any(handle, params);  
      
        /* Set the desired hardware parameters. */  
      
        /* Interleaved mode */  
        snd_pcm_hw_params_set_access(handle, params,  
                    SND_PCM_ACCESS_RW_INTERLEAVED);  
      
        /* Signed 16-bit little-endian format */  
        snd_pcm_hw_params_set_format(handle, params,  
                    SND_PCM_FORMAT_S16_LE);  
      
        /* Two channels (stereo) */  
        snd_pcm_hw_params_set_channels(handle, params, 2);  
      
        /* 44100 bits/second sampling rate (CD quality) */  
        val = 44100;  
        snd_pcm_hw_params_set_rate_near(handle, params,  
                        &val, &dir);  
      
        /* Set period size to 32 frames. */  
        frames = 32;  
        snd_pcm_hw_params_set_period_size_near(handle,  
                        params, &frames, &dir);  
      
        /* Write the parameters to the driver */  
        rc = snd_pcm_hw_params(handle, params);  
        if (rc < 0) {  
            fprintf(stderr,  
                "unable to set hw parameters: %s
    ",  
                snd_strerror(rc));  
            exit(1);  
        }  
      
        /* Use a buffer large enough to hold one period */  
        snd_pcm_hw_params_get_period_size(params,  
                        &frames, &dir);  
        size = frames * 4; /* 2 bytes/sample, 2 channels */  
        buffer = (char *)malloc(size);  
      
        fseek(fp, 44, SEEK_SET);  
        while (1) {  
            rc = fread(buffer, 1, size, fp);  
            if (rc == 0) {  
                fprintf(stderr, "end of file on input
    ");  
                break;  
            } else if (rc != size) {  
                fprintf(stderr,  
                    "short read: read %d bytes
    ", rc);  
            }  
            rc = snd_pcm_writei(handle, buffer, frames);  
            if (rc == -EPIPE) {  
                /* EPIPE means underrun */  
                fprintf(stderr, "underrun occurred
    ");  
                snd_pcm_prepare(handle);  
            } else if (rc < 0) {  
                fprintf(stderr,  
                    "error from writei: %s
    ",  
                    snd_strerror(rc));  
            } else if (rc != (int)frames) {  
                fprintf(stderr,  
                    "short write, write %d frames
    ", rc);  
            }  
        }  
      
        snd_pcm_drain(handle);  
        snd_pcm_close(handle);  
        fclose(fp);  
        free(buffer);  
      
        return 0;  
    }  
     


    参考:http://www.linuxjournal.com/article/6735

  • 相关阅读:
    使用docker搭建gitlab版本控制系统
    Spring Boot与Docker部署
    CentOS7 使用yum命令安装Java SDK(openjdk)
    配置带用户权限的docker registry v2
    Docker搭建带有访问认证的私有仓库
    CentOS7 关闭防火墙
    CentOS7.2网络配置
    Docker Machine 简介
    docker的常用命令汇总
    实时查看docker容器日志
  • 原文地址:https://www.cnblogs.com/Ph-one/p/6802568.html
Copyright © 2011-2022 走看看