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

View file

@ -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<FMOD::Sound *> 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<FMOD::Sound*> 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<FMOD::Sound>(rawChords[i]));
}
for (int i = 0; i < 7; i += 1) {
chords.push_back(std::unique_ptr<FMOD::Sound>(rawChords2[i]));
}
&chords[13]));
std::vector<FMOD::Sound *> rawNotes(15);
notes.resize(15);
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,
&rawNotes[1]));
&notes[1]));
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,
&rawNotes[3]));
&notes[3]));
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,
&rawNotes[5]));
&notes[5]));
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,
&rawNotes[7]));
&notes[7]));
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,
&rawNotes[9]));
&notes[9]));
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,
&rawNotes[11]));
&notes[11]));
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,
&rawNotes[13]));
&notes[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<FMOD::Sound>(rawNotes[i]));
}
&notes[14]));
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 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;
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<std::pair<float, int>> 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<std::pair<float, int>> AudioEmitter::generateMusic() {
std::vector<float> 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<std::pair<float, int>> 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;

View file

@ -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<sf::Event::Closed>()) {
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;

View file

@ -2,6 +2,10 @@
#include "NoteSprite.hpp"
#include <iostream>
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
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;
}