C++ 中的 ALSA - 制作最小的工作代码
ALSA in C++ - Making the minimal working code
话题
我想使用 C++
中的 ALSA
为 Linux
生成任何类型的 PCM 声音计算机。
设置
我在 C++
和 Ubuntu 20.04
上 Code::Blocks
编码。
背景
我曾经制作简单的 Arduino UNO
程序进行 声音处理 并且只需要播放 原始 PCM 样本 .
问题
我查看了 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)) ===|
按照以下步骤操作:
- 安装ALSA开发包,或者确保它已经安装。名称取决于您的发行版。就我而言 (OpenSUSE Tumbleweed),它是 alsa-devel。这将在目录 /usr/include/alsa.
下安装文件 asoundlib.h
- 将代码中的行从
#include "../include/asoundlib.h"
更改为 #include <alsa/asoundlib.h>
。请注意 angular 括号而不是引号。
- 你想要link反对的库被命名为libsound.so,所以用
gcc -Wall pcm_min.c -lasound -o pcm_min
这样的命令编译程序
- 运行 程序:
./pcm_min
话题
我想使用 C++
中的 ALSA
为 Linux
生成任何类型的 PCM 声音计算机。
设置
我在 C++
和 Ubuntu 20.04
上 Code::Blocks
编码。
背景
我曾经制作简单的 Arduino UNO
程序进行 声音处理 并且只需要播放 原始 PCM 样本 .
问题
我查看了 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)) ===|
按照以下步骤操作:
- 安装ALSA开发包,或者确保它已经安装。名称取决于您的发行版。就我而言 (OpenSUSE Tumbleweed),它是 alsa-devel。这将在目录 /usr/include/alsa. 下安装文件 asoundlib.h
- 将代码中的行从
#include "../include/asoundlib.h"
更改为#include <alsa/asoundlib.h>
。请注意 angular 括号而不是引号。 - 你想要link反对的库被命名为libsound.so,所以用
gcc -Wall pcm_min.c -lasound -o pcm_min
这样的命令编译程序
- 运行 程序:
./pcm_min