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
将只显示零。
我已经检查过这些:
- 它连接到适当的麦克风。在将 0 替换为 1(以检测 捕获 设备)后,我用片段 here (archive) 列出了所有可用设备,并手动让程序使用 [=13 专门选择该设备=]
- 我的麦克风工作正常,录音声音很大;我用多个其他应用程序对其进行了测试,没有其他问题。
我正在使用 Ubuntu 20.04 和 Pulseaudio 13.99.1。
SDL_memcpy
是 memcpy
,意思是第一个参数是目标,第二个参数是源。在你的回调中,顺序是错误的,你的输入回调只是用最初存储在 buffer
(零)中的内容擦除你的流数据,而输出回调不输出任何东西,而是将垃圾复制到 buffer
.
同样,您的 if (out_pos >= in_pos)
分支应该删除 stream
,而不是 buffer
。
请注意,您请求的音频格式是 F32(不能保证,因为您允许格式更改),但您的调试 printfs 将其解释为 uint8。这不会影响音频播放,只会影响相关输出。
我正在尝试从我的麦克风录制音频并立即通过我的扬声器播放。我没有做到这一点; 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(以检测 捕获 设备)后,我用片段 here (archive) 列出了所有可用设备,并手动让程序使用 [=13 专门选择该设备=]
- 我的麦克风工作正常,录音声音很大;我用多个其他应用程序对其进行了测试,没有其他问题。
我正在使用 Ubuntu 20.04 和 Pulseaudio 13.99.1。
SDL_memcpy
是 memcpy
,意思是第一个参数是目标,第二个参数是源。在你的回调中,顺序是错误的,你的输入回调只是用最初存储在 buffer
(零)中的内容擦除你的流数据,而输出回调不输出任何东西,而是将垃圾复制到 buffer
.
同样,您的 if (out_pos >= in_pos)
分支应该删除 stream
,而不是 buffer
。
请注意,您请求的音频格式是 F32(不能保证,因为您允许格式更改),但您的调试 printfs 将其解释为 uint8。这不会影响音频播放,只会影响相关输出。