使用麦克风录制时,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_memcpy
是memcpy
,表示第一个参数是目标,第二个参数是源。在你的回调中,你的回调顺序是错误的,你的输入回调只是用最初存储在buffer
(零)中的内容擦除你的流数据,输出回调不输出任何东西,而是将垃圾复制到buffer
。
同样,您的 if (out_pos >= in_pos)
分支应该删除 stream
,而不是 buffer
。
请注意,您请求的音频格式是 F32(不能保证,因为您允许格式更改),但您的调试 printfs 将其解释为 uint8。这不会影响音频播放,只会影响输出的相关程度。
【讨论】:
工作就像一个魅力 :) 看起来我应该在学习音频 I/O 之前真正学习 C(并注意我自己的代码)......(我知道音频格式与 printf 问题,输出只是为了让我知道是否有数据)以上是关于使用麦克风录制时,SDL 音频捕获未检测到任何音频的主要内容,如果未能解决你的问题,请参考以下文章
如何使用openAL将实时音频输入从麦克风录制到文件中? (里面有C++代码)