Упаковка данных ЛЕВОГО и ПРАВОГО каналов

Я декодирую звук FLAC в память и передаю декодированные аудиоданные в OpenAL: void alBufferData (ALuint bufferName, ALenum format, const ALvoid *data, ALsizei size, ALsizei frequency);

Данные из декодированного звука попадают в мой std::vector<FLAC__int32> data_;. В который я пытаюсь упаковать ЛЕВЫЙ и ПРАВЫЙ каналы (AL_FORMAT_STEREO16). Однако я не понимаю, как мне хранить / выравнивать эти каналы в моем data_ векторе.

Итак, у меня есть функция виртуального обратного вызова libFLAC:

FLAC__StreamDecoderWriteStatus
Source::write_callback (
    FLAC__Frame const* _frame, FLAC__int32 const *const _buffer[])
{

    for(size_t i(0); i < _frame->header.blocksize; i++) {

        data_[index_] = _buffer[0][i]; // channel audio on the left
        ++index_;

        data_[index_] = _buffer[1][i]; // what about the right channel?

    } // jump

    return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
} // main

На данный момент при воспроизведении звука я слышу только ЛЕВЫЙ канал. После того, как звук закончился, появляется статический звук, который, как я предполагаю, является недостающими данными ПРАВИЛЬНОГО канала. Как мне заставить работать ПРАВИЛЬНЫЙ канал?

Кроме того, это подпись обратного вызова метаданных согласно libFLAC:

void
Source::metadata_callback (const ::FLAC__StreamMetadata *metadata)
{

    total_samples_ = metadata->data.stream_info.total_samples;
    rate_ = metadata->data.stream_info.sample_rate;
    channels_ = metadata->data.stream_info.channels;
    bps_ = metadata->data.stream_info.bits_per_sample;

    switch (bps_) {
        case 16 :

            if (channels_ > 1) {
                format_ = AL_FORMAT_STEREO16; } else { 
                format_ = AL_FORMAT_MONO16; }

            break;
        case 8 :

            if (channels_ > 1) {
                format_ = AL_FORMAT_STEREO8; } else { 
                format_ = AL_FORMAT_MONO8; }

            break;
        default:
            break;
    }

    size_ = (ALuint)(rate_ * channels_ * (bps_ / 8));
    data_.resize(total_samples_); index_ = 0;
} // main

person 8-bitButterfly    schedule 01.12.2013    source источник
comment
Предположительно он ожидает данные PCM, которые обычно чередуются слева, справа, слева и т. Д. Вы слышите звук из обоих динамиков или только из левого?   -  person Retired Ninja    schedule 01.12.2013
comment
Привет снова, @Retired Ninja. Вы писали о моем последнем вопросе пять часов назад ... Хорошо, я слышу звук в левом динамике только до тех пор, пока не перестанет воспроизводиться короткий звук. Но после того, как звук воспроизводится в левом динамике, в обоих динамиках на короткое время появляется статика (похожая на глючные звуки), после чего программа успешно завершается.   -  person 8-bitButterfly    schedule 01.12.2013
comment
@Retired Ninja Итак, если я напишу в моем типе std::vector<FLAC__int16> data_; вместо std::vector<FLAC__int32> data_; и упакую данные в массив влево, вправо, влево и т. Д. Будет ли это работать?   -  person 8-bitButterfly    schedule 01.12.2013
comment
Я работал! Теперь оба канала работают, но это все еще (глючные звуки) после того, как звук закончился.   -  person 8-bitButterfly    schedule 01.12.2013
comment
Вы тестируете быстрее, чем я печатаю. :) Глядя на это example они, кажется, усекают 32-битные данные до 16 бит при выполнении чередования. Если в конце есть статика, это похоже на то, что в буфере может быть какой-то мусор или размер не соответствует ожиданиям.   -  person Retired Ninja    schedule 01.12.2013
comment
^^ lol ладно, я посмотрю. Я пробовал: struct Data {FLAC__int16 left_; FLAC__int16 right_; }; но было бесполезно ...   -  person 8-bitButterfly    schedule 01.12.2013
comment
У меня теперь работает !!! Я также изменил size_ = (ALuint)(rate_ * channels_ * (bps_ / 8)); на size_ = total_samples_ * sizeof(Source::Data);. Source :: Data - это структура Data { FLAC__int16 left_; FLAC__int16 right_; };, которая теперь является типом данных шахты как таковых std::vector<Source::Data> data_;. Так счастлив! Спасибо @Retired Ninja за все твои подсказки!   -  person 8-bitButterfly    schedule 01.12.2013


Ответы (1)


Решение, которое работает, заключалось в том, чтобы присвоить нижеследующий struct тип векторных данных следующим образом:

struct Data
{

    FLAC__int16 channelLeft_;
    FLAC__int16 channelRight_;

};

std::vector<Source::Data> data_;

чем присвоить size_ так:

size_ = total_samples_ * sizeof(Source::Data);

наконец, цикл данных теперь должен быть:

for(size_t i(0); i < _frame->header.blocksize; i++) {

    data_[index_].channelLeft_ = _buffer[0][i];
    data_[index_].channelRight_ = _buffer[1][i];

    ++index_;
} // jump
person 8-bitButterfly    schedule 01.12.2013