SDL Audio capture 在使用麦克风录音时未检测到任何音频

SDL Audio capture does not detect any audio when recording with a microphone

我正在尝试从我的麦克风录制音频并立即通过我的扬声器播放。我没有做到这一点; 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 将只显示零。

我已经检查过这些:

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

我正在使用 Ubuntu 20.04 和 Pulseaudio 13.99.1。

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

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

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