0

I am decoding FLAC audio into memory, and passing the decoded audio data to the OpenAL: void alBufferData (ALuint bufferName, ALenum format, const ALvoid *data, ALsizei size, ALsizei frequency);

The data from the decoded audio goes into mine std::vector<FLAC__int32> data_;. Into which I am attempting to package the LEFT and RIGHT channels (AL_FORMAT_STEREO16). However, I don't understand how I am to store/align these channels within my data_ vector.

So I have the libFLAC virtual callback member function:

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

At the moment, during audio playback, I am hearing only the LEFT channel. There is static sound after the sound has finished playing which I am assuming is the missing RIGHT channel data. How do i get the RIGHT channel to work also?

Also, this is the metadata callback signature as per 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
greg-449
  • 109,219
  • 232
  • 102
  • 145
8-bitButterfly
  • 203
  • 2
  • 13
  • Presumably it's expecting PCM data which is generally interleaved left, right, left, etc. Do you hear sound from both speakers or only the left? – Retired Ninja Dec 01 '13 at 09:37
  • Hi again @Retired Ninja. You posted on my last question five hours ago... Ok, so i am hearing sound on the left speaker only until the short sound finishes playing. But after the sound has played in the left speaker, the static (glitchy like sounds) is head in both speakers for short time and than program exits successfully. – 8-bitButterfly Dec 01 '13 at 09:45
  • @Retired Ninja So if I made my type say `std::vector data_;` instead of `std::vector data_;` and packed the data into the array left, right, left, etc. Would that work? – 8-bitButterfly Dec 01 '13 at 09:51
  • I did work! Now both channels work but there is still that (glitchy like sounds) after the sound has finished playing. – 8-bitButterfly Dec 01 '13 at 09:54
  • 1
    You test faster than I type. :) Looking at this [example](https://git.xiph.org/?p=flac.git;a=blob;f=examples/cpp/decode/file/main.cpp;h=72a938b86752baa6729037ef128a214ecb764476;hb=HEAD) they appear to truncate the 32-bit data down to 16 bits when doing the interleaving. If there's static at the end it sounds like there might be some garbage in the buffer or the size isn't what it expects. – Retired Ninja Dec 01 '13 at 09:58
  • ^^ lol ok i'll look. What I tried is: struct Data { FLAC__int16 left_; FLAC__int16 right_; }; but was no good... – 8-bitButterfly Dec 01 '13 at 10:04
  • I got it to work now!!! I also changed `size_ = (ALuint)(rate_ * channels_ * (bps_ / 8));` into `size_ = total_samples_ * sizeof(Source::Data);`. Source::Data is the `Data { FLAC__int16 left_; FLAC__int16 right_; };` structure which is now the type for mine data as such `std::vector data_;`. So happy! Thank you @Retired Ninja for all your hints! – 8-bitButterfly Dec 01 '13 at 10:16

1 Answers1

0

A solution which works, was to assagned the below struct as the vector data type like so:

struct Data
{

    FLAC__int16 channelLeft_;
    FLAC__int16 channelRight_;

};

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

than assign the size_ like so:

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

finaly the data loop should now be:

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

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

    ++index_;
} // jump
8-bitButterfly
  • 203
  • 2
  • 13