Pianoptique
Sommaire
Présentation
Connue sous le nom de "Piano à roulette", "Wheeled piano" ou encore d'"Orgue Barbare", le Pianoptique est un dispositif qui permet de faire de la musique via l'analyse d'un flux vidéo.
Dernier fichier en date utilisant Puredata : File:orgue-barbare.zip
Il fonctionne comme un orgue de barbarie où la partition serait lue par une caméra.
Ci-dessous, un rouleau d'orgue de barbarie :
Puis, une interface MIDI qui reprend le même principe :
Enfin, l'interface de lecture du Pianoptique :
Quelques photos/vidéo ici.
Versions
Il existe trois versions différentes du Pianoptique :
Puredata
C'est la première version qui a été codée et celle qui, à ce jour, est présentée en exposition. La version initiale ne produit pas de son, mais envoie des instructions MIDI qui peuvent être interprétées par un synthé.
Un guide d'installation pour Linux est disponible en anglais sur cette page.
voici la version du 10/03/2011 :
Processing
La version Processing ne produit pas non plus de son mais envoie des messages OSC.
Elle se contente aussi de ne lire que les niveaux de gris.
// Piano à roulette pour Processing
// Copyright 2013 Olivier Baudu
// publié sous les termes de la license GPL v3.0
// peut donc être utilisé, copié, modifié et diffusé à loisir
import oscP5.*;
import netP5.*;
import processing.video.*;
import controlP5.*;
Capture cam;
int startMilieu, nbNote, nbPixels, seuil;
boolean [] noteOnOff;
OscP5 oscP5;
NetAddress pourPython;
ControlP5 cp5;
float contraste = 0.2;
void setup() {
//Slider
cp5 = new ControlP5(this);
cp5.addSlider("contraste")
.setPosition(20, 20)
.setColorBackground(0)
.setColorActive(color(255, 0, 0))
.setColorForeground(color(150, 150, 150))
.setColorCaptionLabel(color(150, 150, 150))
.showTickMarks(true)
.setRange(0, 1)
;
oscP5 = new OscP5(this, 12000);
pourPython = new NetAddress("127.0.0.1", 15000);
size(640, 480);
cam = new Capture(this, 640, 480);
cam.start();
startMilieu = width * (height/2);
nbNote = 20;
nbPixels = width/nbNote;
seuil = 40;
noteOnOff = new boolean[nbNote];
for (int i=0; i<nbNote; i++) {
noteOnOff[i] = false;
}
noStroke();
}
void draw() {
if (cam.available() == true) {
cam.read();
cam.filter(THRESHOLD, contraste);
image(cam, 0, 0);
for (int i=0; i<nbNote; i++) {
int somme = 0;
for (int j=0; j<nbPixels; j++) {
color c = cam.pixels[startMilieu + i*nbPixels + j];
somme += brightness(c);
}
int moyenne = somme/nbPixels;
fill(moyenne);
if (moyenne < seuil) {
boolean newValue = true;
if (newValue != noteOnOff[i]) {
noteOnOff[i] = newValue;
fill(255, 0, 0);
OscMessage myMessage = new OscMessage("/playMe");
myMessage.add(i);
oscP5.send(myMessage, pourPython);
}
}
else {
boolean newValue = false;
if (newValue != noteOnOff[i]) {
noteOnOff[i] = false;
}
}
rect(i*nbPixels, height/2, nbPixels, (moyenne-255)/1.5);
}
}
}
Un exemple de script Python qui écoute l'OSC craché par le sketch ci-dessus (mais qui ne produit pas de son):
#Gestion de l'OSC
from twisted.internet import reactor
from txosc import osc
from txosc import dispatch
from txosc import async
def piano_handler(message, address):
print("Je joue la note "+ str(message.getValues()[0]))
class UDPReceiverApplication(object):
"""
Example that receives UDP OSC messages.
"""
def __init__(self, port):
self.port = port
self.receiver = dispatch.Receiver()
self._server_port = reactor.listenUDP(self.port, async.DatagramServerProtocol(self.receiver))
print("Listening on osc.udp://localhost:%s" % (self.port))
self.receiver.addCallback("/playMe", piano_handler)
if __name__ == "__main__":
#initialisation ()
app = UDPReceiverApplication(15000)
reactor.run()
Python + OpenCV
Cette version a été écrite pour pouvoir être utilisée sur une Raspberry Pi. En effet, GEM (lib vidéo de Puredata) ne tourne pas avec l'OpenGL ES et les problèmes liés à la vidéo sur Processing + RasPi ne sont pas encore résolus. Nous avons donc porté le scketch Processing en Python en nous appuyant sur OpenCV pour faire l'acquisition vidéo.
Pour installer OpenCV :
sudo apt-get install python-opencv
Vous trouverez des explications ici sur comment nous nous y sommes pris pour exploiter OpenCV pour nos besoins.
import cv2
# setup video capture
cap = cv2.VideoCapture(0)
ret,im = cap.read()
height,width = im.shape[:2]
milieu = height/2
seuil = 40
nbNote = 8
nbPixels = width/nbNote
noteOnOff = []
for i in range(nbNote):
noteOnOff.append(False)
while True:
ret,im = cap.read()
gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
for i in range(nbNote):
somme = 0
# calcul de la moyenne de niveau de gris
for j in range(nbPixels):
somme += gray[milieu][i*nbPixels + j]
moyenne = somme/nbPixels
# test du seuil
if (moyenne < seuil):
newValue = True
if (newValue != noteOnOff[i]):
noteOnOff[i] = newValue
print ("Je dois jouer la note " + str(i))
else:
newValue = False
if (newValue != noteOnOff[i]):
noteOnOff[i] = newValue
# dessin des graduations
for j in range(nbPixels):
for k in range(4):
gray[milieu+k][i*nbPixels + j] = moyenne
cv2.imshow('video test',gray)
key = cv2.waitKey(10)
Configuration de la Raspberry Pi
L'idée ici est de faire jouer les notes de musiques par des servomoteurs sur un carillon.
Nous passons pour cela par les cartes PCA9685 - 16-Channel de chez Adafruit. Le protocole utilisé étant l'I2C, il est nécessaire d'installer le paquet python-smbus
sudo apt-get install python-smbus
Sur une Raspian, il est nécessaire d'effectuer ces manips supplémentaire pour pouvoir utiliser l'I2C avec les cartes d'Adafruit:
- commenter la ligne blacklist i2c-bcm2708 du fichier raspi-blacklist.conf (placer un # devant)
sudo nano /etc/modprobe.d/raspi-blacklist.conf
- ajouter deux lignes supplémentaires au fichier modules :
sudo nano /etc/modules
i2c-dev i2c-bcm2708
Relier la Raspberry à la carte Adafruit comme sur la photo ci-dessous. (à noter que l'ordre est inversement-conservé et qu'il est donc possible d'utiliser une nappe standard).
Mécanique à manivelle
- But du jeu : Faire tourner le plateau avec une manivelle
Transmission
- Manivelle -> Roue
- Roue -> Plateau
sources :
https://fr.wikipedia.org/wiki/Joint_de_Cardan
https://www.thingiverse.com/thing:42550/#files
https://www.thingiverse.com/thing:264017/#files
openscad:
https://www.thingiverse.com/thing:35057/#files
https://www.thingiverse.com/thing:392828/#files
généralité :
http://5lair.free.fr/Teachings/Files/CM%20Mecanique.pdf