1

From this Lazy Foo tutorial (https://lazyfoo.net/tutorials/SDL/21_sound_effects_and_music/index.php) I wrote the following lines of code:

#include <SDL.h>
#include <SDL_mixer.h>

bool running = true;
int main(int argc, char** argv) {
    SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
    SDL_Window* window = SDL_CreateWindow("testing musique", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, 0);
    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    SDL_Event quit;
    Mix_Music* music;

    while (running) {
        while(SDL_PollEvent(&quit)){
            switch(quit.type) {
            case SDL_QUIT:
                running = false;
                break;
            }
        }

        Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048);
        music = Mix_LoadMUS("../pikachu/keypress_BMP/beat.wav");
        Mix_PlayMusic(music, -1);

        SDL_SetRenderDrawColor(renderer, 20, 20, 255, 255);
        SDL_RenderClear(renderer);
        SDL_RenderPresent(renderer);
    }

    Mix_FreeMusic(music);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
}

I even used the same audio file (beat.wav) as Lazy Foo did in his tutorial, but while his program runs without a hitch, mine plays the wav too fast (despite the fact that I checked every parameters to make sure mine matched with his). I tried decreasing the frequency parameter in Mix_OpenAudio, but while the wav did slow down, so did the pitch, and it should not have made sense to do this in the first place. What should I do?

genpfault
  • 51,148
  • 11
  • 85
  • 139
  • You're calling (most notably) `Mix_PlayMusic` inside `while (running)` loop where the tutorial only calls it once per keystroke that plays/resumes sound. – orhtej2 Mar 21 '22 at 08:43
  • By 'most notably' I mean also that you're needlessly calling `Mix_OpenAudio` and `Mix_LoadMUS` outside of initialization, the latter likely leaking resources. – orhtej2 Mar 21 '22 at 08:44
  • That's precisely the problem haha - I've moved the module out of the while loop and it worked! Thank you so much @orhtej2 – Hoang Tho Nguyen Mar 21 '22 at 09:56

1 Answers1

0

The audio subsystem should only be opened once, before the main loop, meanwhile you open it in each iteration of the loop. The same goes for loading the file into memory — again on each iteration of the loop, instead of once. So the correct code structure should look like this:

#include <SDL.h>
#include <SDL_mixer.h>

int main(int argc, char** argv) {
    bool running = true;
    SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);

    SDL_Window* window = SDL_CreateWindow("testing musique", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, 0);
    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);

    // open audio and load music file before main loop
    Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048);
    Mix_Music* music = Mix_LoadMUS("../pikachu/keypress_BMP/beat.wav");

    SDL_Event event;

    while (running) {
        while(SDL_PollEvent(&event)){
            switch(event.type) {
            case SDL_KEYDOWN:
                switch(event.key.keysym.sym) {
                case SDLK_P:
                    Mix_PlayMusic(music, -1);
                    break;
                case SDLK_S:
                    Mix_HaltMusic();
                    break;
                }
            case SDL_QUIT:
                running = false;
                break;
            }
        }

        SDL_SetRenderDrawColor(renderer, 20, 20, 255, 255);
        SDL_RenderClear(renderer);
        SDL_RenderPresent(renderer);
    }

    // close audio and free the music after main loop
    Mix_CloseAudio();
    Mix_FreeMusic(music);

    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
}

Don't forget about Mix_CloseAudio and about error checking.