Raspberry-Pi

在樹莓派零作業系統中編譯 ALSA 項目的 pcm.c 範例時出現問題

  • October 13, 2021

我正在使用帶有最新樹莓派作業系統的樹莓派零 W

我已經安裝了 libasound2 和 libasound2-dev,並且我從樹莓派論壇上下載的用於測試 alsa 庫的程式碼編譯並正確執行:

#include <stdio.h>
#include <stdlib.h>
#include <alsa/asoundlib.h>
#include <alsa/pcm.h>

int main() {
 int val;

 printf("ALSA library version: %s\n", SND_LIB_VERSION_STR);

 printf("\nPCM stream types:\n");
 for (val = 0; val <= SND_PCM_STREAM_LAST; val++)
   printf("  %s\n",
     snd_pcm_stream_name((snd_pcm_stream_t)val));

 return 0;
}  

我正在嘗試在此處編譯 ALSA 項目網站中提供的正弦波生成範常式式碼:https ://www.alsa-project.org/alsa-doc/alsa-lib/_2test_2pcm_8c-example.html

這在他們的範例頁面中列為 pcm.c

我已將此程式碼保存在 main.cpp 中,並且我已更改#include "../include/asoundlib.h"(這會導致編譯時找不到文件錯誤)為#include <alsa/asoundlib.h>

我使用gcc main.cpp -o main -lasound -fpermissive. 我收到一系列警告,但最後for (format = 0; format < SND_PCM_FORMAT_LAST; format++) {在它說有的行出現錯誤,no match for operator++並且operand type is 'snd_pcm_format_t' {aka '_snd_pcm_format'}). 但是根據他們的文件format已被聲明為static snd_pcm_format_t format = SND_PCM_FORMAT_S16;並且snd_pcm_format_t是一個列舉。

我需要做什麼才能編譯這個基本範例?或者是否有一個更簡單的範例展示如何使用 C++ 在 ALSA 中生成正弦音,或者有一些部落格或教程解釋了 ALSA 的這個範常式式碼是如何工作的?

編輯:這些是在建構過程中看到的消息:[error is main.cpp:842:66: error: no match for ‘operator++’ ]

$ gcc main.cpp -o Main -lasound -fpermissive
main.cpp:19:23: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
static char *device = "plughw:0,0";         /* playback device */
                      ^~~~~~~~~~~~
main.cpp: In function ‘int write_and_poll_loop(snd_pcm_t*, short int*, snd_pcm_channel_area_t*)’:
main.cpp:314:18: warning: invalid conversion from ‘void*’ to ‘pollfd*’ [-fpermissive]
    ufds = malloc(sizeof(struct pollfd) * count);
           ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp: In function ‘void async_callback(snd_async_handler_t*)’:
main.cpp:397:77: warning: invalid conversion from ‘void*’ to ‘async_private_data*’ [-fpermissive]
ct async_private_data *data = snd_async_handler_get_callback_private(ahandler);
                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~

main.cpp: In function ‘void async_direct_callback(snd_async_handler_t*)’:
main.cpp:469:77: warning: invalid conversion from ‘void*’ to ‘async_private_data*’ [-fpermissive]
ct async_private_data *data = snd_async_handler_get_callback_private(ahandler);
                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~

main.cpp: In function ‘void help()’:
main.cpp:756:53: warning: invalid conversion from ‘int’ to ‘snd_pcm_format_t’ {aka ‘_snd_pcm_format’} [-fpermissive]
                const char *s = snd_pcm_format_name(k);
                                                    ^
In file included from /usr/include/alsa/asoundlib.h:54,
                from main.cpp:14:
/usr/include/alsa/pcm.h:1065:56: note:   initializing argument 1 of ‘const char* snd_pcm_format_name(snd_pcm_format_t)’
const char *snd_pcm_format_name(const snd_pcm_format_t format);
                                ~~~~~~~~~~~~~~~~~~~~~~~^~~~~~
main.cpp: In function ‘int main(int, char**)’:
main.cpp:842:27: warning: invalid conversion from ‘int’ to ‘snd_pcm_format_t’ {aka ‘_snd_pcm_format’} [-fpermissive]
            for (format = 0; format < SND_PCM_FORMAT_LAST; format++) {
                          ^
main.cpp:842:66: warning: no ‘operator++(int)’ declared for postfix ‘++’, trying prefix operator instead [-fpermissive]
            for (format = 0; format < SND_PCM_FORMAT_LAST; format++) {
                                                           ~~~~~~^~
main.cpp:842:66: error: no match for ‘operator++’ (operand type is ‘snd_pcm_format_t’ {aka ‘_snd_pcm_format’})
main.cpp:903:21: warning: invalid conversion from ‘void*’ to ‘short int*’ [-fpermissive]
    samples = malloc((period_size * channels * snd_pcm_format_physical_width(format)) / 8);
              ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:909:19: warning: invalid conversion from ‘void*’ to ‘snd_pcm_channel_area_t*’ {aka ‘_snd_pcm_channel_area*’} [-fpermissive]
    areas = calloc(channels, sizeof(snd_pcm_channel_area_t));
            ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$  

使用 g++ 而不是 gcc 會產生相同的錯誤

您正在嘗試將其編譯為 C++ 程序(“ISO C++ 禁止 …”)。因此,您會收到各種警告,因為包含的標頭是 C,而不是 C++。

重命名main.cppmain.c,以便將其編譯為 C 程序,或使用正確的 C++ 方式將 C 頭包含包裝到extern "C"中,然後使用g++,並確保您自己的程式碼符合 C++ 標準。

引用自:https://unix.stackexchange.com/questions/672980