clapping_music_for_robots
Différences
Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente | ||
clapping_music_for_robots [2022/03/14 09:36] – Simon Deplat | clapping_music_for_robots [2022/03/14 11:15] (Version actuelle) – Simon Deplat | ||
---|---|---|---|
Ligne 30: | Ligne 30: | ||
=====Partition à raie===== | =====Partition à raie===== | ||
- | Je lui ai donc pointé du doigt quelque chose de presque magique : il est possible de considérer une //Array// comme une partition. | + | Je lui ai donc pointé du doigt quelque chose de presque magique : **il est possible de considérer une //Array// comme une partition**. |
Si nous prenons l' | Si nous prenons l' | ||
Ligne 38: | Ligne 38: | ||
</ | </ | ||
- | On peut y voir une représentation d'une partition rythmique représentant la clave ||: Noire pointée - Noire pointée - Noire :|| si l'on itère régulièrement dessus, ne jouant une note que si l' | + | On peut y voir **une représentation d'une partition rythmique représentant la clave ||: Noire pointée - Noire pointée - Noire :||** si l'on itère régulièrement dessus, ne jouant une note que si l' |
- | On peut étendre ce principe plus loin, en modifiant le décodeur pour réagir au contenu de l'// | + | On peut étendre ce principe plus loin, en modifiant le //décodeur// pour réagir au contenu de l'// |
Un séquenceur probabiliste : | Un séquenceur probabiliste : | ||
Ligne 60: | Ligne 60: | ||
< | < | ||
[ 60, 67, 64, 67 ] | [ 60, 67, 64, 67 ] | ||
+ | </ | ||
+ | |||
+ | =====écalageD===== | ||
+ | Dans cette optique, j'ai indiqué à l' | ||
+ | |||
+ | Elle m'a rétorqué qu'en fait, **vu qu'on accède à l'// | ||
+ | |||
+ | **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' | ||
+ | |||
+ | Cependant, je lui ai conseillé dans un premier temps de **reconstruire la seconde voix de manière algorithmique pour que l'// | ||
+ | |||
+ | =====Représentation===== | ||
+ | Cette orientation était avant tout didactique : je pense qu'il est mieux d' | ||
+ | |||
+ | Je laisse ici de côté la solution de reconstruction de la bonne partition à chaque changement pour me concentrer sur **les solutions alternatives, | ||
+ | |||
+ | La première solution pour résoudre le problème est la suivante : | ||
+ | |||
+ | Nous commençons par dupliquer notre partition : | ||
+ | |||
+ | {{ :: | ||
+ | |||
+ | Si vous y réfléchissez, | ||
+ | |||
+ | Maintenant, voici comme est décrite notre partition en terme algorithmique : | ||
+ | |||
+ | {{ :: | ||
+ | |||
+ | À 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' | ||
+ | |||
+ | Ce n'est pas le cas avec la représentation " | ||
+ | |||
+ | {{ :: | ||
+ | |||
+ | **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, | ||
+ | |||
+ | < | ||
+ | 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; | ||
+ | }; | ||
+ | }; | ||
+ | }; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | =====Physiologie ?===== | ||
+ | Pour aller encore plus loin, il faut noter que **le duplicata de l'// | ||
+ | |||
+ | Avec cet algorithme, **il n'est même plus possible de représenter adéquatement la " | ||
+ | |||
+ | < | ||
+ | noteAcutelleDeLaDeuxièmeVoix = score[ ( currentBeat + currentCycle ) % numberOfBeats ]; | ||
+ | </ | ||
+ | |||
+ | Encore une fois pourtant, l' | ||
+ | |||
+ | Cela nous questionne sur **la définition de la partition**. | ||
+ | |||
+ | **Doit-elle être considérée comme un système de symbole purement informatifs, | ||
+ | |||
+ | **La version " | ||
+ | |||
+ | À l' | ||
+ | |||
+ | < | ||
+ | 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; | ||
+ | }; | ||
+ | }; | ||
+ | }; | ||
+ | } | ||
</ | </ |
clapping_music_for_robots.1647250571.txt.gz · Dernière modification : 2022/03/14 09:36 de Simon Deplat