Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Playing multiple music files doesn't work  (Read 2881 times)

0 Members and 1 Guest are viewing this topic.

BjornVB

  • Newbie
  • *
  • Posts: 5
    • View Profile
Playing multiple music files doesn't work
« on: September 22, 2023, 10:39:45 am »
Using SFML, I want to be able to play multiple music files at once.
My code currently looks like this:

#include <SFML/Audio.hpp>
#include <iostream>
#include <thread>
#include <vector>
#include <semaphore.h>

using namespace std;

void playMusic(const string &filename, float volume = 50.0f, float pitch = 1.0f) {
    sf::Music music;
    if (!music.openFromFile(filename)) {
        cerr << "Failed to load " << filename << endl;
        return;
    }
    music.setPitch(pitch);
    music.setVolume(volume);
    music.play();

    while (music.getStatus() == sf::Music::Playing) {
        this_thread::sleep_for(chrono::milliseconds(100));
    }

    music.stop();
}

int main() {
    vector<string> musicFiles = {"../res/test.wav", "../res/test.mp3"};

    vector<thread> threads;

    sem_t sem;
    sem_init(&sem, 0, 1);
    for (size_t i = 0; i < musicFiles.size(); i++) {
        sem_wait(&sem);

        string filename = musicFiles[i];
        float pitch = 1.0f + (i * 0.1f);

        threads.emplace_back([pitch, filename, &sem]() {
            playMusic(filename, 50.0f, pitch);
            sem_post(&sem);
        });
    }

    for (auto &thread: threads) {
        thread.join();
    }

    return 0;
}

For each music file, the application makes a new thread and starts playing the file on that thread.

However, when I run the application, only one music file starts playing at a time.

Is there any way to fix this and relocate these music objects to the heap, or is this truly the limit of SFML?

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11033
    • View Profile
    • development blog
    • Email
Re: Playing multiple music files doesn't work
« Reply #1 on: September 22, 2023, 12:05:52 pm »
No idea what semaphore.h does, but does this not ensure that only one thread is running at once?

I recommend to not use multi-threading here.
SFML already plays the audio in a separate thread, so you can just poll the status on the main thread.

You could have a std::vector<sf::Music> and just check their status every frame.
Use a stable container if you wish to update the number of music instances dynamically, as a std::vector would lead to a moving of playing instances, causing them to stop.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

BjornVB

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Playing multiple music files doesn't work
« Reply #2 on: September 23, 2023, 02:42:51 pm »
Alright, so that works really well! Thanks for the suggestion.
Got rid of the semaphore- and thread-related code, made a list of sf::Music object pointers and it works flawlessly. Can play dozens of music files simultaneously now.

Thanks a bunch!