How to play queued audio on SDL Mixer and C++?

Asked

Viewed 129 times

0

I have 4 different audios; I want to play them in a row, press a button and tap 1; when it finishes playing it automatically it starts playing 2, then 3 and then 4.... you can do this in the SDL Mixer?

I only got through the while, however, when it enters it everything stops, it interrupts the other functions... also tried through the tasks of Thread.Join.... but here’s the thing, Join doesn’t know that Task 1 is over.... there has to be a way for C++ to understand that the task has been completed; but I don’t think it recognizes because the method is from an external library....

void tarefa1()
{
    Mix_PlayChannel(1, som_1, 0);

}

void tarefa2()
{
    Mix_PlayChannel(1, som_2, 0);
}

void tocar() {

    thread first(tarefa1);
    thread second(tarefa2);

    first.join();   
    second.join(); 
}

1 answer

0

First of all, a detail: by the description of your problem, the type Mix_Music* seems more appropriate than the guy Mix_Chunk*. Anyway, I’m going to answer the question based on the type Mix_Chunk*.

Regarding the use of std::thread, it seems to me unnecessary, because the function Mix_PlayChannel already runs the song in a separate thread. So, what you could do is use the function Mix_Playing() to know if a song is being played or not and variables to control which song is being played, what’s next, etc.

I did a function to accomplish this task, called Player() and how I wanted to test I prepared the function main() also. I put both below because I think it makes it easier for you to understand what has been done:

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

void Player(Mix_Chunk* mMusic[])
{
    static int previous = 0;
    static int current = 0;

    if (current < 4) {
        if (previous == current) {
            std::cout << "Tocando musica n. " << current + 1 << '\n';
            Mix_PlayChannel(-1, mMusic[current], 1);
            current++;
        }
        if (!Mix_Playing(-1)) {
            previous = current;
        }
    }
}


int main(int argc, char* argv[])
{

    SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
    SDL_Window* window = SDL_CreateWindow("Title",
        SDL_WINDOWPOS_CENTERED,
        SDL_WINDOWPOS_CENTERED,
        960, 540, SDL_WINDOW_SHOWN);
    if (!window) { return -1; }

    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1,
        SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);

    SDL_SetRenderDrawColor(renderer, 50, 50, 50, 255);
    SDL_RenderClear(renderer);

    //Initialize SDL_mixer
    Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048);

    //The music that will be played
    Mix_Chunk *gMusic = Mix_LoadWAV("beat.wav");
    Mix_Chunk* mMusic[4] = { gMusic, gMusic, gMusic, gMusic };
    SDL_Event e;

    int previous = 1;
    int current = 1;


    while (true) {
        while (SDL_PollEvent(&e)) {

            if (e.type == SDL_QUIT) {
                return 0;
            }           
        }

        Player(mMusic);
        SDL_RenderPresent(renderer);
    }   

    //Free the music
    Mix_FreeChunk(gMusic);
    gMusic = NULL;

    //Destroy window    
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    window = NULL;
    renderer = NULL;

    //Quit SDL subsystems
    Mix_Quit();
    SDL_Quit();
    return 0;
}

  • Thanks, V. Santos. Thank you, I’ll test here and come back to post to see if it worked... It is that in fact, I use a form - Win Form... and putting any kind of while the form crashed, did not respond to commands. Actually I decided to put the audio in a thread and using detach() instead of Join... the thread actually runs in parallel and the other things in the program keep responding... but I’ll test your suggestion. If it works, better I don’t need to use threads...

Browser other questions tagged

You are not signed in. Login or sign up in order to post.