Outils pour utilisateurs

Outils du site


clapping_music_for_robots

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
clapping_music_for_robots [2022/03/14 09:50] Simon Deplatclapping_music_for_robots [2022/03/14 11:15] (Version actuelle) Simon Deplat
Ligne 69: Ligne 69:
 **Ce qui est tout-à-fait vrai, et même pertinent en terme algorithmique.** Cela pose un problème de dépassement car le décalage demandera à un moment d'accéder à un index supérieur à la taille de l'//Array//, mais ce problème se règle assez facilement (nous le verrons par la suite). **Ce qui est tout-à-fait vrai, et même pertinent en terme algorithmique.** Cela pose un problème de dépassement car le décalage demandera à un moment d'accéder à un index supérieur à la taille de l'//Array//, mais ce problème se règle assez facilement (nous le verrons par la suite).
  
-Cependant, je lui ai conseillé dans un premier temps de **reconstruire la seconde voix de manière algorithmique dans un premier temps pour que l'//Array// de la seconde voix corresponde effectivement à la partition réellement jouée**.+Cependant, je lui ai conseillé dans un premier temps de **reconstruire la seconde voix de manière algorithmique pour que l'//Array// de la seconde voix corresponde effectivement à chaque instant à la partition réellement jouée par cette voix**.
  
 =====Représentation===== =====Représentation=====
-Cette orientation était avant tout didactique : je pense qu'il est mieux d'apprendre à résoudre concrètement un problème équivalent à sa représentation conceptuelle avant d'ajouter un hack.+Cette orientation était avant tout didactique : je pense qu'il est mieux d'**apprendre en premier lieu à résoudre concrètement un problème équivalent à sa représentation conceptuelle**, avant d'ajouter un hack.
  
