bytebeat

Bonjour à tous.

J'écris cet article pour informer ceux qui n'auraient pas eu la chance de découvrir le bytebeat, une technique musicale permettant de générer de la musique à partir de fonctions simples (en C par exemple).

première vidéo de présentation
le forum où tout semble avoir commencé
un générateur en ligne
un article sur l'outil
une analyse plus poussée
des liens vers de la documentation sur les domaines apparentés (IBNIZ, forth, libglitch, etc)

Cette technique est difficile à expliquer pour le novice que je suis, mais je peux relativement cerner la chose ainsi : il est possible de générer de la musique à partir d'une ligne de code et d'un peu d'imagination.

L'explication de VIznut, l'inventeur :

I chose to replicate the essentials of my earlier 8-bit experiments:
a wave generator whose pitch is controlled by a function consisting of shifts and logical operators.
The simplest waveform for /dev/dsp programs is sawtooth.
A simple for(;;)putchar(t++) generates a sawtooth wave with a cycle length of 256 bytes,
resulting in a frequency of 31.25 Hz when using the the default sample rate of 8000 Hz.
The pitch can be changed with multiplication. t++*2 is an octave higher,
t++*3 goes up by 7 semitones from there, t++*(t>>8) produces a rising sound.
After a couple of trials, I came up with something that I wanted to share on an IRC channel:

main(t){for(t=0;;t++)putchar(t*(((t>>12)|(t>>8))&(63&(t>>4))));}

L'intérêt supplémentaire est qu'il existe quelques adaptations pour l'arduino, qu'il suffit alors de connecter à un piezo ou carrément un gros baffle pour écouter les différentes mélodies.

Voici le code que j'utilise actuellement, généreusement partagé par Kragen Javier Sitaker (ici sa page sur le bytebeat) :

// Based on http://arduino.cc/en/Tutorial/Fading by David A. Mellis
// and Tom Igoe, http://www.arduino.cc/playground/Code/PwmFrequency,
// and viznut's, skurk's, and raer's discoveries documented in
// http://countercomplex.blogspot.com/2011/10/algorithmic-symphonies-from-one-line-of.html

int speakerPin = 9; // Speaker connected to digital pin 9

void setup() {
// use 0x01 for divisor of 1, i.e. 31.25kHz
// or 0x02 for divisor of 8, or 0x03 for divisor of 64 (default)
TCCR1B = TCCR1B & 0xf8 | 0x01;
}

int t = 0;
int i = 0;

void loop() {
if (++i != 64) return;
i = 0;
t++;
analogWrite(speakerPin, /*votre symphonie entre là -->*/  (t*(t>>5|t>>8))>>(t>>16))  /*<-- et là */  );
}

Les décalages de bit à bit me sont assez obscurs mais je ne doute pas qu'un amateur de ce genre d'opérations appréciera la profondeur de l'outil inventé. En attendant un bon tutoriel sur les variations de base, l'expérimentation offre ici de bons résultats également.

salut Saegor, c'est super intéressant, je connaissais le ByteBeat, mais je n'avais pas songé que ça pouvait s'adapter en Arduino (évidemment).

Juste une petite précision, dans ton code la formule indique :

(t*(t>>5|t>>8))>>(t>>16))

mais il y a une parenthèse en trop.

La bonne formule : (t*(t>>5|t>>8))>>(t>>16)

"La bonne formule : (t*(t>>5|t>>8))>>(t>>16)"
Sans lunettes ni drôle de truc qui se fout de vous (il paraît que c'est dans le dictionnaire: o tempora, o mores):
La bonne formule : (t * (t >> 5 | t >> 8 ) )>> (t >> 16 )

La formule serait bonne si elle était placée entre balises code

ou si on met des blancs -espaces- avant les parenthèses fermantes