PortAudio 遍历音频数据
PortAudio iterate through audio data
由于我是 PortAudio 的新手,所以我尝试了一个来自互联网的示例程序。该程序能够通过回调函数记录麦克风的输入。
我想要录制音频的每个样本表示为数值(例如浮点数)。不知道mic的录音数据存放在哪里
这是回调函数:
static int recordCallback(const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData)
{
paTestData *data = (paTestData*)userData;
const SAMPLE *rptr = (const SAMPLE*)inputBuffer;
SAMPLE *wptr = &data->recordedSamples[data->frameIndex * NUM_CHANNELS];
long framesToCalc;
long i;
int finished;
unsigned long framesLeft = data->maxFrameIndex - data->frameIndex;
(void)outputBuffer; /* Prevent unused variable warnings. */
(void)timeInfo;
(void)statusFlags;
(void)userData;
if (framesLeft < framesPerBuffer)
{
framesToCalc = framesLeft;
finished = paComplete;
}
else
{
framesToCalc = framesPerBuffer;
finished = paContinue;
}
if (inputBuffer == NULL)
{
for (i = 0; i<framesToCalc; i++)
{
*wptr++ = SAMPLE_SILENCE; /* left */
if (NUM_CHANNELS == 2) *wptr++ = SAMPLE_SILENCE; /* right */
}
}
else
{
cout << endl << "SAMPLE" << endl;
for (i = 0; i<framesToCalc; i++)
{
*wptr++ = *rptr++; /* left */
//cout << rptr<<endl;
if (NUM_CHANNELS == 2) *wptr++ = *rptr++; /* right */
}
}
data->frameIndex += framesToCalc;
return finished;
}
这里初始化音频输入流:
err = Pa_OpenStream(
&stream,
&inputParameters,
NULL, /* &outputParameters, */
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
recordCallback,
&data);
传入的数据存储在回调的inputBuffer
指针中。根据调用 Pa_OpenStream
时使用的 inputParameters
应该能够将输入缓冲区转换为相应数据类型的数组(例如,如果 paFloat32
用作示例格式,则缓冲区可以被解释为 const float*
).
建议您在回调函数中将传入数据复制到另一个缓冲区以进行进一步处理(在回调之外)。
多个通道样本在缓冲区中交错。例如,对于立体声输入,inputBuffer[0]
是左声道的第一个样本,inputBuffr[1]
是右声道的第一个样本,inputBuffer[2]
是左声道的第二个样本,等等。总计样本数通过回调的 framesPerBuffer
参数提供。
由于我是 PortAudio 的新手,所以我尝试了一个来自互联网的示例程序。该程序能够通过回调函数记录麦克风的输入。
我想要录制音频的每个样本表示为数值(例如浮点数)。不知道mic的录音数据存放在哪里
这是回调函数:
static int recordCallback(const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData)
{
paTestData *data = (paTestData*)userData;
const SAMPLE *rptr = (const SAMPLE*)inputBuffer;
SAMPLE *wptr = &data->recordedSamples[data->frameIndex * NUM_CHANNELS];
long framesToCalc;
long i;
int finished;
unsigned long framesLeft = data->maxFrameIndex - data->frameIndex;
(void)outputBuffer; /* Prevent unused variable warnings. */
(void)timeInfo;
(void)statusFlags;
(void)userData;
if (framesLeft < framesPerBuffer)
{
framesToCalc = framesLeft;
finished = paComplete;
}
else
{
framesToCalc = framesPerBuffer;
finished = paContinue;
}
if (inputBuffer == NULL)
{
for (i = 0; i<framesToCalc; i++)
{
*wptr++ = SAMPLE_SILENCE; /* left */
if (NUM_CHANNELS == 2) *wptr++ = SAMPLE_SILENCE; /* right */
}
}
else
{
cout << endl << "SAMPLE" << endl;
for (i = 0; i<framesToCalc; i++)
{
*wptr++ = *rptr++; /* left */
//cout << rptr<<endl;
if (NUM_CHANNELS == 2) *wptr++ = *rptr++; /* right */
}
}
data->frameIndex += framesToCalc;
return finished;
}
这里初始化音频输入流:
err = Pa_OpenStream(
&stream,
&inputParameters,
NULL, /* &outputParameters, */
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
recordCallback,
&data);
传入的数据存储在回调的inputBuffer
指针中。根据调用 Pa_OpenStream
时使用的 inputParameters
应该能够将输入缓冲区转换为相应数据类型的数组(例如,如果 paFloat32
用作示例格式,则缓冲区可以被解释为 const float*
).
建议您在回调函数中将传入数据复制到另一个缓冲区以进行进一步处理(在回调之外)。
多个通道样本在缓冲区中交错。例如,对于立体声输入,inputBuffer[0]
是左声道的第一个样本,inputBuffr[1]
是右声道的第一个样本,inputBuffer[2]
是左声道的第二个样本,等等。总计样本数通过回调的 framesPerBuffer
参数提供。