-Dans notre cas, la première solution pour résoudre le problème est la suivante :+Je laisse ici de côté la solution de reconstruction de la bonne partition à chaque changement pour me concentrer sur **les solutions alternativesqui nous éloignent de la manière dont on conçoit la partition habituellement**. 
 + 
 +La première solution pour résoudre le problème est la suivante :
  
 Nous commençons par dupliquer notre partition : Nous commençons par dupliquer notre partition :
 +
 +{{ ::2barsreich.png?600 |}}
 +
 +Si vous y réfléchissez, la dernière note est d'ailleurs superflue.
 +
 +Maintenant, voici comme est décrite notre partition en terme algorithmique :
 +
 +{{ ::reichoffset.png?600 |}}
 +
 +À chaque fin de cycles, on augmente le décalage de la seconde voix, et on le remet à zéro s'il atteint le nombre de temps de la clave initiale.
 +
 +Ce qui semble étrange, c'est que **cette méthode introduit une asymétrie de représentation des deux voix**. Une information supplémentaire est nécessaire pour situer la voix II : son décalage par rapport à l'origine.
 +
 +Ce n'est pas le cas avec la représentation "reconstruite" :
 +
 +{{ ::reichisomorph.png?600 |}}
 +
 +**Les deux font pourtant référence au même objet.** La première solution est efficiente en terme de calcul. La seconde est plus facile à comprendre pour les humains.
 +
 +Voici le code associé à cet algorithme, qui, à la place de servomoteurs, fait clignoter des LEDs :
 +
 +<code>
 +int ledPin1 = 2;
 +int ledPin2 = 3;
 +
 +int msBetweenBeats = 200;
 +
 +int initialScore[] = { 1, 0, 0, 1, 0, 0, 1, 0 };
 +int score[16];
 +
 +int currentBeat = 0;
 +
 +int numberOfBeats;
 +
 +int currentCycleRepetition = 0;
 +int numberOfCycleRepetitions = 4;
 +int currentCycle = 0;
 +
 +void setup() {
 +  Serial.begin(9600);
 +  
 +  pinMode( ledPin1, OUTPUT );
 +  pinMode( ledPin2, OUTPUT );
 +
 +  numberOfBeats = sizeof( initialScore ) / sizeof( initialScore[0] );
 +
 +  for( int i = 0; i < ( numberOfBeats * 2 ); i++ ) {
 +    score[ i ] = initialScore[ i%numberOfBeats ];
 +  };
 +
 +}
 +
 +void loop() {
 +
 +  Serial.println( score[ currentBeat + currentCycle ] );
 +
 +  if( score[ currentBeat ] == 1 ) {
 +    digitalWrite( ledPin1, HIGH );
 +  };
 +
 +  if( score[ currentBeat + currentCycle ] == 1 ) {
 +    digitalWrite( ledPin2, HIGH );
 +  };
 +
 +  delay( msBetweenBeats / 4 * 3 );
 +
 +  digitalWrite( ledPin1, LOW );
 +  digitalWrite( ledPin2, LOW );
 +
 +  delay( msBetweenBeats / 4 );
 +
 +  currentBeat = currentBeat + 1;
 +  
 +  if( currentBeat == numberOfBeats ) {
 +    
 +    currentBeat = 0;
 +    currentCycleRepetition = currentCycleRepetition + 1;
 +    
 +    if( currentCycleRepetition == numberOfCycleRepetitions ) {
 +        currentCycleRepetition = 0;
 +        currentCycle = currentCycle + 1;
 +        
 +        if( currentCycle == numberOfBeats ) {
 +          currentCycle = 0;
 +        };
 +      };
 +    };
 +}
 +</code>
 +
 +=====Physiologie ?=====
 +Pour aller encore plus loin, il faut noter que **le duplicata de l'//Array// n'est même pas nécessaire**.
 +
 +Avec cet algorithme, **il n'est même plus possible de représenter adéquatement la "partition" de la deuxième voix  à l'aide d'un dessin**, puisqu'elle est dépendante de l'utilisation du modulo (%) qui est une opération logique effectuée sur des électrons :
 +
 +<code>
 +noteAcutelleDeLaDeuxièmeVoix = score[ ( currentBeat + currentCycle ) % numberOfBeats ];
 +</code>
 +
 +Encore une fois pourtant, l'effet réel est le bon et les LEDs jouent en rythme.
 +
 +Cela nous questionne sur **la définition de la partition**. 
 +
 +**Doit-elle être considérée comme un système de symbole purement informatifs, ou comme un //objet// agissant sur le musicien de telle sorte à le faire jouer correctement ?**
 +
 +**La version "reconstruite" à l'aide de deux //Arrays// semble pencher du première côté**, étant très descriptive, même si l'inspection du contenu des //Arrays// agit effectivement sur les LEDs. Cela n'est cependant pas immédiat : la partition est d'abord "écrite", puis "lue" //a posteriori// pour déclencher le clignotement.
 +
 +À l'inverse, **dans le cas de la version "modulo" de l'algorithme, nous sommes beaucoup plus proche de la seconde hypothèse.** Ici, l'algorithme ressemble plus à une description de la manière dont le corps doit se comporter pour jouer la partition. La partition est en quelque sorte "cachée" dans l'algorithme, et bien qu'elle puisse être déduite de l'algorithme, elle n'est pas accessible de manière immédiate. Par ailleurs, contrairement au premier exemple, il n'y a aucune information donnée //a priori//, et l'Arduino a sa propre méthode pour savoir trouver la note qu'il doit jouer au moment même où il doit la jouer.
 +
 +<code>
 +int ledPin1 = 2;
 +int ledPin2 = 3;
 +
 +int msBetweenBeats = 200;
 +
 +int score[] = { 1, 0, 0, 1, 0, 0, 1, 0 };
 +
 +int currentBeat = 0;
 +
 +int numberOfBeats;
 +
 +int currentCycleRepetition = 0;
 +int numberOfCycleRepetitions = 4;
 +int currentCycle = 0;
 +
 +void setup() {
 +  Serial.begin(9600);
 +  
 +  pinMode( ledPin1, OUTPUT );
 +  pinMode( ledPin2, OUTPUT );
 +
 +  numberOfBeats = sizeof( score ) / sizeof( score[0] );
 +
 +}
 +
 +void loop() {
 +
 +  Serial.println( score[ currentBeat + currentCycle ] );
 +
 +  if( score[ currentBeat ] == 1 ) {
 +    digitalWrite( ledPin1, HIGH );
 +  };
 +
 +  if( score[ ( currentBeat + currentCycle ) % numberOfBeats ] == 1 ) {
 +    digitalWrite( ledPin2, HIGH );
 +  };
 +
 +  delay( msBetweenBeats / 4 * 3 );
 +
 +  digitalWrite( ledPin1, LOW );
 +  digitalWrite( ledPin2, LOW );
 +
 +  delay( msBetweenBeats / 4 );
 +
 +  currentBeat = currentBeat + 1;
 +  
 +  if( currentBeat == numberOfBeats ) {
 +    
 +    currentBeat = 0;
 +    currentCycleRepetition = currentCycleRepetition + 1;
 +    
 +    if( currentCycleRepetition == numberOfCycleRepetitions ) {
 +        currentCycleRepetition = 0;
 +        currentCycle = currentCycle + 1;
 +        
 +        if( currentCycle == numberOfBeats ) {
 +          currentCycle = 0;
 +        };
 +      };
 +    };
 +}
 +</code>
clapping_music_for_robots.1647251415.txt.gz · Dernière modification : 2022/03/14 09:50 de Simon Deplat