1

In a project I'm working on, I'd like to use stb_vorbis to stream audio from an ogg file. However, after implementing the processes to do this, I found the audio was crackly. I feel the problem may be similar to this question, but I can't see where a problem could be.

Here is my code:

#include <SDL2/SDL.h>
#include <stb/vorbis.h>
#include <iostream>

void sdlAudioCallback(void* userData, Uint8* stream, int len)
{
    stb_vorbis* myVorbis = (stb_vorbis*) userData;
    SDL_memset(stream, 0, len);
    stb_vorbis_get_frame_short_interleaved(myVorbis, 2, (short*) stream, len/sizeof(short));
}

int main()
{
    if (SDL_Init(SDL_INIT_AUDIO) != 0)
        return -1;

    int error = 0;
    stb_vorbis_alloc* alloc;
    stb_vorbis* vorbis = stb_vorbis_open_filename("res/thingy.ogg", &error, alloc);

    if (error != 0) 
        return -2;

    stb_vorbis_info info = stb_vorbis_get_info(vorbis);

    SDL_AudioSpec spec;
    spec.freq = info.sample_rate;
    spec.format = AUDIO_S16;
    spec.channels = 2;
    spec.samples = 1024;
    spec.callback = sdlAudioCallback;
    spec.userdata = vorbis;

    if (SDL_OpenAudio(&spec, NULL) < 0) {
        std::cout << "failed to open audio device: " << SDL_GetError() << std::endl;
        SDL_Quit();
        return -3;
    }

    SDL_PauseAudio(0);
    SDL_Delay(5000);
}

More information:
thingy.ogg is from Sean Barrett's samples
building with g++ on an OSX machine

NMorris
  • 72
  • 1
  • 9
  • 1
    Aside from obvious errors like uninitialised `alloc` - you should use `stb_vorbis_get_samples_short_interleaved`, not `_get_frame_` which only extracts single frame. – keltar Jun 20 '18 at 14:40
  • Thank you @keltar, that did fix the problem. What is the correct way to initialise `stb_vorbis_alloc` objects? – NMorris Jun 20 '18 at 23:41
  • If you don't care how stb_vorbis should allocate its memory - just pass `NULL` instead. If you do, read comment about it in the source file. – keltar Jun 21 '18 at 04:12

0 Answers0