导航

    全志在线开发者论坛

    • 注册
    • 登录
    • 搜索
    • 版块
    • 话题
    • 在线文档
    • 社区主页

    调用ALSA音频采集无法识别库问题

    飞凌嵌入式专区
    1
    2
    1318
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • newcastle
      newcastle LV 6 最后由 编辑

      我的开发环境是全志A40i,用的配套的底板和核心板,按照手册录音放音没有问题。
      之后我想实现的功能是读取录音的数据,并将其转换为指定格式文件输出,同时将数据显示在屏幕上,以波形图的形式,就像录音实时跟踪那种效果
      在已经搭建好源码和交叉编译环境下,我编译一个文件在终端提示找不到#include <alsa/asoundlib.h>文件,是因为这句话没有识别,但是系统实际是已经安装了ALSA库的

      我的源码如下

      #define ALSA_PCM_NEW_HW_PARAMS_API
      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      #include <fcntl.h>
      #include <sys/ioctl.h>
      #include <sys/stat.h>
      #include <sys/types.h>
      #include <unistd.h>
      
      #include <alsa/asoundlib.h>
      
      int main() {
          long loops;
          int rc;
          int size;
          unsigned int val;
          int dir;
          char *buffer;
          snd_pcm_t *handle;
          snd_pcm_hw_params_t *params;
          snd_pcm_uframes_t frames;
      
          /*以录制模式打开*/
          /* 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");
              exit(EXIT_FAILURE);
          }
      
          /*分配一个参数对象*/
          /* Allocate a hardware parameters object. */
          snd_pcm_hw_params_alloca(&#182;ms);
          /*初始化参数对象*/
          /* Fill it in with default values. */
          rc = snd_pcm_hw_params_any(handle, params);
          if (rc < 0) {
              printf("Err\n");
          }
          /* Set the desired hardware parameters. */
      
          /*交错模式*/
          /* Interleaved mode */
          rc = snd_pcm_hw_params_set_access(handle, params,
                                SND_PCM_ACCESS_RW_INTERLEAVED);
          if (rc < 0) {
              printf("Err\n");
          }
          /*PCM格式*/
          /* Signed 16-bit little-endian format */
          rc = snd_pcm_hw_params_set_format(handle, params,
                                        SND_PCM_FORMAT_S16_LE);
          if (rc < 0) {
              printf("Err\n");
          }
          /*设置通道数*/
          /* Two channels (stereo) */
          rc = snd_pcm_hw_params_set_channels(handle, params, 2);
          if (rc < 0) {
              printf("Err\n");
          }
          /*设置采样率*/
          /* 44100 bits/second sampling rate (CD quality) */
          val = 44100;
          rc = snd_pcm_hw_params_set_rate_near(handle, params,
                                      &val, &dir);
          if (rc < 0) {
              printf("Err\n");
          }
          /*没周期的帧数*/
          /* Set period size to 32 frames. */
          frames = 32;
          rc = snd_pcm_hw_params_set_period_size_near(handle,
                                  params, &frames, &dir);
          if (rc < 0) {
              printf("Err\n");
          }
          /* Write the parameters to the driver */
          rc = snd_pcm_hw_params(handle, params);
          if (rc < 0) {
              fprintf(stderr,
                      "unable to set hw parameters: %s/n",
                      snd_strerror(rc));
              exit(1);
          }
      
          /* Use a buffer large enough to hold one period */
          rc = snd_pcm_hw_params_get_period_size(params,
                                                &frames, &dir);
          if (rc < 0) {
              printf("Err\n");
          }
          size = frames * 4; /* 2 bytes/sample, 2 channels */
          buffer = (char *) malloc(size);
      
          /* We want to loop for 5 seconds */
          rc = 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/n");
                //把PCM流置于PREPARED状态,这样下次我们向该PCM流中数据时,它就能重新开始处理数据。
                snd_pcm_prepare(handle);
              } else if (rc < 0) {
                fprintf(stderr,
                        "error from read: %s/n",
                        snd_strerror(rc));
              } else if (rc != (int)frames) {
                fprintf(stderr, "short read, read %d frames/n", rc);
              }
              rc = write(1, buffer, size);
              if (rc != size)
                fprintf(stderr,
                        "short write: wrote %d bytes/n", rc);
          }
      
          //调用snd_pcm_drain把所有挂起没有传输完的声音样本传输完全
          rc = snd_pcm_drain(handle);
          //关闭该音频流,释放之前动态分配的缓冲区,退出
          rc = snd_pcm_close(handle);
          free(buffer);
      
          return 0;
      }
      

      测试文件引用代码如下

      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      #include <fcntl.h>
      #include <sys/ioctl.h>
      #include <sys/stat.h>
      #include <sys/types.h>
      #include <unistd.h>
      

      测试程序说明都没有执行,只是单纯的引用alsa库,都无法编译通过

      newcastle 1 条回复 最后回复 回复 引用 分享 0
      • newcastle
        newcastle LV 6 @newcastle 最后由 编辑

        LIBS +=   -L/root/workspace/allwinner/A40i/bsp/lichee/out/sun8iw11p1/linux/common/buildroot/host/usr/arm-buildroot-linux-gnueabihf/sysroot/usr/lib/ -lasound
        

        在pro文件种添加这句好使了➿

        1 条回复 最后回复 回复 引用 分享 0
        • 1 / 1
        • First post
          Last post

        Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号

        行为准则 | 用户协议 | 隐私权政策