打包左通道和右通道数据



我正在将FLAC音频解码到内存中,并将解码的音频数据传递到OpenAL:void alBufferData (ALuint bufferName, ALenum format, const ALvoid *data, ALsizei size, ALsizei frequency);

来自解码音频的数据进入矿井std::vector<FLAC__int32> data_;。我正试图将LEFT(左)和RIGHT(右)通道封装到其中(AL_FORMAT_STERIO16)。但是,我不明白如何在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

目前,在音频播放过程中,我只听到LEFT频道。在声音播放完毕后会有静态声音,我认为这是丢失的右声道数据。我如何让正确的频道也工作?

此外,这是根据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

一个有效的解决方案是将以下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

最新更新