IBNIZ
IBNIZ est un petit logiciel qui permet générer de l'image et du son en utilisant un langage de programmation dont les commandes se limitent à un seul caractère.
L'esthétique, autant sonore que visuel, est celle du 8bit.
Sommaire
Installation
Sous Ubuntu 14.04
Par les dépôts
sudo apt-get install ibniz
En le compilant
Installer le paquet libsdl2-dev
sudo apt-get install libsdl2-dev
Télécharger les sources ici (Attention, archive TGZ pas à jour !). La dernière version est disponible sur Github à cette adresse. Taper make dans le dossier issu de la décompression de l'archive. Taper ensuite "./ibniz" pour lancer Ibniz.
Sous Raspberry
IBNIZ is now in debian repository (thks maxigas !) :
sudo apt-get install ibniz
Kano
raspbian customisé par os Kano http://www.kano.me/
sudo apt-get install make
sudo apt-get install gcc
sudo apt-get install libsdl1.2-dev
Sous Mac OSX
Installation de Xcode
Télécharger Xcode, à partir du apple store de votre ordinateur (menu pomme en haut à gauche app store)
Installation de Macport
http://www.macports.org/install.php
Choisissez et téléchargez l'installeur qui convient en fonction de votre version puis double click.
Installation de la librairie SDL
https://www.libsdl.org/download-1.2.php
Choisissez la version qui convient et copier le dossier dans /Library/Frameworks
Télécharger Ibniz
Téléchargez le code source sur la page
extraire l'archive (dezipper) ou bon vous semble
Compilation
ouvrir un terminal (utilities)
$cd et glisser votre dossier Ibniz à la suite...
ici
$cd /Users/VOUS/Desktop/ibniz-1.18
puis
$make
vous obtiendrez:
gcc -c -Os ui_sdl.c -o ui_sdl.o `sdl-config --libs --cflags` -DX11 -lX11
i686-apple-darwin10-gcc-4.2.1: -lSDLmain: linker input file unused because linking not done
i686-apple-darwin10-gcc-4.2.1: -framework: linker input file unused because linking not done
i686-apple-darwin10-gcc-4.2.1: AppKit: linker input file unused because linking not done
i686-apple-darwin10-gcc-4.2.1: -lSDL: linker input file unused because linking not done
i686-apple-darwin10-gcc-4.2.1: -framework: linker input file unused because linking not done
i686-apple-darwin10-gcc-4.2.1: Cocoa: linker input file unused because linking not done
i686-apple-darwin10-gcc-4.2.1: -lX11: linker input file unused because linking not done
gcc -c -O3 vm_slow.c -o vm_slow.o
gcc -c -Os clipboard.c -o clipboard.o `sdl-config --libs --cflags` -DX11 -lX11
i686-apple-darwin10-gcc-4.2.1: -lSDLmain: linker input file unused because linking not done
i686-apple-darwin10-gcc-4.2.1: -framework: linker input file unused because linking not done
i686-apple-darwin10-gcc-4.2.1: AppKit: linker input file unused because linking not done
i686-apple-darwin10-gcc-4.2.1: -lSDL: linker input file unused because linking not done
i686-apple-darwin10-gcc-4.2.1: -framework: linker input file unused because linking not done
i686-apple-darwin10-gcc-4.2.1: Cocoa: linker input file unused because linking not done
i686-apple-darwin10-gcc-4.2.1: -lX11: linker input file unused because linking not done
gcc -Os -s ui_sdl.o vm_slow.o clipboard.o -o ibniz `sdl-config --libs --cflags` -DX11 -lX11 -lm
ld: warning: option -s is obsolete and being ignored''
si vous obtenez l'erreur suivante :
gcc -c -Os ui_sdl.c -o ui_sdl.o `sdl-config --libs --cflags` -DX11 -lX11 /bin/sh: sdl-config: command not found ui_sdl.c:2:17: error: SDL.h: No such file or directory make: *** [ui_sdl.o] Error 1
essayez d'installer sdl depuis macport :
port install libsdl
lancement du logiciel
Aller dans votre dossier ibniz et cliquez sur le fichier programme qui vient d'être créer
Ibniz s'ouvre --- appuyer sur F1 (fn+f1) pour entendre du son --
Voila pour le mac
IBNIZ pour Android
Un portage de Ibniz par ce très cher Cedriko <3 en version beta à télécharger là : https://wiki.labomedia.org/images/3/32/IBNIZ_Android.zip
IBNIZ pour iOS
Par ici : http://bzztbomb.com/blog/2016/05/15/iosbniz/
Enregistrement / Lecture d'un set
Enregistrement
La commande suivante va lancer IBNIZ puis enregistrer tout ce qui sera taper au clavier en conservant très précisément le délais qui séparera chaque commande. Il est ainsi possible d’enregistrer un live de plusieurs heures.
./ibniz -e > MonSet
Lecture
Pour le rejouer, il faut utiliser la commande suivante :
./ibniz -p < MonSet
Expérimentation
Modification de la font
Pour changer l'aspect des caractères entrés au clavier, il suffit de modifier le fichier font.pl avant de compiler.
Les caractères sont codés sur une matrice carrée de 8x8. Ainsi, A et B donnent.
.#####..
##...##.
#######.
##...##.
##...##.
##...##.
........
........
######..
.##..##.
.#####..
.##..##.
.##..##.
######..
........
........
En modifiant la place des # il est facilement possible de se créer une font personnalisée.
Voici un essai avec des caractères qui bouclent entre eux. Fichier:Font.pd (à renommer en font.pl)
Construction d'un set avec un script Python
La structure d'un fichier d'enregistrement est déterminée par les lignes de codes suivantes :
int sym=e.key.keysym.sym;
int mod=e.key.keysym.mod;
if(ui.opt_dumpkeys)
{
static int last=0;
int now=getticks();
if(!sym && e.key.keysym.unicode)
sym=e.key.keysym.unicode;
printf("%d %d %d %d\n",now-last,sym,
e.key.keysym.unicode,mod);
last=now;
}
getticks() | e.key.keysym.sym | e.key.keysym.unicode | e.key.keysym.mod
Nombre de milliseconde écoulée | code ASCII de la touche | code ASCII de la touche | mode
Utiles :
- backspace : 8 8 *
- ctrl+A : 97 1 4160
- Suppr : 97 1 4160
- Gauche : 276 0 4096
- Droite : 275 0 4096
- Haut : 273 0 4160
- F1 : 282 0 4096
- F2 : 283 0 4096
- Escape : 27 27 4096
Example :
# -*- coding: utf8 -*-
#
# Ce script permet de générer un fichier "events" qui contient une liste
# d'évènements qu'IBNIZ est capable d'interpréter succéssivement avec la
# commande -p < events
#
# En l'occurence, il soumet à IBNIZ 5 caractères pris aléatoirement dans la
# liste des caractères qui ont une fonction. Puis il les efface. Et ce n fois.
from random import randint
# Liste complète des caractères utiles
liste= '''+-*/%q&|^rl~sa><=1234567890ABCDEFdpxv()MWT@!?:;XLij[]J{}VRPUG$bqoh'''
# Temps qui sépare chaque instrucion, en milliseconde
tps = 50
# Nombre de fois que sera exécutée la boucle
nb_passe = 100
# Nombre de caractère écrits à chaque boucle
nb_caract = 5
# Touches ou combinaisons spéciales
F1 = "{0} 282 0 4096\n".format(tps)
F2 = "{0} 283 0 4096\n".format(tps)
backSpace = "{0} 8 8 4096\n".format(tps)
supprAll = "{0} 97 1 4160\n{0} 127 127 4096\n".format(tps)
Esc = "{0} 27 27 4096\n".format(tps)
# Crée une page vide
pattern =""
# Démmarre le traitement
pattern += F1
for i in range(nb_passe):
# Fait écrire les caractères un par un
for k in range(nb_caract):
# Choisi un nombre entre 0 et le nb d'élément de la liste
choix = randint(0, len(liste)-1)
# Récupère le caractère correspondant dans la liste
caract = liste[choix]
# Récupère la valeur ASCII de ce caractère
ascii_caract = ord(caract)
# Compose l'évènement corresponant
pattern += "{0} {1} {1} 4096\n".format(tps, ascii_caract)
# Fait effacer les caractères un par un
for k in range(nb_caract):
pattern += backSpace
# Relance le traitemant audio et vidéo
pattern += F2
# Écrit la liste d'évènement dans un fichier
with open ("events", 'w') as base:
base.write(pattern)
Le script ci-dessous permet de produire un fichier events qui, ouvert avec la commande -p < events produira des lignes aléatoires dans le but de générer une trame à partir de la nouvelle font obtenue plus haut.
from random import randint
pattern = ""
tps = "0"
for k in range(500):
a = randint(97, 122)
b = randint(97, 122)
for i in range(15):
pattern += "{0} {1} {1} 4096\n".format(tps, a)
pattern += "{0} {1} {1} 4096\n".format(tps, b)
pattern += "{0} {1} {1} 4096\n".format(tps, a)
pattern += "{0} {1} {1} 4096\n".format("300", b)
with open ("events", 'w') as base:
base.write(pattern)
Alimenter IBNIZ de l'extérieur
Piste : python-xlib permet de simuler l'appuie de touche au clavier.
Autres versions
Info : https://github.com/twinshadow/IBNIZ/tree/project-restructure
Github network : https://github.com/twinshadow/IBNIZ/network
Compilation (il manque le fichier language.h dans le dernier commit, c'est pour ça qu'il faut revenir à un commit de février dernier) :
- git clone https://github.com/twinshadow/IBNIZ.git
- cd IBNIZ
- git checkout project-restructure
- git checkout e8be5df317e9e13f0973bdd725269dc11e2d052a
- make
- ./src/ibniz
INFO : ./ibniz -e > events
./ibniz -M -p < events 2>vid.pcm | ffmpeg -y -i - -r 30 vid.avi
ffmpeg -i vid.avi -f s16le -ar 44100 -ac 1 \ -i vid.pcm -vcodec copy vidav.avi
Principe de fonctionnement
Notes : Les informations ci-dessous sont issues de ce que j'ai compris d'IBNIZ, certaines informations sont peut-être plus ou moins exactes, voire complètement fausses :) Des notions d'assembleur sont recommandées pour comprendre la suite ...
La machine et la pile
IBNIZ reproduit un ordinateur virtuel minimaliste qu'on programme en assembleur IBNIZ.
IBNIZ fournit un jeu d'instructions assembleur (bas niveau) très complet qui en fait un vrai langage de programmation, il passe d'ailleurs avec succès le test de Turin.
On retrouve les instructions habituelles pour programmer en assembleur tel que poser une valeur sur la pile, l'enlever, faire des opérations mathématiques, faire des boucles, des tests, définir des sous-programmes, etc.
IBNIZ utilise une pile LIFO : Last In, First Out, et pose à chaque cycle des valeurs sur la pile, qui changent selon le mode (voir plus bas).
Les commandes que l'on tape modifient ces valeurs, et IBNIZ utilise ces nouvelles valeurs pour produire de l'image et du son.
Exemple, la fameuse texture du XOR : ^xp
1 - IBNIZ pose sur la pile 3 valeurs : X, Y, T (T est au bas de la pile et X en haut. X a été la dernière valeur posée sur la pile, cela sera donc la première valeur enlevée de la pile). IBNIZ balaye l'écran (je ne sais pas encore dans quel sens), X correspond à la valeur de la coordonnées de l'abscisse x, et Y à l'ordonnée y. T est le compteur de frames (de cycles)
2 - Le chapeau ^ effectue l'opération binaire XOR entre X (première valeur de la pile) et Y (deuxième valeur). La pile contient donc en haut de la pile le résultat de X^Y, et T en seconde position
3 - La lettre x inverse les deux valeurs de la pile : T passe en première position en haut de la pile, suivi de X^Y en seconde position
4 - La lettre p (pop) enlève une valeur de la pile, il reste donc sur la pile le résultat de X^Y, et IBNIZ se sert de cette valeur pour faire la video et le son.
Un nouveau cycle recommence, IBINIZ repars à l'étape 1 et copie sur la pile les nouvelles valeurs de X, Y et T
Les différents modes de fonctionnement
IBNIZ dispose de 3 modes de fonctionnement :
Vidéo en mode TYX : IBNIZ pose sur la pile TTTT.0000, YYYY.YYYY et XXXX.XXXX
YYYY.YYYY et XXXX.XXXX sont des valeurs entre -1 et 1, TTTT est le compteur de frames (le temps en soixantième de secondes)
Vidéo en mode T : IBNIZ pose sur la pile TTTT.YYXX
YY et XX varient entre 00 et FF (soit entre 0 et 255), TTTT est le compteur de frames
Audio en mode T : IBNIZ pose sur la pile TTTT.TTTT
La partie entière est le compteur de frames comme dans le mode vidéo, et la partie décimale est une fraction de 65536.
Attention, l'implémentation courante change le mode du contexte vidéo automatiquement selon la balance de stacks (à expliquer ...) et combien de fois on a appelé whereami (qui permet de reposer les valeurs sur la pile).
Le mode audio
TODO
Le mode vidéo
TODO
Ressources
- Le site officiel est ici.
- Les dernières sources de IBNIZ sont sur la page Github de viznut.
- Une source importante d'information est disponible sur Codelab.
- Une bonne page pour (commencer à) comprendre le fonctionnement de IBNIZ.
- Un doc PDF écrit par Viznut sur la génération mathématique de son.
- Une version réseau de Ibniz : nIBNIZ.
- Une version de Ibniz qui permet d'indiquer la position, la taille et la décoration de la fenêtre.
- Une interface graphique qui permet de gérer différents sets IBNIZ et de lancer plusieurs IBNIZ à des positions et avec des tailles et à des positions différentes : Pybniz.