4

I am recording my microphone with SDL2. Somehow the callback is called after about 2 seconds. I expected it to be called immediately.

If'd I create a callback for my speaker it'll be called immediately.

Here is a MWE where I get the delay:

#include <SDL2/SDL.h>

void cb(void *userdata, Uint8 *stream, int len) {
    printf("Callback at %u\n", SDL_GetTicks());
}

int main() {
    SDL_Init(SDL_INIT_AUDIO);

    SDL_AudioDeviceID dev;

    SDL_AudioSpec want, have;

    SDL_zero(want);
    want.freq = 44100;
    want.format = AUDIO_S16SYS;
    want.channels = 1;
    want.samples = 1024;
    want.callback = cb;
    dev = SDL_OpenAudioDevice(SDL_GetAudioDeviceName(0, 1), 1, &want, &have, 0);

    if (have.format != want.format) {
        SDL_Log("We didn't get the wanted format.");
        return 1;
    }

    SDL_PauseAudioDevice(dev, 0);

    if (dev == 0) {
        SDL_Log("Failed to open audio: %s", SDL_GetError());
        return 1;
    }

    printf("Started at %u\n", SDL_GetTicks());
    SDL_Delay(5000);

    SDL_CloseAudioDevice(dev);
}

My output is

Started at 21

Callback at 2001

Callback at 2001

Callback at 2001

and so on.

I also changed want.freq and want.samples to smaller numbers with no effect.

Community
  • 1
  • 1
Peter
  • 41
  • 1
  • 3
  • Are you sure it's not just a standard output or terminal buffering issue? You might wish to include a wall-clock timestamp in the printed output, perhaps `printf("Started at %u\n", SDL_GetTicks());` and `printf("Callback at %u\n", SDL_GetTicks());`, and see what the difference is between the first two. (The values are milliseconds since SDL initialization, according to the [documentation](http://wiki.libsdl.org/SDL_GetTicks?highlight=%28%5CbCategoryAPI%5Cb%29%7C%28SDLFunctionTemplate%29).) – Nominal Animal Mar 24 '17 at 01:59
  • Nice idea :) This is my result: `Started at 21`, `Callback at 2001` – Peter Mar 24 '17 at 02:03
  • Could you show what `printf("Started at %u, expect next in %d\n", SDL_GetTicks(), (1000*have.samples)/have.freq);` outputs? I would expect a `1000*have.samples/have.freq` millisecond delay between the two (thus the print), since that is how long it takes to record the audio. With 1024 samples at 44100 samples/sec that's about 23 milliseconds. The repeated `Callback at 2001` is very puzzling, however: it should increment by around 23, not stay constant. Weird. – Nominal Animal Mar 24 '17 at 03:59
  • Also, I am assuming your SDL version is at least 2.0.5, since recording [was not supported in SDL version 2.0 prior to 2.0.5](https://wiki.libsdl.org/SDL_OpenAudioDevice). Have you checked whether this is a known bug or not? – Nominal Animal Mar 24 '17 at 04:02
  • The output is `Started at 24, expect next in 11`. I am using 2.0.5. I didn't find any related bugs. After `Started` I get some `Callback at 2001`, then some `2002`, then some `3981`, then some `5962`. As you said, the callback should be called with a 11 second delay every time.. – Peter Mar 24 '17 at 10:15
  • 5
    Ah, I think I see what is happening. SDL has an internal buffer it records to, which is slightly less than one second long in samples. Rather than call the callback whenever there is sufficient information, it batches them up! In other words, the first time SDL calls your callback it already has about a seconds' worth recorded, and thus calls your callback a bunch of times. I'm not sure how to avoid this. (The amount buffered is in `SDL_AudioDevice->spec.size`, but callback only takes `SDL_AudioDevice->callbackspec.size`; it seems those two do not match in SDL `src/audio/SDL_audio.c`.) – Nominal Animal Mar 24 '17 at 13:32
  • This could be made into an answer. On my device one has to click "show more" to see the last comment. – Mörkö May 05 '18 at 08:30
  • @NominalAnimal can you post your solution as an answer? I'm looking at using SDL for low-latency recording & processing, and I'd need to do this. – Petrus Theron Mar 04 '19 at 13:04

0 Answers0