fmod error solve
This commit is contained in:
parent
b5e08cedd5
commit
ec790fd381
4 changed files with 74 additions and 75 deletions
|
@ -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();
|
||||||
|
|
|
@ -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]));
|
¬es[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]));
|
¬es[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]));
|
¬es[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]));
|
¬es[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]));
|
¬es[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]));
|
¬es[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]));
|
¬es[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]));
|
¬es[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]));
|
¬es[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]));
|
¬es[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]));
|
¬es[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]));
|
¬es[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]));
|
¬es[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]));
|
¬es[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]));
|
¬es[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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue