Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Constantly growing audio delay (Android), or very loud noise, or no audio at all (Linux) #11585

Open
NicolasFirmo opened this issue Dec 5, 2024 · 0 comments

Comments

@NicolasFirmo
Copy link

I'm trying to read the default device audio data and use that to render a audio wave on the screen.

On Android (13), the program reads the audio data but it the signal shown on the screen is delayed, and this delay constantly grows over time, for example, if I tap the mic with my finger, the wave sound corresponding to my tap appears 1 second later, when I try that again the corresponding wave appears 2 seconds later, and so on...

On Linux (Pop!_OS) the delay behavior is not present, but the wave shown for my connected mic is just floor noise, nothing stands out if I talk or tap it. If I unplug and use the computer mic, a very loud signal is shown, the floor noise just clips out, If I tap or talk the signal gets even more cliped.

static std::array<SDL_FPoint, 1024> lines;
static u32                          nextSampleIndex = 0;

static void streamCallback(void* const /*userdata*/,
                           SDL_AudioStream* const stream,
                           const i32              additionalAmount,
                           const i32 /*totalAmount*/) {
    const u32 numSamplesReceived = additionalAmount / sizeof(f32);
    const u32 numSamplesToRead   = SDL_min(numSamplesReceived, lines.size() - nextSampleIndex);

    const f32 displayWidth  = (f32)Display::width();
    const f32 displayHeight = (f32)Display::height();

    std::array<f32, lines.size()> buf{};
    SDL_GetAudioStreamData(stream, buf.data(), (i32)(numSamplesToRead * sizeof(f32)));

    for (u32 i = 0; i < numSamplesToRead; ++i, ++nextSampleIndex) {
        lines[nextSampleIndex].y = displayHeight / 2.0F + 100.0F * buf[i];
        lines[nextSampleIndex].x = displayWidth * ((f32)i / (f32)buf.size());
    }

    if (nextSampleIndex == lines.size()) {
        nextSampleIndex = 0;
    }
}

// after initing SDL:
bool App::run() {
    const SDL_AudioSpec audioSpec   = {.format = SDL_AudioFormat::SDL_AUDIO_F32, .channels = 1, .freq = 44100};
    SDL_AudioStream*    audioStream = SDL_OpenAudioDeviceStream(
        SDL_AUDIO_DEVICE_DEFAULT_RECORDING, &audioSpec, streamCallback, nullptr);
    if (audioStream == nullptr) {
        logging::log(logging::LogLevel::ERROR, "SDL_OpenAudioDeviceStream failed ({})", SDL_GetError());
        return false;
    }

    SDL_ResumeAudioStreamDevice(audioStream);

    while (running) {
        processEvents();

        Display::setDrawColor();
        Display::clear();

        Display::setDrawColor({.r = 0XFF, .g = 0XFF, .b = 0XFF, .a = 0XFF});
        Display::draw(lines);

        Display::show();
    }

    SDL_DestroyAudioStream(audioStream);

    return true;
}

// Display funcs

bool Display::clear() {
    if (!SDL_RenderClear(renderer)) {
        logging::log(logging::LogLevel::ERROR, "SDL_RenderClear failed ({})", SDL_GetError());
        return false;
    }

    return true;
}

bool Display::show() {
    if (!SDL_RenderPresent(renderer)) {
        logging::log(logging::LogLevel::ERROR, "SDL_RenderPresent failed ({})", SDL_GetError());
        return false;
    }

    return true;
}

bool Display::setDrawColor(const SDL_Color drawColor) {
    const auto [r, g, b, a] = drawColor;
    if (!SDL_SetRenderDrawColor(renderer, r, g, b, a)) {
        logging::log(logging::LogLevel::ERROR, "SDL_SetRenderDrawColor failed ({})", SDL_GetError());
        return false;
    }

    return true;
}

bool Display::draw(const std::span<const SDL_FPoint> lines) {
    if (!SDL_RenderLines(renderer, lines.data(), (i32)lines.size())) {
        logging::log(logging::LogLevel::ERROR, "SDL_RenderLines failed ({})", SDL_GetError());
        return false;
    }

    return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant