Decoding with OGG/Vorbis gives no sound

210 Views Asked by At

I'd like to play an Ogg/Vorbis audio/video file, but right now I can't get to read audio from a file.

My algorithm to read audio is:

  • Initialize required structures:
vorbis_info info;
vorbis_comment comment;
vorbis_dsp_state dsp;
vorbis_block block;

vorbis_info_init(&info);
vorbis_comment_init(&comment);
  • Read headers:
    • Call vorbis_synthesis_headerin(&info, &comment, packet); until it returns OV_ENOTVORBIS
    • vorbis_synthesis_init(&dsp, &info);
    • vorbis_block_init(&dsp, &block);
    • Pass the first non-header packet to function below
  • Parse packets, do it until audioReady == READY
putPacket(ogg_packet *packet) {
    int ret;
    ret = vorbis_synthesis(&block, packet);
    if( ret == 0 ) {
        ret = vorbis_synthesis_blockin(&dsp, &block);
        audioReady = (ret == 0) ? READY : NOT_READY;
    } else {
        audioReady = NOT_READY;
    }
}
  • Read audio data:
float** rawData = nullptr;
readSamples = vorbis_synthesis_pcmout(&dsp, &rawData);
if( readSamples == 0 ) {
    audioReady = NOT_READY;
    return;
}

int16_t* newData = new int16_t[readSamples * getChannels()];
int16_t* dst = newData;
for(unsigned int i=0; i<readSamples; ++i) {
    for(unsigned char ch=0; ch<getChannels(); ++ch) {
        *(dst++) = math::clamp<int16_t>(rawData[ch][i]*32767 + 0.5f, -32767, 32767);
    }
}
audioData.push_back({readSamples * getChannels() , newData});
vorbis_synthesis_read(&dsp, static_cast<int>(readSamples));

audioReady = NOT_READY;

This is where it gets wrong: after examining the newData contents it is revealed that it contains a very silent sound. I doubt if it is the right data which means somewhere along my algorithm I did something wrong.

I tried to find some examples of similar programs, but all I got are sources with very spaghetti-like code, which seems to do the same algorithm like mine, yet they do their job. (There is one off such library: https://github.com/icculus/theoraplay )

Is there any reason why I'm getting (almost) silence in my application?

PS: If you are wondering if I might getting OGG packets wrong, then I assure you this part of my code is working right, as I'm also reading video data from the same file, using the same code and it shows the video right.

1

There are 1 best solutions below

0
Felix.leg On

I've found it: during reading packets I assumed that one Ogg Page = one Ogg packet. I's wrong: for audio one page can contain many packets. To read it properly one has to make a code like:

do{
   putPacket(&packet);
}while( ogg_stream_packetout(&state, &packet) == 1 );

I did this mistake because for video packets (which I did first) a page contains only one packet.