如何使用PortAudio将交错的缓冲区解析为不同的多通道缓冲区

伊格纳蒂斯

希望你能帮我 :)

我正在尝试从具有PortAudio库的多通道ASIO设备获取音频数据。一切正常:我设法将默认主机API设置为ASIO,并且还设法选择4个特定通道作为输入。然后,我得到了一个交错的音频流,该音频流听起来正确,但是我想分别获取每个通道数据。

PortAudio允许进行非交错记录,但是我不知道如何编写或修改RecordCallBack和multibuffer指针(每个通道一个缓冲区)。当然我已经尝试过... :(

如果有人知道如何处理这个问题,对我将有很大的帮助。

原始的RecordCallBack函数取自一个众所周知的立体声示例(稍作修改即可管理4个通道而不是2个),但是它管理单个交错缓冲区:

static int recordCallback( const void *inputBuffer, void *outputBuffer,
                       unsigned long framesPerBuffer,
                       const PaStreamCallbackTimeInfo* timeInfo,
                       PaStreamCallbackFlags statusFlags,
                       void *userData )
{
paTestData *data = (paTestData*)userData;
const short *rptr = (const short*)inputBuffer;
short *wptr = &data->recordedSamples[data->frameIndex * NUM_CHANNELS_I];
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;  /* ch1*/
        if( NUM_CHANNELS_I == 4 ){
            *wptr++ = SAMPLE_SILENCE;/* ch2*/
            *wptr++ = SAMPLE_SILENCE;/* ch3*/
            *wptr++ = SAMPLE_SILENCE;}  /* ch4*/
    }
}
else
{
    for( i=0; i<framesToCalc; i++ )
    {
        *wptr++ = *rptr++;  /* ch1*/
        if( NUM_CHANNELS_I == 4 ){ 
            *wptr++ = *rptr++;/* ch2*/
            *wptr++ = *rptr++;/* ch3*/
            *wptr++ = *rptr++;}  /* ch4*/
    }
}
data->frameIndex += framesToCalc;

return finished;
}

* inputbuffer指针声明为:

PaStream* stream;

Open_Stream函数称为:

err = Pa_OpenStream(
          &stream,
          NULL, /* no input */
          &outputParameters,
          SAMPLE_RATE,
          FRAMES_PER_BUFFER,
          paClipOff,      /* we won't output out of range samples so don't bother clipping them */
          playCallback,
          &data );
伊格纳蒂斯

感谢Scott的帮助。解决方案就在我眼前,而我最终不必处理偏移量的样本。我没有为您提供有关代码的足够信息,因此您的方法非常出色,但是代码本身提供了一种更简单的方法:

数据存储在结构中:

typedef struct
{
int          frameIndex;  /* Index into sample array. */
int          maxFrameIndex;
short       *recordedSamples;
}
paTestData;

我将其修改为:

typedef struct
{
int          frameIndex;  /* Index into sample array. */
int          maxFrameIndex;
short       *recordedSamples;
short       * recordedSamples2; //ch2
short       * recordedSamples3; //ch3
short       *recordedSamples4; //ch4
}
paTestData;

然后,我只需要在内存中分配此变量,并按如下所示修改recordCallback函数:

static int recordCallback( const void *inputBuffer, void *outputBuffer,
                       unsigned long framesPerBuffer,
                       const PaStreamCallbackTimeInfo* timeInfo,
                       PaStreamCallbackFlags statusFlags,
                       void *userData )
 {
 paTestData *data = (paTestData*)userData;
 const short *rptr = (const short*)inputBuffer;

short *wptr = &data->recordedSamples[data->frameIndex];
short *wptr2=&data->recordedSamples2[data->frameIndex];
short *wptr3=&data->recordedSamples3[data->frameIndex];
short *wptr4=&data->recordedSamples4[data->frameIndex];
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;  //ch1
        if( NUM_CHANNELS_I == 4 ){
            *wptr2++ = SAMPLE_SILENCE;//ch2
            *wptr3 ++= SAMPLE_SILENCE;//ch3
            *wptr4++ = SAMPLE_SILENCE;}  //ch4
    }
}
else
{
    for( i=0; i<framesToCalc; i++ )
    {
        *wptr++ = *rptr++;  //ch1
        if( NUM_CHANNELS_I == 4 ){ 
            *wptr2++ = *rptr++;//ch2
            *wptr3++ = *rptr++;//ch3
            *wptr4 ++= *rptr++;}  //ch4
    }
}
data->frameIndex += framesToCalc;

return finished;
}

希望这可以帮助其他人。再次谢谢你,斯科特

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

将缓冲区数据解析为struct

来自分类Dev

OpenGL glMultiDrawElementsIndirect与交错缓冲区

来自分类Dev

三.js 缓冲区已经交错

来自分类Dev

解析循环缓冲区

来自分类Dev

如何使用流解析缓冲区中的行?

来自分类Dev

如何使用流解析缓冲区中的行?

来自分类Dev

如何将多重采样深度缓冲区解析为深度纹理?

来自分类Dev

是gorouines忽略通道的缓冲区大小

来自分类Dev

何时使用数组,缓冲区或直接缓冲区

来自分类Dev

缓冲区大小如何影响NIO通道性能?

来自分类Dev

如何将char *缓冲区转换为unsigned char缓冲区

来自分类Dev

比较缓冲区

来自分类Dev

请求缓冲区

来自分类Dev

在 Flex 中使用多个缓冲区时,如何避免令牌在缓冲区之间拆分

来自分类Dev

使用通道将数据从outputStream传递到字节缓冲区

来自分类Dev

使用通道将数据从outputStream传递到字节缓冲区

来自分类Dev

在C ++中解析协议缓冲区

来自分类Dev

用Qt解析GLTF缓冲区

来自分类Dev

如何进行复杂的多缓冲区搜索?

来自分类Dev

如何进行复杂的多缓冲区搜索?

来自分类Dev

将中间转换的char *缓冲区设置为int *

来自分类Dev

将复杂的Java类建模为协议缓冲区

来自分类Dev

Flatbuffer缓冲区始终为空

来自分类Dev

FBO深度缓冲区为红色

来自分类Dev

非交错顶点缓冲区DirectX11

来自分类Dev

使用C ++ API解析协议缓冲区中的错误

来自分类Dev

如何检查缓冲区是否为空?

来自分类Dev

如何检查输入缓冲区是否为空?

来自分类Dev

将`:map`的输出放入缓冲区