Étape 8: Fatigué de faire de la chute de battre ? Nous allons ajouter d’autres capteurs et sons.
La joie de faire un tambour bass le coup d’une presse de bouton physique s’estompe assez rapidement, nous allons donc faire un peu plus intéressant. Nous pouvons utiliser Cylon s’interfacer avec une énorme quantité de différents capteurs et dispositifs. Jusqu'à présent, nous avons collé à l’aide d’un événement de pousser le bouton unique pour lancer le tambour. Maintenant, nous allons à refactoriser notre code app.js pour la rendre un peu plus facile d’ajouter plus de boutons, ainsi que d’ajouter certains capteurs analogiques.
Avant d’apporter des modifications au code, nous allons ajouter quelques dispositifs plus de travailler avec.
Pour cela instructable, j’ai choisi d’associer un total de 4 boutons, un potentiomètre et une cellule photoélectrique. Cela nous permettra de contrôler plusieurs paramètres d’instruments de Timbre.js avec un large éventail de valeurs, au lieu de simplement les valeurs ON/OFF de nos boutons.
Maintenant, nous allons Refactoriser notre code pour prendre en charge davantage de périphériques. Nous voulons être en mesure de permettre à notre client pour écouter les touches spécifiques et des lectures de capteurs spécifiques, au lieu d’utiliser un événement générique "bouton". Nous allons envoyer deux événements différents, « bouton » et « capteur », avec une valeur de hachage qui contient un id de notre dispositif, ainsi que la valeur que nous voulons envoyer. Pour les boutons, nous attendrons un 0 ou un 1 et pour capteurs analogiques, nous tout ce qui attendra la valeur qu'est la lecture de la sonde. Apportez les modifications suivantes à votre fichier « app.js ».
var express = require('express') var app = express() var server = require('http').Server(app) var cylon = require('cylon') var io = require('socket.io')(server) app.use(express.static(__dirname + '/public')) server.listen(8080) var socket = io .of('/soundsocket') .on('connection', function (socket) { console.log('client connected') }) var cylonReady = function(my) { io .of('/soundsocket') .on('connection', function (socket) { registerSocketHandlers(my, socket); }) } // this will be called each time a socket is opened, so each client will receive their own events when buttons are pushed. var registerSocketHandlers = function(my, socket) { buttons = [my.button0, my.button1, my.button2, my.button3] for (var i = 0; i < buttons.length; i++) { var button = buttons[i]; registerButtonHandler(socket, button, i); } analogSensors = [my.potentiometer, my.photocell] for (var i = 0; i < analogSensors.length; i++) { var sensor = analogSensors[i]; registerAnalogSensorHandler(socket, sensor, i); } } // convenience for button specific events var registerButtonHandler = function(socket, button, buttonID) { // on push, send button ID and value of 1 button.on('push', function() { socket.emit('button', { 'id': buttonID, 'value': 1 }) }) // on push, send button ID and value of 0 button.on('release', function() { socket.emit('button', { 'id': buttonID, 'value': 0 }) }) } // convenience for listening to analog read events and emitting sensor data messages var registerAnalogSensorHandler = function(socket, analogSensor, analogSensorID) { // on new data, send sensor ID and value of sensor reading analogSensor.on('analogRead', function() { // ask the sensor for it's value sensorValue = analogSensor.analogRead() socket.emit('sensor', { 'id': analogSensorID, 'value': sensorValue }) }) } // tell Cylon which devices we will be interfacing with var getDevices = function() { return { button0: { driver: 'button', pin: 2 }, button1: { driver: 'button', pin: 3 }, button2: { driver: 'button', pin: 4 }, button3: { driver: 'button', pin: 5 }, potentiometer: { driver: 'analogSensor', pin: 0, lowerLimit: 100, upperLimit: 900 }, photocell: { driver: 'analogSensor', pin: 1, lowerLimit: 100, upperLimit: 900 } } } // tell Cylon how we will be connecting to our devices var getConnections = function() { return { edison: { adaptor: 'intel-iot' } } } cylon.robot({ connections: getConnections(), // use our getConnections function to clean this up. devices: getDevices() // use our getDevices function to clean this up. }).on('ready', cylonReady) cylon.start()
Remarque : Assurez-vous que vos capteurs analogiques sont connectés aux ports Analogiques dans de votre Edison.
Afin de consommer ces changements dans notre client, apportez les modifications suivantes afin que votre "playsounds.js" reflète le code suivant :
var BD var SD var HH1 var HH2 var CYM var drum var lead var env var arp var delay var inv T("audio").load("./drumkit.wav", function() { BD = this.slice( 0, 500).set({bang:false}) SD = this.slice( 500, 1000).set({bang:false}) HH1 = this.slice(1000, 1500).set({bang:false, mul:0.2}) HH2 = this.slice(1500, 2000).set({bang:false, mul:0.2}) CYM = this.slice(2000).set({bang:false, mul:0.2}) var scale = new sc.Scale([0,1,3,7,8], 12, "Pelog") var P1 = [ [BD, HH1], [HH1], [HH2], [], [BD, SD, HH1], [HH1], [HH2], [SD], ].wrapExtend(128) var P2 = sc.series(16) drum = T("lowshelf", {freq:110, gain:8, mul:0.6}, BD, SD, HH1, HH2, CYM).play() lead = T("saw", {freq:T("param")}) env = T("perc", {r:100}) arp = T("OscGen", {wave:"sin(15)", env:env, mul:0.5}) delay = T("delay", {time:"BPM128 L4", fb:0.65, mix:0.35}, T("pan", {pos:T("tri", {freq:"BPM64 L1", mul:0.8}).kr()}, arp) ).play(); inv = T("interval", {interval:"BPM128 L16"}, function(count) { var i = count % P1.length if (i === 0) CYM.bang() P1[i].forEach(function(p) { p.bang() }) if (Math.random() < 0.015) { var j = (Math.random() * P1.length)|0; P1.wrapSwap(i, j); P2.wrapSwap(i, j); } var noteNum = scale.wrapAt(P2.wrapAt(count)) + 60; if (i % 2 === 0) { lead.freq.linTo(noteNum.midicps() * 2, "100ms"); } arp.noteOn(noteNum + 24, 60) }).start() }) var socketConnection = io.connect('http://0.0.0.0:8080/soundsocket') socketConnection.on('connect', function () { console.log('connected to socket') }) socketConnection.on('button', function (data) { buttonID = data['id'] value = data['value'] switch (buttonID) { case 0: if (value == 1) { BD.bang() } break; case 1: if (value == 1) { CYM.bang() } break; case 2: value == 1 ? HH1.set({mul: 1}) : HH1.set({mul: 0.2}) break; case 3: value == 1 ? HH2.set({mul: 1}) : HH2.set({mul: 0.2}) break; default: } }) socketConnection.on('sensor', function (data) { sensorID = data['id'] value = data['value'] switch (sensorID) { case 0: inv.set({interval: value * 2 }) break; case 1: arp.set({mul: 10 / value }) break; default: } })
Commettre et poussez vos modifications, tirez-les vers le bas pour l' Edisonet exécuter votre application. Si tout fonctionne comme prévu, vous devriez être en mesure d’utiliser les touches pour frapper des instruments spécifiques et être capable de modifier le délai et Remarque décale à l’aide de vos capteurs analogiques.
Cela vous donne un exemple de la façon de consommer des différents types de données et chaque jeu ou modifier les paramètres des instruments au sein de la Timbre.js.