fmod error solve

This commit is contained in:
antpoms 2025-06-16 20:25:10 +02:00
parent b5e08cedd5
commit ec790fd381
4 changed files with 74 additions and 75 deletions

View file

@ -8,12 +8,12 @@
class AudioEmitter { class AudioEmitter {
private: private:
std::unique_ptr<FMOD::System> system; FMOD::System* system{ nullptr };
FMOD::Sound* metronome_Sound; FMOD::Sound* metronome_Sound{ nullptr };
FMOD::Channel *timer{nullptr}; FMOD::Channel *timer{nullptr};
std::vector<std::unique_ptr<FMOD::Sound>> chords; std::vector<FMOD::Sound*> chords;
std::vector<std::unique_ptr<FMOD::Sound>> drums; std::vector<FMOD::Sound*> drums;
std::vector<std::unique_ptr<FMOD::Sound>> notes; std::vector<FMOD::Sound*> notes;
std::vector<std::vector<float>> markov_matrix_chords; std::vector<std::vector<float>> markov_matrix_chords;
std::vector<std::vector<float>> markov_matrix_melody; std::vector<std::vector<float>> markov_matrix_melody;
int nbr_melo_max{4}; int nbr_melo_max{4};
@ -27,9 +27,9 @@ private:
public: public:
int tempo{ 170 }; int tempo{ 170 };
AudioEmitter(); AudioEmitter();
~AudioEmitter();
std::vector<std::pair<float, int>> generateMusic(); std::vector<std::pair<float, int>> generateMusic();
void audioUpdate(); void audioUpdate();
void audioEnd();
int firstChord(); int firstChord();
int nextChord(int currentChord); int nextChord(int currentChord);
int firstNote(); int firstNote();

View file

@ -19,83 +19,71 @@ auto fmodSoundDeleter = [](FMOD::Sound *sound) {
}; };
AudioEmitter::AudioEmitter() { AudioEmitter::AudioEmitter() {
FMOD::System *rawSystem = nullptr; ERRCHECK(FMOD::System_Create(&system));
ERRCHECK(FMOD::System_Create(&rawSystem));
system.reset(rawSystem);
ERRCHECK(system->init(512, FMOD_INIT_NORMAL, nullptr)); ERRCHECK(system->init(512, FMOD_INIT_NORMAL, nullptr));
std::vector<FMOD::Sound *> rawChords(7); chords.resize(14);
ERRCHECK(system->createSound("media/chords/variation1/C.mp3", FMOD_LOOP_OFF, nullptr, 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, 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, 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, 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, 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, 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, ERRCHECK(system->createSound("media/chords/variation1/B.mp3", FMOD_LOOP_OFF, nullptr,
&rawChords[6])); &chords[6]));
std::vector<FMOD::Sound*> rawChords2(7); std::vector<FMOD::Sound*> rawChords2(7);
ERRCHECK(system->createSound("media/chords/variation2/C.mp3", FMOD_LOOP_OFF, nullptr, 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, 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, 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, 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, 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, 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, ERRCHECK(system->createSound("media/chords/variation2/B.mp3", FMOD_LOOP_OFF, nullptr,
&rawChords2[6])); &chords[13]));
for (int i = 0; i < 7; i += 1) {
chords.push_back(std::unique_ptr<FMOD::Sound>(rawChords[i]));
}
for (int i = 0; i < 7; i += 1) {
chords.push_back(std::unique_ptr<FMOD::Sound>(rawChords2[i]));
}
std::vector<FMOD::Sound *> rawNotes(15); notes.resize(15);
ERRCHECK(system->createSound("media/notes/A1.mp3", FMOD_LOOP_OFF, nullptr, ERRCHECK(system->createSound("media/notes/A1.mp3", FMOD_LOOP_OFF, nullptr,
&rawNotes[0])); &notes[0]));
ERRCHECK(system->createSound("media/notes/B1.mp3", FMOD_LOOP_OFF, nullptr, ERRCHECK(system->createSound("media/notes/B1.mp3", FMOD_LOOP_OFF, nullptr,
&rawNotes[1])); &notes[1]));
ERRCHECK(system->createSound("media/notes/C1.mp3", FMOD_LOOP_OFF, nullptr, ERRCHECK(system->createSound("media/notes/C1.mp3", FMOD_LOOP_OFF, nullptr,
&rawNotes[2])); &notes[2]));
ERRCHECK(system->createSound("media/notes/D1.mp3", FMOD_LOOP_OFF, nullptr, ERRCHECK(system->createSound("media/notes/D1.mp3", FMOD_LOOP_OFF, nullptr,
&rawNotes[3])); &notes[3]));
ERRCHECK(system->createSound("media/notes/E1.mp3", FMOD_LOOP_OFF, nullptr, ERRCHECK(system->createSound("media/notes/E1.mp3", FMOD_LOOP_OFF, nullptr,
&rawNotes[4])); &notes[4]));
ERRCHECK(system->createSound("media/notes/F1.mp3", FMOD_LOOP_OFF, nullptr, ERRCHECK(system->createSound("media/notes/F1.mp3", FMOD_LOOP_OFF, nullptr,
&rawNotes[5])); &notes[5]));
ERRCHECK(system->createSound("media/notes/G1.mp3", FMOD_LOOP_OFF, nullptr, ERRCHECK(system->createSound("media/notes/G1.mp3", FMOD_LOOP_OFF, nullptr,
&rawNotes[6])); &notes[6]));
ERRCHECK(system->createSound("media/notes/A2.mp3", FMOD_LOOP_OFF, nullptr, ERRCHECK(system->createSound("media/notes/A2.mp3", FMOD_LOOP_OFF, nullptr,
&rawNotes[7])); &notes[7]));
ERRCHECK(system->createSound("media/notes/B2.mp3", FMOD_LOOP_OFF, nullptr, ERRCHECK(system->createSound("media/notes/B2.mp3", FMOD_LOOP_OFF, nullptr,
&rawNotes[8])); &notes[8]));
ERRCHECK(system->createSound("media/notes/C2.mp3", FMOD_LOOP_OFF, nullptr, ERRCHECK(system->createSound("media/notes/C2.mp3", FMOD_LOOP_OFF, nullptr,
&rawNotes[9])); &notes[9]));
ERRCHECK(system->createSound("media/notes/D2.mp3", FMOD_LOOP_OFF, nullptr, ERRCHECK(system->createSound("media/notes/D2.mp3", FMOD_LOOP_OFF, nullptr,
&rawNotes[10])); &notes[10]));
ERRCHECK(system->createSound("media/notes/E2.mp3", FMOD_LOOP_OFF, nullptr, ERRCHECK(system->createSound("media/notes/E2.mp3", FMOD_LOOP_OFF, nullptr,
&rawNotes[11])); &notes[11]));
ERRCHECK(system->createSound("media/notes/F2.mp3", FMOD_LOOP_OFF, nullptr, ERRCHECK(system->createSound("media/notes/F2.mp3", FMOD_LOOP_OFF, nullptr,
&rawNotes[12])); &notes[12]));
ERRCHECK(system->createSound("media/notes/G2.mp3", FMOD_LOOP_OFF, nullptr, ERRCHECK(system->createSound("media/notes/G2.mp3", FMOD_LOOP_OFF, nullptr,
&rawNotes[13])); &notes[13]));
ERRCHECK(system->createSound("media/notes/A3.mp3", FMOD_LOOP_OFF, nullptr, ERRCHECK(system->createSound("media/notes/A3.mp3", FMOD_LOOP_OFF, nullptr,
&rawNotes[14])); &notes[14]));
for (int i = 0; i < 15; i += 1) {
notes.push_back(std::unique_ptr<FMOD::Sound>(rawNotes[i]));
}
index_note = firstNote(); index_note = firstNote();
@ -287,7 +275,7 @@ std::vector<std::pair<float, int>> 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 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 //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<std::pair<float, int>> result; std::vector<std::pair<float, int>> 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; return result;
} }
result.reserve(16 * nbr_melo_max); result.reserve(16 * nbr_melo_max);
@ -325,7 +313,7 @@ std::vector<std::pair<float, int>> AudioEmitter::generateMusic() {
// Chords // Chords
FMOD::Channel *channelChords = nullptr; FMOD::Channel *channelChords = nullptr;
int index_chord = chordProgression[i % 4]; 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)); &channelChords));
unsigned long long delay = unsigned long long delay =
@ -342,7 +330,7 @@ std::vector<std::pair<float, int>> AudioEmitter::generateMusic() {
std::vector<float> rythme_melodie = rythmes[index_rythme]; std::vector<float> rythme_melodie = rythmes[index_rythme];
for (float time : rythme_melodie) { for (float time : rythme_melodie) {
FMOD::Channel* channelNote = nullptr; FMOD::Channel* channelNote = nullptr;
ERRCHECK(system->playSound(notes[index_note].get(), nullptr, true, ERRCHECK(system->playSound(notes[index_note], nullptr, true,
&channelNote)); &channelNote));
float note_start = (i + time / 8.f) * beatDuration; float note_start = (i + time / 8.f) * beatDuration;
unsigned long long delayNote = unsigned long long delayNote =
@ -359,31 +347,45 @@ std::vector<std::pair<float, int>> AudioEmitter::generateMusic() {
return result; 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 //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 //FMOD a sa propre gestion mémoire, on doit donc simplement lui signaler que nous n'avons plus besoin de ses éléments
for (int i = 0; i < activeChannels.size(); i += 1) { for (auto& note : notes) {
if (activeChannels[i]) { note->release();
activeChannels[i]->stop();
}
} }
for (int i = 0; i < notes.size(); i += 1) { notes.clear();
notes[i].get()->release();
for (auto& chord : chords) {
chord->release();
} }
for (int i = 0; i < chords.size(); i += 1) { chords.clear();
chords[i].get()->release();
for (auto& drum : drums) {
drum->release();
} }
drums.clear();
timer->stop(); timer->stop();
timer = nullptr;
metronome_Sound->release(); metronome_Sound->release();
metronome_Sound = nullptr;
system->close(); system->close();
system->release(); system->release();
system = nullptr;
} }
float AudioEmitter::getTimeTempo() const { float AudioEmitter::getTimeTempo() const {
//Renvoie le temps écoulé depuis le début de la musique, en beat musicaux //Renvoie le temps écoulé depuis le début de la musique, en beat musicaux
//Par exemple, renvoie 4 au bout d'une mesure //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; float beatDuration = tempo / 60.f / 8.f;
unsigned long long dspClock = 0; unsigned long long dspClock = 0;
ERRCHECK(timer->getDSPClock(&dspClock, nullptr)); ERRCHECK(timer->getDSPClock(&dspClock, nullptr));
@ -392,6 +394,9 @@ float AudioEmitter::getTimeTempo() const {
float AudioEmitter::getTime() const { float AudioEmitter::getTime() const {
//Renvoie le temps écoulé depuis le début de la musique, en secondes //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; unsigned long long dspClock = 0;
ERRCHECK(timer->getDSPClock(&dspClock, nullptr)); ERRCHECK(timer->getDSPClock(&dspClock, nullptr));
return dspClock / 48000.f; return dspClock / 48000.f;

View file

@ -94,14 +94,12 @@ void Game::run() {
processEvents(audioEmitter); processEvents(audioEmitter);
audioEmitter.audioUpdate(); audioEmitter.audioUpdate();
update(TimePerFrame); update(TimePerFrame);
updateStatistics(audioEmitter);
} }
} }
void Game::processEvents(AudioEmitter &audioEmitter) { void Game::processEvents(AudioEmitter &audioEmitter) {
while (const std::optional event = mWindow.pollEvent()) { while (const std::optional event = mWindow.pollEvent()) {
if (event->is<sf::Event::Closed>()) { if (event->is<sf::Event::Closed>()) {
audioEmitter.audioEnd();
mWindow.close(); mWindow.close();
break; break;
} }
@ -145,15 +143,6 @@ void Game::render() {
mWindow.display(); 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) { void Game::update_scores(bool good_action) {
if (good_action) { if (good_action) {
score += score_multiplier; score += score_multiplier;

View file

@ -2,6 +2,10 @@
#include "NoteSprite.hpp" #include "NoteSprite.hpp"
#include <iostream> #include <iostream>
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
int main() { int main() {
// from out/build/src // from out/build/src
if (!NoteSprite::loadTexture("media/sprites/flower_tile.png")) { if (!NoteSprite::loadTexture("media/sprites/flower_tile.png")) {
@ -10,4 +14,5 @@ int main() {
} }
Game game; Game game;
game.run(); game.run();
return 0;
} }