Switch/case sur plusieurs séries de valeurs

Switch/case sur plusieurs séries de valeurs - C++ - Programmation

Marsh Posté le 03-01-2025 à 15:13:36    

Bonjour à tous  :hello:  
 
Je colle sur un petit problème et j'aimerais trouver une solution élégante.
Pour le contexte le code va tourner sur un µC Atmega Série1 et j'essaye d'optimiser un poil le tout mais je ne suis pas un grand programmeur  :whistle:  
 
je dois discriminer des notes en MIDI et faire un switch/case.
Les notes sont disponibles sous forme d'entier dans une variable entre 1 et 127, parmi ces notes je dois faire un case pour tous les LA : 21, 33, 45, 57, 69 etc... Tous les LA correspondent à un interval de 12 en commençant par 21.
Ensuite tous les SI ont un interval de 12 mais commençant par 23 (23, 35, 47 etc...), et c'est ainsi de suite pour toutes les notes.
 
La méthode bourrine que j'envisage c'est de tester toutes les valeurs avec un OR dans mon case pour chacune des notes.
Mais je me dit qu'il doit y avoir un moyen de tester la variable et d'en ressortir si c'est un LA peut importe lequel.
 
Vous voyez une bonne méthode pour faire ce test ? En ayant en tête que l'idée c'est que ce soit plus rapide à executer qu'un case blindé d'opérateurs OR.
 
Merci pour votre aide :jap:


---------------
--== M4vr|ck ==--
Reply

Marsh Posté le 03-01-2025 à 15:13:36   

Reply

Marsh Posté le 03-01-2025 à 15:29:17    

J'ai pas bien compris et je ne suis pas un rongeur musical, mais perso je dirais tente un truc genre

 
Code :
  1. if(note-21)%12==0) -> LA
  2. else if(note-23)%12==0) -> SI
  3. ...
 

EDIT: Sinon file un bout de code...


Message édité par rat de combat le 03-01-2025 à 15:29:48

---------------
Ne laissez pas mourir vos sujets en cours de route!
Reply

Marsh Posté le 03-01-2025 à 15:36:52    

C'est pas bete comme solution, ca pourrait convenir.
 
Actuellement c'est du bourrin comme j'ai dit :
 

Code :
  1. switch (inNote) {
  2.     case (21||33||45||57||69||81||93||105||117):
  3.       break;
  4.     case (23||35||47||59||71||83||95||107||119):
  5.       break;
  6.   } //end switch


 


---------------
--== M4vr|ck ==--
Reply

Marsh Posté le 03-01-2025 à 15:40:00    

A moins que ce soit spécifique au C++ ton code ne devrait pas fonctionner ou même compiler?
 
A mon avis - en C et si tu restes sur le switch - il faudrait faire genre
 

Code :
  1. case 21:
  2. case 33:
  3. case 45:
  4. <code>
  5. break;
  6. case 23:
  7. case 35:
  8. <code>
  9. break;


---------------
Ne laissez pas mourir vos sujets en cours de route!
Reply

Marsh Posté le 03-01-2025 à 15:43:20    

l'IDE Arduino le compile sans erreurs :o


---------------
--== M4vr|ck ==--
Reply

Marsh Posté le 03-01-2025 à 15:47:09    

et ça fonctionne aussi? :o Les warnings sont activés dans l'IDE?
 
Car à mon avis (21||33||....) == true simplement? :??:


---------------
Ne laissez pas mourir vos sujets en cours de route!
Reply

Marsh Posté le 03-01-2025 à 15:50:34    

Non, tu as raison ca ne fonctionne pas  :whistle:  
 
Donc soit je garde les case en série comme tu le suggères, soit un if else.
 
Merci du coup de main :jap:
 
Si quelqu'un voit une autre solution je prends aussi.


---------------
--== M4vr|ck ==--
Reply

Marsh Posté le 03-01-2025 à 15:55:31    

Il y a d'autres solutions, p.ex. un tableau de pointeur de fonctions / labels (-> assembleur :cry: ), un tableau et une boucle, ...
 
Il faut voir à quel point tu es limité par la puissance de calcul / le temps d'exécution. Si c'est pas un soucis prend une solution que tu comprend et qui est lisible (pour toi). Il ne faut jamais optimiser trop tôt.
 
Tu peux aussi vérifier que tu compiles bien avec -O3 (pour GCC), autrement dit "optimiser aggressivement pour la meilleure vitesse d'exécution au détriment de la taille du firmware". Le "contraire" serait "-Os" pour "optimiser pour taille".


---------------
Ne laissez pas mourir vos sujets en cours de route!
Reply

Marsh Posté le 04-01-2025 à 05:50:29    

Je sais pas si le "modulo" pourrait être utile ; Mais j'en parle.


---------------
inconito.net IP : 82.64.250.137
Reply

Marsh Posté le 04-01-2025 à 09:29:44    

C'est la solution que m'a proposé le rat de combat, je pense la garder au final au lieu d'une liste de case.


---------------
--== M4vr|ck ==--
Reply

Marsh Posté le 04-01-2025 à 09:29:44   

Reply

Marsh Posté le 04-01-2025 à 15:27:53    

Bah moi le modulo m'a l'air fait exactement pour ce genre de choses :o


---------------
Topic .Net - C# @ Prog
Reply

Marsh Posté le 05-01-2025 à 13:36:24    

M4vrick a écrit :

C'est pas bete comme solution, ca pourrait convenir.
 
Actuellement c'est du bourrin comme j'ai dit :
 

Code :
  1. switch (inNote) {
  2.     case (21||33||45||57||69||81||93||105||117):
  3.       break;
  4.     case (23||35||47||59||71||83||95||107||119):
  5.       break;
  6.   } //end switch


 

Ce code est fondamentalement faux, tes deux case sont équivalents à case true. Pour tester chaque note, il faut en effet un case par note comme le propose rat de combat.
La solution du modulo est compacte et me semble bien moins source de bugs qu'une longue liste de case "valeur".


---------------
"Ce qui serait effrayant ce n'est pas qu'un IA passe le test de Turing, mais qu'elle y échoue volontairement."
Reply

Marsh Posté le 06-01-2025 à 11:17:09    

Je confirme que cela fonctionne très bien avec le modulo :jap:


---------------
--== M4vr|ck ==--
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed