面對奇怪的PulseAudio監視器設備(即播放發送到揚聲器的聲音的音頻輸入設備)行爲。我將代碼從我的真實項目簡化爲基於PulseAudio文檔代碼的簡單示例https://freedesktop.org/software/pulseaudio/doxygen/parec-simple_8c-example.html,我只添加了時間限制和讀取字節計數。它工作例如30秒並打印讀取字節數。問題是如果在程序運行過程中播放某些內容,則字節數會大大不同。我已經執行了這個程序並行執行bash for
循環組成aplay
與短tada.wav
文件。差異是9%。爲了進一步測試,我嘗試了與PulseAudio例子並行運行4個這樣的循環,差異甚至更大--34%。但如果不是幾個aplay
與短wav我運行mplayer
長mp3文件 - 沒有這種差異,字節計數類似於沒有聲音播放時的情況。奇怪的PulseAudio監視器設備行爲
這樣的行爲會導致聲音處理代碼在我的真實項目中失敗,所以如果有人可以建議如何解決它 - 我將非常感激。
在基於Qt的Windows上使用類似的代碼,並且使用立體聲混音器設備作爲PulseAudio監聽器的模擬器,其工作原理沒有這樣的問題。
這是基於例如我的代碼的PulseAudio文檔:
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <iostream>
#include <chrono>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <pulse/simple.h>
#include <pulse/error.h>
#define BUFSIZE 1024
using namespace std;
using namespace std::chrono;
int main(int argc, char *argv[])
{
int duration = 30000;
int64_t readBytesCounter = 0;
milliseconds msStart = duration_cast<milliseconds>(system_clock::now().time_since_epoch());
/* 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, "alsa_output.pci-0000_00_1b.0.analog-stereo.monitor", "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;
}
readBytesCounter += BUFSIZE;
milliseconds msCurrent = duration_cast<milliseconds>(system_clock::now().time_since_epoch());
int elapsed = msCurrent.count() - msStart.count();
if (elapsed > duration)
{
cerr << int(elapsed/1000) << " seconds elapsed, terminating" << endl;
cerr << readBytesCounter << " bytes read" << endl;
goto finish;
}
}
ret = 0;
finish:
if (s)
pa_simple_free(s);
return ret;
}
它可以用下面的命令來構建:
g++ -o main main.cpp -lpulse -lpulse-simple -std=c++11
例wav文件我已經從http://d0.waper.ru/f/462151/23/HgDwimvX37CwxWqW38eywg%2C1485353628/7d74/9/462151.wav/tada.wav
採取這裏是測試結果:
測試1.沒有聲音在spea KER
$ time ./main
30 seconds elapsed, terminating
5323776 bytes read
real 0m30.028s
user 0m0.168s
sys 0m0.388s
試驗2擊for
環「對i在SEQ 1 22;做aplay tada.wav;完成」在後臺短WAV文件。字節數增加5798912/5323776 = 1.089
倍。
測試3. 4猛砸for
迴路短wav文件的背景。字節數增加7129088/5323776 = 1.339
倍。
$ time ./main
30 seconds elapsed, terminating
7129088 bytes read
real 0m30.019s
user 0m0.164s
sys 0m0.196s
測試4. mplayer
在後臺長時間的MP3。5288960/5323776 = 0.993
,即沒有顯著的字節數差異。
$ time ./main
30 seconds elapsed, terminating
5288960 bytes read
real 0m30.024s
user 0m0.096s
sys 0m0.204s
試圖執行一組每個測試,平均字節數 - 類似的差異。
PS:我的系統的配置:
- OS的Ubuntu 16.04.1 AMD64
- 的pulseaudio 1:8.0-0ubuntu3.2
- ALSA基1.0.25 + DFSG-0ubuntu5