gpt4 book ai didi

c - Pulseaudio 的 pa_simple_read() 输出 0-5 或 248-255

转载 作者:行者123 更新时间:2023-12-03 01:18:15 26 4
gpt4 key购买 nike

我正在尝试学习使用 pulseaudio 的 Simple API for C。当我意识到我收到的值没有意义时,我开始有所收获。起初他们在 ~64-66 和 0 之间交换。即“65 0 64 0 65 0 66 0 64 0”。然后,过了一会儿(也许我做了一些事情来促使这种变化?)我开始得到非常低或非常高的值,没有介于两者之间。更奇怪的是,这些值是 4 的系列。即 n 个小数后面跟着 m 个大数,其中 n 和 m 是 4 的倍数。

偶尔会有一些数字不是那么极端,但非常罕见。

这是代码:

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

int main() {
pa_simple *s;
pa_sample_spec ss;

ss.format = PA_SAMPLE_S16NE;
ss.channels = 2;
ss.rate = 44100;

int error;

s = pa_simple_new(
NULL,
"PulseAudioTest",
PA_STREAM_RECORD,
NULL,
"My test",
&ss,
NULL,
NULL,
&error
);

if(!s)
printf("error: %s", pa_strerror(error));

uint8_t buf[1024];

while(1) {
pa_simple_read(s, buf, sizeof(buf), NULL);

for(int i = 0; i < sizeof(buf); i++)
printf("%d,", buf[i]);
printf("\n-----------\n"); // just here for me separating the data, im not playing this back
}

if(s)
pa_simple_free(s);
else
printf("error\n");

return 0;
}

和一些示例输出: https://pastebin.com/FgFekmf0 .

我还尝试了 http://0pointer.de/lennart/projects/pulseaudio/doxygen/parec-simple_8c-example.html 中的 parec.c 和 pacat.c ,但是当我播放录音时,它只是静态的。我还尝试切换默认接收器并通过默认和非默认接收器播放音乐。

另外,如果有人对在哪里学习使用它(以及音频的一般工作方式)有任何建议,我会喜欢建议(即使只是我对谷歌的一个术语 - 我花了一段时间才知道输出是“pcm”,甚至是什么)。

最佳答案

为什么代码打印值以零分隔,即“65 0 64 0 65 0 66 0 64 0 ...”?
通常,默认的录制音频规范是编写在您的代码中的规范:

/* Each sample is Signed 16-bit integer recorded in little-endian (the Native
* Endian in intel x86 and x86-64).
*/
ss.format = PA_SAMPLE_S16NE;
/* There are 2 channels. */
ss.channels = 2;
/* Sample rate is 44100 Hz. */
ss.rate = 44100;
/* This is how audio samples are arranged. Given a stream of samples
*
* ADDR 0x0 0x2 0x4 0x6 0x8 0xA
* SAMPLE 12345, 13579, -185, -3, -9876, -9999, ...
* |-----||-----||-----||-----||-----||-----|
* CH1 CH2 CH1 CH2 CH1 CH2
* |------------||------------||------------|
* FRAME FRAME FRAME
*/
给定一个值为 65 的样本,其十六进制为 0x0041,其中 little-endian ,它将被存储为 41 00在内存中。请注意,您的代码打印 buf一个字节一个字节,这就是你得到 65 0 的原因.因此,对于样本流 65、64、65...,您将打印 65 0 64 0 65 0 ... .
试过parecpacat ,但只有静态噪音。如何让它发挥作用?
确保音频输入(麦克风)未静音且音量合适。运行 pavucontrol ,转到“输入设备”选项卡,取消麦克风静音,然后调节音量。发出一些噪音,您应该会看到信号条(在音量条下方)跳跃。
PulseAudio 带有多个录音和播放实用程序(arch 中的包 libpulse,debian 中的包 pulseaudio-utils): parec , parecord , pacat , paplay .试试看。他们应该工作。
播放 parec 录制的声音与 pacat .
$ parec sample1.wav
^C
$ pacat sample1.wav
播放 parecord 录制的声音与 paplay .
$ parecord sample2.wav
^C
$ paplay sample2.wav
它们之间的主要区别在于 parecpacat不要在声音文件中读写头文件,而 parecordpaplay做。
成功运行这些命令后,您可以尝试编译 pacat-simple.cparec-simple.c来自 official repository , 在 src/tests/ 下.
$ gcc pacat-simple.c -o pacat-simple -lpulse-simple -lpulse
$ gcc parec-simple.c -o parec-simple -lpulse-simple -lpulse
之后,尝试运行它们。
$ ./parec-simple > sample3.wav
^C
$ ./pacat-simple < sample3.wav
它应该工作。现在你可以开始检查和玩 parec-simple.cpacat-simple.c .请注意 parec-simplepacat-simple也不要在声音文件中读写头文件,就像 parecpacat .
通过对 while 循环进行一些修改,您的代码将像 parec-simple 一样工作。 .修改版(文件 my-parec.c ):
while(1) {
pa_simple_read(s, buf, sizeof(buf), NULL);

//for(int i = 0; i < sizeof(buf); i++)
// printf("%d,", buf[i]);
//printf("\n-----------\n"); // just here for me separating the data, im not playing this back

fwrite(buf, 1, sizeof(buf), stdout);
}
编译并运行它:
$ gcc my-parec.c -o my-parec -lpulse-simple -lpulse
$ my-parec > sample4.wav
^C
有没有使用 PulseAudio C API 的例子?
除了 parec-simple.cpacat-simple.c ,如果您已通读 PulseAudio asynchronous API documentation ,您可以结帐 pacat.csrc/utils/ 下举个例子。其实 parec , parecord , 和 paplay只是 pacat 的符号链接(symbolic link),源代码为 pacat.c .
声音文件的标题是什么?上面提到过。
如果声音文件仅包含数据,则播放器无法知道该文件的音频规范,例如 channel 数、每个样本的位数(位深度)、字节序等。在这种情况下,它只能假设默认规范是使用过,可能不是这样。因此,为了将这些属性保存到声音文件中,我们在该文件中创建了一个标题部分来存储它们。引用 WAV PCM soundfile formataudio file format specifications对于标题格式。
为了管理声音文件的标题部分,C 库 libsndfile可以使用。 pacat.c确实使用该库来读取和写入带有标题的声音文件。 libsndfile还提供了一些实用程序,例如 sndfile-info这有助于我们检查声音文件。这些实用程序包含在包 libsndfile 中。在拱形和包装 sndfile-programs在Debian中。
$ sndfile-info sample2.wav
========================================
File : sample2.wav
Length : 698668
RIFF : 698660
WAVE
fmt : 16
Format : 0x1 => WAVE_FORMAT_PCM
Channels : 2
Sample Rate : 44100
Block Align : 4
Bit Width : 16
Bytes/sec : 176400
data : 698624
End

----------------------------------------
Sample Rate : 44100
Frames : 174656
Channels : 2
Format : 0x00010002
Sections : 1
Seekable : TRUE
Duration : 00:00:03.960
Signal Max : 17226 (-5.59 dB)
要将标题添加到没有标题的声音文件中,我能想到的最简单的方法是,从另一个有标题的声音文件中复制标题,将其添加到没有标题的声音文件中,然后使用十六进制编辑器更改一些值(我使用 ghex )。编辑标题中的数字字段时请注意字节顺序。
# In my system, sample2.wav has the simplest header which is 44 bytes long.
head -c 44 sample2.wav > header.wav
# Prepend header to sound file without header.
cat header.wav sample3.wav > sample3-with-header.wav
# Edit the chunk size field and data chunk size field.
ghex sample3-with-header.wav
其他引用资料
PulseAudio under the hood很好地解释了 PulseAudio 服务器。它关于缓冲和延迟的主题有助于理解 API 的使用,如 pa_stream_begin_write()pa_stream_write() .

关于c - Pulseaudio 的 pa_simple_read() 输出 0-5 或 248-255,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61841923/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com