c - PulseAudio API - 无麦克风信号

标签 c linux audio real-time pulseaudio

我正在尝试使用 PulseAudio“实时”捕获麦克风信号。该程序是用 C 语言编写的,并使用 PulseAudio Simple API。不幸的是我请求的音频缓冲区不包含任何信号。要么我的代码有问题,要么设备源无法被识别。我在我的程序之外使用gstreamer的pulssrc和pulssink进行了一些测试,这些测试有效。我还测试了以下命令,它也有效:

parec -d alsa_input.usb-041e_30d3_121023000184-00-U0x41e0x30d3.analog-mono | sox -t raw -r 44100 -sLb 16 -c 2 - /home/roos/Arbeitsfläche/pulsetest.wav

在我的第二张卡上它也有效:

parec -d alsa_input.usb-Creative_Technology_Ltd_Sound_Blaster_X-Fi_Go__Pro_00173634-00-Pro_1.analog-stereo | sox -t raw -r 44100 -sLb 16 -c 2 - /home/roos/Arbeitsfläche/pulsetest.wav

这是应该起作用的代码:

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <math.h>

#include <pulse/simple.h>
#include <pulse/error.h>

#define BUFSIZE 1024
#define SAMPLE_BITS 16

/* A simple routine calling UNIX write() in a loop */
static ssize_t loop_write(int fd, const uint8_t *data, size_t size) 
{
    int i = 0;
    for (i = 0; i < size; i += 2)
    {
        // put two bytes into one __signed__ integer
        int16_t val = data[i] + ((uint32_t)data[i+1] << 8);
        printf("%d", val);
    }

        return size;
}

int main(int argc, char*argv[]) 
{
    char *device = "alsa_output.usb-Creative_Technology_Ltd_Sound_Blaster_X-Fi_Go__Pro_00173634-00-Pro_1.analog-stereo";

    // The sample type to use
    static const pa_sample_spec ss = {
    .format = PA_SAMPLE_S16LE,
    .rate = 44100,
    .channels = 2
    };
    pa_simple *s = NULL;
    int ret = 1;
    int error;

    // Create the recording stream 
    if (!(s = pa_simple_new(NULL, argv[0], PA_STREAM_RECORD, NULL, "record", &ss, NULL, NULL, &error))) {
    fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error));
    goto finish;
    }

    for (;;) {
    uint8_t buf[BUFSIZE];

    // Record some data ...
    if (pa_simple_read(s, buf, sizeof(buf), &error) < 0) {
        fprintf(stderr, __FILE__": pa_simple_read() failed: %s\n", pa_strerror(error));
        goto finish;
    }

    // And write it to STDOUT
    if (loop_write(STDOUT_FILENO, buf, sizeof(buf)) != sizeof(buf)) {
        fprintf(stderr, __FILE__": write() failed: %s\n", strerror(errno));
        goto finish;
    }
    }

    ret = 0;

finish:

    if (s)
    pa_simple_free(s);

    return 0;
}

方法“ssize_t Loop_write”接收缓冲区,因为它是一个 16 位小端字节数组,所以我将两个字节组合成一个有符号的 16 位整数。这意味着幅度(由变量“val”表示)应该在 0 到 32768 之间。但到目前为止,它都是 0。所以我主要关心的两个问题是设备源(在我看来更有可能)和我的转换一个整数值。

您对此有什么建议吗?预先感谢您!

编辑/更新:好的,我不知道我做了什么 - 但如果我通过特定设备,我现在会收到以下消息:

pa_simple_new() failed: Connection refused

当我传递 NULL 时,它适用于默认声卡。仍在使用我之前描述的命令行命令。知道这可能是怎么回事吗?

最佳答案

好吧,刚刚弄清楚 - 我犯了一个相当愚蠢的错误。

我将设备传递给第一个函数参数而不是第四个。

所以这样做

if (!(s = pa_simple_new(NULL, argv[0], PA_STREAM_RECORD, device, "record", &ss, NULL, NULL, &error)))

而不是这个

if (!(s = pa_simple_new(device, argv[0], PA_STREAM_RECORD, NULL, "record", &ss, NULL, NULL, &error)))

关于c - PulseAudio API - 无麦克风信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15155947/

相关文章:

python - 在Python中将声波编码为图像和文本?

c - 如何使用读取功能从终端输入(stdin)读取?

microcontroller - MPLABX/MPLAB IDE 中的 "File can not be opened"编译器错误

c - 在二叉搜索树中查找节点的父节点

linux - 如何在 Windows 上 chmod 0777 文件并按原样提交给 Git?

c - GNU 中使用负 ERRNO 值的历史

javascript - HTML5音频播放本地mp3文件的播放列表

c - 优化用于模式填充数组的嵌套循环,以帮助编译器生成高效的 ARM 程序集?

linux - 如何清除linux文件中的ctrl+z?

javascript - 禁用 HTML5 音频