使用麦克风录制时,SDL 音频捕获未检测到任何音频

Posted

技术标签:

【中文标题】使用麦克风录制时,SDL 音频捕获未检测到任何音频【英文标题】:SDL Audio capture does not detect any audio when recording with a microphone 【发布时间】:2021-11-29 05:03:22 【问题描述】:

我正在尝试从我的麦克风录制音频并立即通过我的扬声器播放。我没有做到这一点; SDL 似乎没有检测到音频。

这是我的代码:

#include <SDL2/SDL.h>

#include <stdio.h>
#include <stdlib.h>

static SDL_AudioDeviceID input_dev;
static SDL_AudioDeviceID output_dev;

static Uint8* buffer = 0;
static int in_pos = 0;
static int out_pos = 0;

void cb_in(void *userdata, Uint8 *stream, int len) 
    // If len < 4, the printf below will probably segfault

    SDL_memcpy(stream, buffer + in_pos, len);
    in_pos += len;
    printf("IN:  %d\t%d %d %d %d\n", in_pos, stream[0], stream[1], stream[2], stream[3]);


void cb_out(void *userdata, Uint8 *stream, int len) 
    // If len < 4, the printf below will probably segfault

    if (out_pos >= in_pos) 
        // Output is way ahead of input; fill with emptiness
        memset(buffer + out_pos, 0, len * sizeof(Uint8));
        printf("OUT: %d\t(Empty)\n", out_pos);
     else if (out_pos + len > in_pos) 
        // Output is reaching input; read until reaching input, and leave the rest empty
        memset(buffer + out_pos, 0, len * sizeof(Uint8));
        SDL_memcpy(buffer + out_pos, stream, in_pos - out_pos);
        out_pos = in_pos;
        printf("OUT: %d\t%d %d %d %d (Partial)\n", out_pos, stream[0], stream[1], stream[2], stream[3]);
     else 
        // Input is way ahead of output; read as much as requested
        SDL_memcpy(buffer + out_pos, stream, len);
        out_pos += len;
        printf("OUT: %d\t%d %d %d %d\n", out_pos, stream[0], stream[1], stream[2], stream[3]);
    

    // This is to make sure the output device works
    //for (int i = 0; i < len; i++)
    //    stream[i] = (Uint8) random();


int main() 
    SDL_Init(SDL_INIT_AUDIO);

    // 16Mb should be enough; the test lasts 5 seconds
    buffer = malloc(16777215);

    SDL_Audiospec want_in, want_out, have_in, have_out;

    SDL_zero(want_out);
    want_out.freq = 44100;
    want_out.format = AUDIO_F32;
    want_out.channels = 1;
    want_out.samples = 1024;
    want_out.callback = cb_out;

    output_dev = SDL_OpenAudioDevice(NULL, 0, &want_out, &have_out, SDL_AUDIO_ALLOW_ANY_CHANGE);
    if (output_dev == 0) 
        SDL_Log("Failed to open output: %s", SDL_GetError());
        return 1;
    

    SDL_zero(want_in);
    want_in.freq = 44100;
    want_in.format = AUDIO_F32;
    want_in.channels = 1;
    want_in.samples = 1024;
    want_in.callback = cb_in;

    input_dev = SDL_OpenAudioDevice(NULL, 1, &want_in, &have_in, SDL_AUDIO_ALLOW_ANY_CHANGE);
    if (input_dev == 0) 
        SDL_Log("Failed to open input: %s", SDL_GetError());
        return 1;
    

    SDL_PauseAudioDevice(input_dev, 0);
    SDL_PauseAudioDevice(output_dev, 0);

    SDL_Delay(5000);

    SDL_CloseAudioDevice(output_dev);
    SDL_CloseAudioDevice(input_dev);
    free(buffer);


(注意:为了简洁和可读性,我没有对所有可能的溢出进行检查。)

gcc main.c -lSDL2 -I/usr/include/SDL2/编译这段代码并执行它,程序运行良好;但是,似乎没有从我的麦克风中拾取音频printf 将只显示零。

我已经检查了这些:

    它连接到适当的麦克风。在将 0 替换为 1(以检测正在捕获设备)之后,我列出了所有带有 sn-p here (archive) 的可用设备,并手动使程序专门使用 @987654326 选择该设备@ 我的麦克风工作正常,录音声音很大;我用多个其他应用程序对其进行了测试,没有其他问题。

我正在使用 Ubuntu 20.04 和 Pulseaudio 13.99.1。

【问题讨论】:

【参考方案1】:

SDL_memcpymemcpy,表示第一个参数是目标,第二个参数是源。在你的回调中,你的回调顺序是错误的,你的输入回调只是用最初存储在buffer(零)中的内容擦除你的流数据,输出回调不输出任何东西,而是将垃圾复制到buffer

同样,您的 if (out_pos &gt;= in_pos) 分支应该删除 stream,而不是 buffer

请注意,您请求的音频格式是 F32(不能保证,因为您允许格式更改),但您的调试 printfs 将其解释为 uint8。这不会影响音频播放,只会影响输出的相关程度。

【讨论】:

工作就像一个魅力 :) 看起来我应该在学习音频 I/O 之前真正学习 C(并注意我自己的代码)......(我知道音频格式与 printf 问题,输出只是为了让我知道是否有数据)

以上是关于使用麦克风录制时,SDL 音频捕获未检测到任何音频的主要内容,如果未能解决你的问题,请参考以下文章

如何使用openAL将实时音频输入从麦克风录制到文件中? (里面有C++代码)

使用 C 在 Windows 上捕获和分析音频

在 Python 中检测和录制音频

在移动设备上进行第二次音频录制后未触发 SampleDataEvent

如何录制网络/浏览器音频输出(不是麦克风音频)

捕获音频输出