流时间信息
使用回调I / O方法时,您的流回调函数 通过指向a的指针接收定时信息 PaStreamCallbackTimeInfo结构。这个结构包含了 当前时间以及估计的硬件捕获和回放 输入和输出缓冲区的第一个样本的时间。一直 相对于特定于流的时钟以秒为单位进行测量。该 可以使用Pa_GetStreamTime()来检索当前流时钟时间。
因此PaStreamCallbackTimeInfo::currentTime
以某种方式指示当前时间,PaStreamCallbackTimeInfo::outputBufferDacTime
应指示当前缓冲区中第一个样本的输出时间。我不知道为什么,但在Linux上,这些值对我来说都是零。也许我做错了什么。这是代码和输出:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include "portaudio.h"
#define PI 3.14159265359
#define SRATE 44100
#define FREQ 440
#define DURATION 5000
int
audio_callback(
const void* inbuf,
void* outbuf,
unsigned long bufsize,
const PaStreamCallbackTimeInfo* time_info,
PaStreamCallbackFlags status_flags,
void* user_data)
{
(void)inbuf;
(void)status_flags;
double* phase = (double*)user_data;
float* out = (float*)outbuf;
printf(
"current time = %f; out time = %f\n",
time_info->currentTime,
time_info->outputBufferDacTime);
for (unsigned long i = 0; i < bufsize; i++)
{
*phase += 2 * PI * FREQ / SRATE;
out[i] = sin(*phase);
}
return 0;
}
int
main(int argc, char** argv)
{
(void)argc;
(void)argv;
PaError pa_error;
PaStream* stream = NULL;
int error = 0;
double phase = 0;
pa_error = Pa_Initialize();
if (pa_error != paNoError)
{
return 1;
}
pa_error = Pa_OpenDefaultStream(
&stream,
0,
1,
paFloat32,
SRATE,
paFramesPerBufferUnspecified,
&audio_callback,
&phase);
if (pa_error != paNoError)
{
error = 1;
goto exit;
}
pa_error = Pa_StartStream(stream);
if (pa_error != paNoError)
{
error = 1;
goto exit;
}
Pa_Sleep(DURATION);
pa_error = Pa_CloseStream(stream);
if (pa_error != paNoError)
{
error = 1;
goto exit;
}
printf("Done.\n");
exit:
Pa_Terminate();
if (pa_error != paNoError)
{
printf("PortAudio error: %s\n", Pa_GetErrorText(pa_error));
}
return error;
}
输出:
current time = 0.000000; out time = 0.000000
current time = 0.000000; out time = 0.000000
current time = 0.000000; out time = 0.000000
current time = 0.000000; out time = 0.000000
...
附录:同样的代码似乎可以在Windows 10中与Visual Studio一起使用。
答案 0 :(得分:0)
您的示例在我的Mac上编译正常并返回有意义的时间信息,因此问题不在您的代码中。
你还没有说过你在Linux上使用的音频后端,但如果你使用的是 ALSA 和 PulseAudio ,那么获取时间信息就会出现问题与那些(例如,见there)。在 ALSA / PulseAudio 的特定情况下, Pulse 是责备而 PortAudio 与此无关。
如果您使用的是其他音频后端,则可能需要检查相应GetStreamTime()
PortAudio 源文件夹中src/hostapi/<your_backend>
函数的实现。
作为旁注,永远不要在真实产品的音频回调中进行I / O操作。 printf
是一个庞大的函数,需要花费大量的时间来执行(从音频回调的角度来看)。