zoukankan      html  css  js  c++  java
  • Linux ALSA音频PCM播放编程

    使用ALSA播放两个频率的单音,并使用GNU Radio中的Audio Source和FFT来观测声音的频谱。

      1 #include <alsa/asoundlib.h>
      2 #include <math.h>
      3 #include <inttypes.h>
      4 
      5 int main(int argc, char **argv)
      6 {
      7     long loops;
      8     snd_pcm_t *handle;
      9     snd_pcm_hw_params_t *params;
     10     snd_pcm_uframes_t frames;
     11     unsigned int val;
     12     int rc;
     13     int size;
     14     int dir;
     15     char *buffer;
     16 
     17     /* Open PCM device for playback. */
     18     rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
     19     if (rc < 0) {
     20         fprintf(stderr, "unable to open pcm device: %s
    ", snd_strerror(rc));
     21         exit(1);
     22     }
     23 
     24     /* Allocate a hardware parameters object. */
     25     snd_pcm_hw_params_alloca(&params);
     26 
     27     /* Fill it in with default values. */
     28     snd_pcm_hw_params_any(handle, params);
     29 
     30     /* Interleaved mode */
     31     snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
     32     /* Signed 16-bit format */
     33     snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16);
     34     /* Two channels (stereo) */
     35     snd_pcm_hw_params_set_channels(handle, params, 2);
     36     /* 16000 samples/second sampling rate */
     37     val = 16000;
     38     snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir);
     39     /* Set period size to 32 frames. */
     40     frames = 32;
     41     snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir);
     42 
     43     /* Write the parameters to the driver */
     44     rc = snd_pcm_hw_params(handle, params);
     45     if (rc < 0) {
     46         fprintf(stderr, "unable to set hw parameters: %s
    ", snd_strerror(rc));
     47         exit(1);
     48     }
     49 
     50     /* Use a buffer large enough to hold one period */
     51     snd_pcm_hw_params_get_period_size(params, &frames, &dir);
     52 
     53     size = frames * 2 * 2; /* 2 bytes/sample, 2 channels */
     54 
     55     buffer = (char *) malloc(size);
     56     if(buffer == NULL) {
     57         fprintf(stderr, "Not enough Memory!
    ");
     58         exit(1);
     59     }
     60 
     61     /* We want to loop for 15 seconds */
     62     snd_pcm_hw_params_get_period_time(params, &val, &dir);
     63 
     64     /* 15 seconds in microseconds divided by period time */
     65     loops = 15000000 / val;
     66 
     67     for (size_t i = 0; i < size; i += 4) {
     68         // Generate a 500Hz tone
     69         *((int16_t *)(buffer + i)) = (uint16_t)(16384.0*sin(i*2.0*M_PI/size));
     70         *((int16_t *)(buffer + i + 2)) = (uint16_t)(16384.0*sin(i*2.0*M_PI/size));
     71         // Generate a 2kHz tone
     72         *((int16_t *)(buffer + i)) += (uint16_t)(16384.0*sin(i*8.0*M_PI/size));
     73         *((int16_t *)(buffer + i + 2)) += (uint16_t)(16384.0*sin(i*8.0*M_PI/size));
     74     }
     75 
     76     while (loops > 0) {
     77         loops--;
     78         //rc = read(0, buffer, size);
     79         //if (rc == 0) {
     80         //    fprintf(stderr, "end of file on input
    ");
     81         //    break;
     82         //} else if (rc != size) {
     83         //    fprintf(stderr, "short read: read %d bytes
    ", rc);
     84         //}
     85 
     86         rc = snd_pcm_writei(handle, buffer, frames);
     87         if (rc == -EPIPE) {
     88             /* EPIPE means underrun */
     89             fprintf(stderr, "underrun occurred
    ");
     90             snd_pcm_prepare(handle);
     91         } else if (rc < 0) {
     92             fprintf(stderr,"error from writei: %s
    ", snd_strerror(rc));
     93         } else if (rc != (int)frames) {
     94             fprintf(stderr,"short write, write %d frames
    ", rc);
     95         }
     96     }
     97     snd_pcm_drop(handle);
     98     snd_pcm_drain(handle);
     99     snd_pcm_close(handle);
    100     free(buffer);
    101     return 0;
    102 }

  • 相关阅读:
    MySql 数据备份与还原
    PHP 连接数据库
    迭代法写线性回归
    ML numpy、pandas、matplotlib的使用
    005 动态加载实例
    爬虫实现案例
    004 使用scrapy框架爬虫
    003 爬虫持久化的三个不同数据库的python代码
    内置函数和匿名函数
    迭代器和生成器
  • 原文地址:https://www.cnblogs.com/lyuyangly/p/7709011.html
Copyright © 2011-2022 走看看