Я хотел бы передавать аудио с помощью openal (linux), но то, что я получаю, это шум и часть песни в фоновом режиме. Я читал 4-канальный файл амбиций и отбрасывал 2 канала. Я отправляю 20000 кадров в открытый буфер (20000 * 2_channels * 4 байта).Шум при потоковой передаче в openal
Не могу сказать, что не так. Я думаю, что этот код правильный. Часть, которая отвечает за загрузку фрагмента аудиофайла и преобразование его в 2 канала, хороша, потому что я его протестировал. Я написал вывод в файл и получил качественный 2-канальный wav.
Амбициозный файл имеет 4 канала и частоту 48 кГц. Я создал открытый контекст без дополнительных параметров.
Любые предложения?
const int NUM_BUFFERS = 2;
const int BUFFER_SIZE = 20000; // frames
ALuint source, buffers[NUM_BUFFERS];
int streamBuffer(ALuint bufID, int bufferSize, AudioFile &audio) {
const SF_INFO &info = audio.getInfo();
const lli numFrames = bufferSize;
float *bufHrtf = new float[bufferSize * 2];
float *buf = nullptr;
audio.readFrames(numFrames, &buf);
lli idxHrtf = 0;
for (lli j = 0; j < numFrames * info.channels; j += info.channels) {
bufHrtf[idxHrtf++] = buf[j + 1];
bufHrtf[idxHrtf++] = buf[j + 2];
}
alBufferData(bufID, AL_FORMAT_STEREO16, bufHrtf, idxHrtf * sizeof(float), info.samplerate);
delete [] bufHrtf;
}
int main(int argc, char **argv) {
AudioFile audio;
if (!audio.open("sample.amb")) {
return 1;
}
if (!createOpenAlAndBuffer()) {
return 1;
}
streamBuffer(buffers[0], BUFFER_SIZE, audio);
streamBuffer(buffers[1], BUFFER_SIZE, audio);
alSourceQueueBuffers(source, 2, buffers);
alSourcePlay(source);
while(!audio.endOfFile())
{
// Check how much data is processed in OpenAL's internal queue
ALint processed{0};
alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
// add more buffers while we need them
while (processed--)
{
ALuint bufID;
alSourceUnqueueBuffers(source, 1, &bufID);
streamBuffer(bufID, BUFFER_SIZE, audio);
alSourceQueueBuffers(source, 1, &bufID);
int val{0};
alGetSourcei(source, AL_SOURCE_STATE, &val);
if(val != AL_PLAYING) {
alSourcePlay(source);
}
}
}
destroyOpenAl();
return 0;
}