Интерпретация значения inputBuffer в обратном вызове

Я основываю свой код на примере Portaudio paex_record_file.c. Одним из параметров обратного вызова является inputBuffer, и я хотел использовать его данные для вычисления других чисел с типом double/float. Я изменил файл с .raw на .txt, но блокнот по-прежнему не может его прочитать, что заставляет меня поверить, что его данные на самом деле не закодированы как число. Как данные хранятся в inputBuffer и как с ними выполнять арифметические действия (складывать, умножать, делить и т. д.)?

Вот как я инициализировал inputParameters:

inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
if (inputParameters.device == paNoDevice) {
    fprintf(stderr,"Error: No default input device.\n");
    goto error;
}
inputParameters.channelCount = 2;                    /* stereo input */
inputParameters.sampleFormat = paFloat32;
inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
inputParameters.hostApiSpecificStreamInfo = NULL;

Этот вопрос в некоторой степени связан с печатью поплавков из функции обратного вызова аудиовхода ( без ответа).


person himty    schedule 25.02.2016    source источник


Ответы (1)


Параметр inputBuffer для обратного вызова — это void*. Фактический тип базового буфера зависит от параметров и флагов, которые вы передаете Pa_OpenStream.

Если вы указали paFloat32, то где-то там будет float*. Однако есть две возможности:

  1. Чередование: inputParameters.sampleFormat = paFloat32;
  2. Без чередования: inputParameters.sampleFormat = paFloat32|paNonInterleaved;

Вы указали параметр с чередованием. В этом случае inputBuffer указывает на один буфер чередующихся чисел с плавающей запятой. Итак, вы можете написать:

float *samples = (float*)inputBuffer;

В двухканальном потоке samples будут чередоваться левые и правые сэмплы, например:

samples[0]; // first left sample
samples[1]; // first right sample
samples[2]; // second left sample
samples[3]; // second right sample
// etc.

Для полноты: если это был поток без чередования, то inputBuffer указывает на массив указателей на одноканальные буферы. Чтобы извлечь указатели буфера, вы должны написать что-то вроде:

float *left = ((float **) inputBuffer)[0];
float *right = ((float **) inputBuffer)[1];

Обратите внимание, что во всех случаях framesPerBuffer считает кадры, а не выборки. Кадр включает в себя по одной выборке из каждого канала. Например, в стереопотоке кадр включает выборки как левого, так и правого каналов.

person Ross Bencina    schedule 09.04.2016
comment
Большое спасибо! - person himty; 10.04.2016