Problème arrêt son

LYSANDRE

4 years ago

Bonjour,

Je n'arrive pas à arrêter la mélodie.

j'ai du mal à saisir pourquoi

voici mon code:

#include <Gamebuino-Meta.h>
int Mode = 5;
int Music = -1;
void setup()
{
  // initialize the Gamebuino object
  gb.begin();
  gb.sound.playOK();
}

void loop()
{
  while (!gb.update());
  gb.display.clear();
  switch (Mode)
  {
    case 0:
      Music = -1;
      gb.sound.stop(Music);
      gb.display.print("STOP la musique");

      break;
    case 1:
      break;
    case 5:
      gb.display.print("JOUE la musique");
      // play sound
      Music = gb.sound.play("Space.WAV", true);
      if (gb.buttons.pressed(BUTTON_A))
      {
        Mode = 0;
        gb.sound.playTick();
      }
      break;
  }
}

Codnpix

NEW 4 years ago

Salut, 

Je ne pense pas que tu doives mettre Music = -1; dans le case 0 de ton switch.

-1 est l'identifiant de la track retourné par la fonction play en cas d'échec, tu n'as pas à le réaffecter à ta track manuellement. Tu le mets juste au début dans tes déclaration de variables comme tu as fait. Mais dans ton switch je dirais qu'il faut juste que tu enlèves cette ligne.

Autre chose, je ne sais pas si ça gêne vraiment le fonctionnement mais à ta place je sortirais la gestion de ton input ( if (gb.buttons.pressed(BUTTON_A)) ) du switch. Dans le switch tu te contente de dire ce qui se passe dans un cas ou dans l'autre. Et tu fais une fonction pour faire varier ce Mode qui va faire réagir le switch.

Donc en gros je dirais plutôt quelque chose comme ça :

#include <Gamebuino-Meta.h>
int Mode = 5;
int Music = -1;
void setup()
{
  // initialize the Gamebuino object
  gb.begin();
  gb.sound.playOK();
}

void loop()
{
  while (!gb.update());
  gb.display.clear();
  handleInputs();
  switch (Mode)
  {
    case 0:
      gb.sound.stop(Music);
      gb.display.print("STOP la musique");
      break;
    case 1:
      break;
    case 5:
      gb.display.print("JOUE la musique");
      // play sound
      Music = gb.sound.play("Space.WAV", true);
      break;
  }
}

void handleInputs()
{
    if (gb.buttons.pressed(BUTTON_A))
      {
        Mode = 0;
        gb.sound.playTick();
      }
}

LYSANDRE

NEW 4 years ago

Merci pour les remarques

le code est plus lisible mais j'ai toujours le même problème

la musique continue et ne s'arrête pas quand la variable Mode est à 0.

Codnpix

4 years ago

Ah mince, j'aurais dû tester avant d'envoyer ! Je vais regarder de plus près.

Codnpix

NEW 4 years ago

LYSANDRE LYSANDRE

Ah mince, j'aurais dû tester avant d'envoyer ! Je vais regarder de plus près.

LYSANDRE

NEW 4 years ago

Si ça peux servir voici mon fichier config-gamebuino.h

#define SOUND_CHANNELS 1
#define SOUND_FREQ 44100

pour info : j'avais toujours un problème de grésillement pour mes différents sons ou musiques

j'ai rajouté les paramètres ci-dessus dans le fichier config-gamebuino.h. et hop plus rien

Codnpix

4 years ago

Message deleted

Codnpix

NEW 4 years ago

LYSANDRE LYSANDRE

Message deleted

Steph

NEW 4 years ago

Voilà une solution à ta problématique ;-)

https://gist.github.com/iw4rr10r/072cf9fa0e8e243cef556b4bfca0f013

Codnpix

NEW 4 years ago

Bon si besoin je te propose aussi cette solution qui fonctionne  cette fois:

#include <Gamebuino-Meta.h>
uint8_t mode = 5;
int8_t music = -1;
bool isPlaying = false;
void setup()
{
  // initialize the Gamebuino object
  gb.begin();
  gb.sound.playOK();

}

void loop()
{
  gb.waitForUpdate();
  gb.display.clear();
  handleInputs();

  switch (mode)
  {
    case 0:
      if (!isPlaying) play();
      break;
    case 1:
      break;
    case 5:
      if (isPlaying) stop();
      break;
  }

  if (isPlaying)
  {
    gb.display.print("JOUE la musique");
  } else {
    gb.display.print("STOP la musique");
  }
}

void play()
{
  music = gb.sound.play("test.wav", true);
  isPlaying = true;
}
void stop()
{
  gb.sound.stop(music);
  isPlaying = false;
}

void handleInputs()
{
    if (gb.buttons.pressed(BUTTON_A))
    {
      mode = 0;
      gb.sound.playTick();
    }
    if (gb.buttons.pressed(BUTTON_B))
    {
      mode = 5;
      gb.sound.playTick();
    }
}

Donc en gros l'idée c'est que tu ne peux pas appeler gb.sound.play directement dans la boucle, sinon ça va jouer juste la fraction de seconde de la frame, puis la track redeviendra -1. Donc il faut sortir sound.play dans une fonction et la lancer selon un booléen vrai ou faux qu'il faut contrôler pour ne pas relancer la lecture si c'est déjà en lecture, etc...

LYSANDRE

NEW 4 years ago

merci à vous 2 problème résolu.

j'ai du mal à comprendre pourquoi il faut un booleen. Si on utilise gb.sound.stop(music), il devrait arrêter le son.

est-ce que gb.sound.play(music) se lance plusieurs fois ?

Steph

4 years ago

Dans ton code initial, l'instruction de lecture du son est répétée à chaque passage dans la boucle loop() quand Mode=5... donc oui !

Le code que je t'ai posté sur Gist est la bonne manière de procéder en définissant une machine à états, dont le comportement varie justement en fonction de son état (représenté par la propriété mode).

Codnpix

4 years ago

D'ailleurs c'est le cas pour cette histoire de son mais aussi pour tout le reste. En général à chaque fois que tu veux déclencher un truc une seule fois à un moment précis depuis une boucle infinie (la fonction loop() en l'occurence), tu as toujours besoin d'enregistrer un état quelque part en dehors de la boucle pour pouvoir poser une condition sur le déclenchement du truc en question et éviter de le déclencher en rafale à chaque tour de boucle.

Steph

NEW 4 years ago

LYSANDRE LYSANDRE

Dans ton code initial, l'instruction de lecture du son est répétée à chaque passage dans la boucle loop() quand Mode=5... donc oui !

Le code que je t'ai posté sur Gist est la bonne manière de procéder en définissant une machine à états, dont le comportement varie justement en fonction de son état (représenté par la propriété mode).

Codnpix

NEW 4 years ago

LYSANDRE LYSANDRE

D'ailleurs c'est le cas pour cette histoire de son mais aussi pour tout le reste. En général à chaque fois que tu veux déclencher un truc une seule fois à un moment précis depuis une boucle infinie (la fonction loop() en l'occurence), tu as toujours besoin d'enregistrer un état quelque part en dehors de la boucle pour pouvoir poser une condition sur le déclenchement du truc en question et éviter de le déclencher en rafale à chaque tour de boucle.