надеюсь, что вы можете мне помочь :)Как разобрать перемежаемое буфер на отдельные несколько буферов каналов с Portaudio
Я пытаюсь получить аудиоданные из многоканального ASIO устройства с библиотекой Portaudio. Все в порядке: мне удалось установить API-интерфейс хоста по умолчанию как ASIO, и мне также удалось выбрать 4 конкретных канала в качестве входных данных. Затем я получаю чередующийся аудиопоток, который звучит правильно, но я хотел бы получить каждый канал данных отдельно.
PortAudio позволяет делать запись без чередования, но я не знаю, как писать или изменять свой RecordCallBack и указатель мультибуфера (один буфер на канал). Конечно, я пытался ... :(
Было бы массивной помощь мне, если кто-то знает, как справиться с этой проблемой.
Оригинальная функция RecordCallBack взята из хорошо известного стерео примера (немного модифицирован для управления 4 channles вместо 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);
Привет, Скотт, благодарю вас за ваш ответ. Если я получаю вас правильно, так как мои образцы имеют длину в 16 бит (короткий), чередование 4 каналов означает буфер: samplech1samplech2samplech3samplech4samplech1samplech2samplech3samplech4 ... ??? Мой первый подход заключался в том, чтобы обрабатывать подобный буффер, и получать каждую шанель следующим образом (в цикле): datach2 (i) = data (i + 1); datach3 (i) = data (i + 2); datach4 (i) = данные (я + 3). Где «данные» содержат весь поток бурового буфера. Но это не сработало ... Может быть, мне что-то не хватает ... – JavaRar
Я вижу, что вы используете смещение всего 1 между каналами, и вы используете отдельные буферы для каждого канала - я предложил подход выше, который будет работать как внутри callback, а также за пределами ... удачи –
Большое спасибо Скотту, я очень ценю вашу помощь. Я постараюсь сделать то, что вы предлагаете как можно скорее, тогда я дам вам знать, насколько я уверен в успехе или нет. Еще раз спасибо – JavaRar