【问题标题】:ALSA in C++ - Making the minimal working codeC++ 中的 ALSA - 制作最少的工作代码
【发布时间】:2020-12-11 03:01:18
【问题描述】:

主题

我想为C++ 中的C++ 生成任何类型的PCM 声音,用于Linux 计算机。

设置

我在Code::Blocks 上用Ubuntu 20.04 编码C++

背景

我曾经制作简单的Arduino UNO 程序进行声音处理,只需要播放原始 PCM 样本

问题

ALSA Project's Website不太好理解。

我查看了c - ALSA tutorial required,发现很多链接都已过期。

我将minimal PCM example in C 的代码直接复制粘贴到一个空的Code::Blocks 项目中,我得到了那个错误:

||=== Build: Release in Test (compiler: GNU GCC Compiler) ===|
Test/main.cpp|5|fatal error: ../include/asoundlib.h: No such file or directory|
||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

就在代码的第一行#include "../include/asoundlib.h"。 我猜这个问题可能是因为我必须下载一些东西或为编译器添加链接器
但我也认为它可能是 C 到 C++ 转换的问题,这意味着这在 C 中有效,但在 C++ 中无效。

我是否必须为编译器添加链接器或下载一些东西才能使the code 工作?

然后我查看了ALSA library并下载了alsa-lib-1.2.3.tar.bz2
我有一个档案,看起来有正确的东西,但我不知道如何处理它。

然后我在我的电脑上找到了usr/include/sound/asound.h。它看起来是 ALSA 的一部分,但是当我更改代码以使用它时,它在使用时会吐出一堆错误。
现在的代码如下所示:

/*
 *  This extra small demo sends a random samples to your speakers.
 */
#include <sound/asound.h>
#include <cstdio>
static char *device = "default";            /* playback device */
unsigned char buffer[16*1024];              /* some random data */
int main(void)
{
    int err;
    unsigned int i;
    snd_pcm_t *handle;
    snd_pcm_sframes_t frames;
    for (i = 0; i < sizeof(buffer); i++)
        buffer[i] = random() & 0xff;
    if ((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
        printf("Playback open error: %s\n", snd_strerror(err));
        exit(EXIT_FAILURE);
    }
    if ((err = snd_pcm_set_params(handle,
                      SND_PCM_FORMAT_U8,
                      SND_PCM_ACCESS_RW_INTERLEAVED,
                      1,
                      48000,
                      1,
                      500000)) < 0) {   /* 0.5sec */
        printf("Playback open error: %s\n", snd_strerror(err));
        exit(EXIT_FAILURE);
    }
        for (i = 0; i < 16; i++) {
        frames = snd_pcm_writei(handle, buffer, sizeof(buffer));
        if (frames < 0)
            frames = snd_pcm_recover(handle, frames, 0);
        if (frames < 0) {
            printf("snd_pcm_writei failed: %s\n", snd_strerror(frames));
            break;
        }
        if (frames > 0 && frames < (long)sizeof(buffer))
            printf("Short write (expected %li, wrote %li)\n", (long)sizeof(buffer), frames);
    }
    /* pass the remaining samples, otherwise they're dropped in close */
    err = snd_pcm_drain(handle);
    if (err < 0)
        printf("snd_pcm_drain failed: %s\n", snd_strerror(err));
    snd_pcm_close(handle);
    return 0;
}

错误是这样的:

||=== Build: Release in Test (compiler: GNU GCC Compiler) ===|
Test/main.cpp|6|warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]|
Test/main.cpp||In function ‘int main()’:|
Test/main.cpp|12|error: ‘snd_pcm_t’ was not declared in this scope; did you mean ‘snd_pcm_info’?|
Test/main.cpp|12|error: ‘handle’ was not declared in this scope|
Test/main.cpp|16|error: ‘SND_PCM_STREAM_PLAYBACK’ was not declared in this scope; did you mean ‘SNDRV_PCM_STREAM_PLAYBACK’?|
Test/main.cpp|16|error: ‘snd_pcm_open’ was not declared in this scope; did you mean ‘snd_pcm_info’?|
Test/main.cpp|17|error: ‘snd_strerror’ was not declared in this scope|
||error: %s\n", snd_strerror(err));|
Test/main.cpp|21|error: ‘SND_PCM_FORMAT_U8’ was not declared in this scope; did you mean ‘SNDRV_PCM_FORMAT_U8’?|
Test/main.cpp|22|error: ‘SND_PCM_ACCESS_RW_INTERLEAVED’ was not declared in this scope; did you mean ‘SNDRV_PCM_ACCESS_RW_INTERLEAVED’?|
Test/main.cpp|20|error: ‘snd_pcm_set_params’ was not declared in this scope; did you mean ‘snd_pcm_sw_params’?|
Test/main.cpp|27|error: ‘snd_strerror’ was not declared in this scope|
||error: %s\n", snd_strerror(err));|
Test/main.cpp|31|error: ‘snd_pcm_writei’ was not declared in this scope|
Test/main.cpp|33|error: ‘snd_pcm_recover’ was not declared in this scope|
Test/main.cpp|35|error: ‘snd_strerror’ was not declared in this scope|
Test/main.cpp|42|error: ‘snd_pcm_drain’ was not declared in this scope|
Test/main.cpp|44|error: ‘snd_strerror’ was not declared in this scope|
Test/main.cpp|45|error: ‘snd_pcm_close’ was not declared in this scope|
||=== Build failed: 17 error(s), 1 warning(s) (0 minute(s), 0 second(s)) ===|

【问题讨论】:

    标签: c++ c linux alsa


    【解决方案1】:

    按照以下步骤操作:

    1. 安装 ALSA 开发包,或确保它已安装。该名称取决于您的发行版。就我而言(OpenSUSE Tumbleweed),它是 alsa-devel。这将在 /usr/include/alsa 目录下安装文件 asoundlib.h。
    2. 将代码中的行从#include "../include/asoundlib.h" 更改为#include &lt;alsa/asoundlib.h&gt;。注意尖括号而不是引号。
    3. 要链接的库名为 libsound.so,因此请使用gcc -Wall pcm_min.c -lasound -o pcm_min 之类的命令编译程序
    4. 运行程序:./pcm_min

    【讨论】:

    • 感谢您的回答。但是,我很难找到要安装的内容。我不想把事情搞砸,所以,终端中是否有一个精确的位置或命令可以执行?我暂时找到了ALSA project library,我应该如何处理/安装它?顺便说一句,我发现usr/include/sound/asound.h 看起来是 ALSA 的一部分,但在使用时会吐出很多错误。我在 Ubuntu 20.04
    • 在 Ubuntu 中,运行 sudo apt install libasound2-dev,这应该会安装你需要的东西。我上面的指令还是一样的,你需要把源码中的include文件路径改成#include &lt;alsa/asoundlib.h&gt;
    猜你喜欢
    • 2020-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-18
    • 2018-06-07
    • 2018-08-25
    • 1970-01-01
    相关资源
    最近更新 更多