diff --git a/SimpleGame/src/Include/AudioEmitter.hpp b/SimpleGame/src/Include/AudioEmitter.hpp index 4cb6dd2..bcf036c 100644 --- a/SimpleGame/src/Include/AudioEmitter.hpp +++ b/SimpleGame/src/Include/AudioEmitter.hpp @@ -8,12 +8,12 @@ class AudioEmitter { private: - std::unique_ptr system; - FMOD::Sound* metronome_Sound; + FMOD::System* system{ nullptr }; + FMOD::Sound* metronome_Sound{ nullptr }; FMOD::Channel *timer{nullptr}; - std::vector> chords; - std::vector> drums; - std::vector> notes; + std::vector chords; + std::vector drums; + std::vector notes; std::vector> markov_matrix_chords; std::vector> markov_matrix_melody; int nbr_melo_max{4}; @@ -27,9 +27,9 @@ private: public: int tempo{ 170 }; AudioEmitter(); + ~AudioEmitter(); std::vector> generateMusic(); void audioUpdate(); - void audioEnd(); int firstChord(); int nextChord(int currentChord); int firstNote(); diff --git a/SimpleGame/src/Source/AudioEmitter.cpp b/SimpleGame/src/Source/AudioEmitter.cpp index 6dfa401..8705b82 100644 --- a/SimpleGame/src/Source/AudioEmitter.cpp +++ b/SimpleGame/src/Source/AudioEmitter.cpp @@ -19,83 +19,71 @@ auto fmodSoundDeleter = [](FMOD::Sound *sound) { }; AudioEmitter::AudioEmitter() { - FMOD::System *rawSystem = nullptr; - ERRCHECK(FMOD::System_Create(&rawSystem)); - - system.reset(rawSystem); + ERRCHECK(FMOD::System_Create(&system)); ERRCHECK(system->init(512, FMOD_INIT_NORMAL, nullptr)); - std::vector rawChords(7); + chords.resize(14); ERRCHECK(system->createSound("media/chords/variation1/C.mp3", FMOD_LOOP_OFF, nullptr, - &rawChords[0])); + &chords[0])); ERRCHECK(system->createSound("media/chords/variation1/D.mp3", FMOD_LOOP_OFF, nullptr, - &rawChords[1])); + &chords[1])); ERRCHECK(system->createSound("media/chords/variation1/E.mp3", FMOD_LOOP_OFF, nullptr, - &rawChords[2])); + &chords[2])); ERRCHECK(system->createSound("media/chords/variation1/F.mp3", FMOD_LOOP_OFF, nullptr, - &rawChords[3])); + &chords[3])); ERRCHECK(system->createSound("media/chords/variation1/G.mp3", FMOD_LOOP_OFF, nullptr, - &rawChords[4])); + &chords[4])); ERRCHECK(system->createSound("media/chords/variation1/A.mp3", FMOD_LOOP_OFF, nullptr, - &rawChords[5])); + &chords[5])); ERRCHECK(system->createSound("media/chords/variation1/B.mp3", FMOD_LOOP_OFF, nullptr, - &rawChords[6])); + &chords[6])); std::vector rawChords2(7); ERRCHECK(system->createSound("media/chords/variation2/C.mp3", FMOD_LOOP_OFF, nullptr, - &rawChords2[0])); + &chords[7])); ERRCHECK(system->createSound("media/chords/variation2/D.mp3", FMOD_LOOP_OFF, nullptr, - &rawChords2[1])); + &chords[8])); ERRCHECK(system->createSound("media/chords/variation2/E.mp3", FMOD_LOOP_OFF, nullptr, - &rawChords2[2])); + &chords[9])); ERRCHECK(system->createSound("media/chords/variation2/F.mp3", FMOD_LOOP_OFF, nullptr, - &rawChords2[3])); + &chords[10])); ERRCHECK(system->createSound("media/chords/variation2/G.mp3", FMOD_LOOP_OFF, nullptr, - &rawChords2[4])); + &chords[11])); ERRCHECK(system->createSound("media/chords/variation2/A.mp3", FMOD_LOOP_OFF, nullptr, - &rawChords2[5])); + &chords[12])); ERRCHECK(system->createSound("media/chords/variation2/B.mp3", FMOD_LOOP_OFF, nullptr, - &rawChords2[6])); - for (int i = 0; i < 7; i += 1) { - chords.push_back(std::unique_ptr(rawChords[i])); - } - for (int i = 0; i < 7; i += 1) { - chords.push_back(std::unique_ptr(rawChords2[i])); - } + &chords[13])); - std::vector rawNotes(15); + notes.resize(15); ERRCHECK(system->createSound("media/notes/A1.mp3", FMOD_LOOP_OFF, nullptr, - &rawNotes[0])); + ¬es[0])); ERRCHECK(system->createSound("media/notes/B1.mp3", FMOD_LOOP_OFF, nullptr, - &rawNotes[1])); + ¬es[1])); ERRCHECK(system->createSound("media/notes/C1.mp3", FMOD_LOOP_OFF, nullptr, - &rawNotes[2])); + ¬es[2])); ERRCHECK(system->createSound("media/notes/D1.mp3", FMOD_LOOP_OFF, nullptr, - &rawNotes[3])); + ¬es[3])); ERRCHECK(system->createSound("media/notes/E1.mp3", FMOD_LOOP_OFF, nullptr, - &rawNotes[4])); + ¬es[4])); ERRCHECK(system->createSound("media/notes/F1.mp3", FMOD_LOOP_OFF, nullptr, - &rawNotes[5])); + ¬es[5])); ERRCHECK(system->createSound("media/notes/G1.mp3", FMOD_LOOP_OFF, nullptr, - &rawNotes[6])); + ¬es[6])); ERRCHECK(system->createSound("media/notes/A2.mp3", FMOD_LOOP_OFF, nullptr, - &rawNotes[7])); + ¬es[7])); ERRCHECK(system->createSound("media/notes/B2.mp3", FMOD_LOOP_OFF, nullptr, - &rawNotes[8])); + ¬es[8])); ERRCHECK(system->createSound("media/notes/C2.mp3", FMOD_LOOP_OFF, nullptr, - &rawNotes[9])); + ¬es[9])); ERRCHECK(system->createSound("media/notes/D2.mp3", FMOD_LOOP_OFF, nullptr, - &rawNotes[10])); + ¬es[10])); ERRCHECK(system->createSound("media/notes/E2.mp3", FMOD_LOOP_OFF, nullptr, - &rawNotes[11])); + ¬es[11])); ERRCHECK(system->createSound("media/notes/F2.mp3", FMOD_LOOP_OFF, nullptr, - &rawNotes[12])); + ¬es[12])); ERRCHECK(system->createSound("media/notes/G2.mp3", FMOD_LOOP_OFF, nullptr, - &rawNotes[13])); + ¬es[13])); ERRCHECK(system->createSound("media/notes/A3.mp3", FMOD_LOOP_OFF, nullptr, - &rawNotes[14])); - for (int i = 0; i < 15; i += 1) { - notes.push_back(std::unique_ptr(rawNotes[i])); - } + ¬es[14])); index_note = firstNote(); @@ -287,7 +275,7 @@ std::vector> AudioEmitter::generateMusic() { //Pour générer la musique aléatoirement, on utilise une chaîne de Markov. Sachant qu'on joue un note donnée, on a un ensemble de probabilités pour jouer la note suivante //Pour savoir à quel rythme nous jouons les notes, on tire aléatoirement dans un ensemble de rythmes possibles, on tire des rythmes plus ou moins complexe en fonction de si on est au début ou à la fin de la musique std::vector> result; - if (current_beat >= nbr_melo_total) { //On génère un nombre fini de mélodies, pour avoir une musique de 4min + if (current_beat >= nbr_melo_total || !system) { //On génère un nombre fini de mélodies, pour avoir une musique de 4min return result; } result.reserve(16 * nbr_melo_max); @@ -325,7 +313,7 @@ std::vector> AudioEmitter::generateMusic() { // Chords FMOD::Channel *channelChords = nullptr; int index_chord = chordProgression[i % 4]; - ERRCHECK(system->playSound(chords[index_chord + variation*nbrChords].get(), nullptr, true, + ERRCHECK(system->playSound(chords[index_chord + variation*nbrChords], nullptr, true, &channelChords)); unsigned long long delay = @@ -342,7 +330,7 @@ std::vector> AudioEmitter::generateMusic() { std::vector rythme_melodie = rythmes[index_rythme]; for (float time : rythme_melodie) { FMOD::Channel* channelNote = nullptr; - ERRCHECK(system->playSound(notes[index_note].get(), nullptr, true, + ERRCHECK(system->playSound(notes[index_note], nullptr, true, &channelNote)); float note_start = (i + time / 8.f) * beatDuration; unsigned long long delayNote = @@ -359,31 +347,45 @@ std::vector> AudioEmitter::generateMusic() { return result; } -void AudioEmitter::audioUpdate() { system->update(); } +void AudioEmitter::audioUpdate() { + system->update(); +} -void AudioEmitter::audioEnd() { +AudioEmitter::~AudioEmitter() { //release les différents éléments avant la fin du programme - //FMOD a sa propre gestion mémoire, on doit donc simplement lui signaler que nous n'avons plus besoin de ces éléments - for (int i = 0; i < activeChannels.size(); i += 1) { - if (activeChannels[i]) { - activeChannels[i]->stop(); - } + //FMOD a sa propre gestion mémoire, on doit donc simplement lui signaler que nous n'avons plus besoin de ses éléments + for (auto& note : notes) { + note->release(); } - for (int i = 0; i < notes.size(); i += 1) { - notes[i].get()->release(); + notes.clear(); + + for (auto& chord : chords) { + chord->release(); } - for (int i = 0; i < chords.size(); i += 1) { - chords[i].get()->release(); + chords.clear(); + + for (auto& drum : drums) { + drum->release(); } + drums.clear(); + timer->stop(); + timer = nullptr; + metronome_Sound->release(); + metronome_Sound = nullptr; + system->close(); system->release(); + system = nullptr; } float AudioEmitter::getTimeTempo() const { //Renvoie le temps écoulé depuis le début de la musique, en beat musicaux //Par exemple, renvoie 4 au bout d'une mesure + if (timer==nullptr) { //Si timer n'existe plus, on sort de la fonction + return 0.f; + } float beatDuration = tempo / 60.f / 8.f; unsigned long long dspClock = 0; ERRCHECK(timer->getDSPClock(&dspClock, nullptr)); @@ -392,6 +394,9 @@ float AudioEmitter::getTimeTempo() const { float AudioEmitter::getTime() const { //Renvoie le temps écoulé depuis le début de la musique, en secondes + if (timer==nullptr) { //Si timer n'existe plus, on sort de la fonction + return 0.f; + } unsigned long long dspClock = 0; ERRCHECK(timer->getDSPClock(&dspClock, nullptr)); return dspClock / 48000.f; diff --git a/SimpleGame/src/Source/Game.cpp b/SimpleGame/src/Source/Game.cpp index 68db75a..2d19044 100644 --- a/SimpleGame/src/Source/Game.cpp +++ b/SimpleGame/src/Source/Game.cpp @@ -94,14 +94,12 @@ void Game::run() { processEvents(audioEmitter); audioEmitter.audioUpdate(); update(TimePerFrame); - updateStatistics(audioEmitter); } } void Game::processEvents(AudioEmitter &audioEmitter) { while (const std::optional event = mWindow.pollEvent()) { if (event->is()) { - audioEmitter.audioEnd(); mWindow.close(); break; } @@ -145,15 +143,6 @@ void Game::render() { mWindow.display(); } -void Game::updateStatistics(AudioEmitter &audioEmitter) { - mStatisticsText.setString(std::format( - "Mesure = {}\nBeat = {} us", ceil(audioEmitter.getTimeTempo() / 8.f), - ceil(fmod(audioEmitter.getTimeTempo(), 8.f)))); - - mStatisticsUpdateTime -= sf::seconds(1.0f); - mStatisticsNumFrames = 0; -} - void Game::update_scores(bool good_action) { if (good_action) { score += score_multiplier; diff --git a/SimpleGame/src/Source/Main.cpp b/SimpleGame/src/Source/Main.cpp index 6551ccf..728bde4 100644 --- a/SimpleGame/src/Source/Main.cpp +++ b/SimpleGame/src/Source/Main.cpp @@ -2,6 +2,10 @@ #include "NoteSprite.hpp" #include +#define _CRTDBG_MAP_ALLOC +#include +#include + int main() { // from out/build/src if (!NoteSprite::loadTexture("media/sprites/flower_tile.png")) { @@ -10,4 +14,5 @@ int main() { } Game game; game.run(); + return 0; }