‘nerd’ Category

Open Drum Machine Wireless Orchestra

aprile 8th, 2013

Domenica scorsa sono stato invitato a partecipare all’evento from MARKET to MAKERS, un evento sull’autoproduzione dal basso basato su strumenti e prodotti open source. Io sono stato invitato come musicista a presentare uno dei miei progetti basati su Arduino (come il midi mitra oppure Onda Quadra Posse).

Siccome mi piace reinventarmi, ho deciso di presentare un progetto nuovo, sempre basato su Arduino. Anche perchè le vecchie cose che avevo fatto erano fine a se stessi, e considerando il fatto che avevo già smontato tutto e perso lo schema elettrico.

Per tutta questa serie di ragioni ho ideato la Open Drum Machine Wireless Orchestra. Una performance in cui tutto il pubblico diventa parte integrante performativa dell’esibizione. Il concetto è semplice: accedendo ad una rete wireless opportunamente configurata tramite il proprio device (smartphone, tablet, pc) e accedendo ad un’apposita pagina web, si può interagire facendo suonare la batteria. E tutti i partecipanti agiscono sulla stessa batteria.

Per fare questo, coadiuvato dal mio amichetto nerd che però preferisce rimanere anonimo, ho configurato una Fonera installandoci OpenWRT, che forniva connettività wireless e assegnava ad ogni client connesso un indirizzo ip tramite l’apposito server DHCP e, tramite il server web, gestiva una pagina web sui cui girava una pagina statica che, con un click ad una immagine linkata, mandava la richiesta, tramite cavo ethernet, a un Arduino con lo shield ethernet. La richiesta http veniva convertita in segnale MIDI e inviato a Ableton Live installato sul computer. Ableton era configurato in modo da far partire un sample di batteria ad ogni impulso midi che gli arrivava.

odmwo

A tutto questo ho aggiunto una scheda makey makey, regalatami per il compleanno per far suonare loop tamarri di synth, come contorno per la batteria. L’idea era di prendere 4 persone, fargli tenere una parte del sensore, e dargli il 5 per far partire il loop assegnato a quel sensore. Per problemi legati alle masse o a inneschi o potrei inventarmi tantissime parole tecniche tanto non so da cosa è dipeso, quest’ultima parte della performance non è riuscita del tutto.

Ecco un video che spiega, forse, meglio:

Il Midi Mitra

gennaio 5th, 2013

Chi segue assiduamente questo blog, o chi mi conosce personalmente, sa cos’è la gara delle batterie elettroniche in quanto ne sono un fan e sostenitore accanito. Il 30 dicembre scorso si è svolta l’ultima edizione assoluta (ma io sono sicuro che non sia affatto così) e per parteciparvi ho costruito un aggegio che ho chiamato “midi mitra”.

midimitra

il midi mitra in azione

Ma cos’è in realtà il midimitra? Scopriamo le meraviglie che si celano dietro quest’arma sonora. E’ semplicemente una scheda Arduino con un sensore di prossimità a ultrasuoni che genera un segnale midi che serve a pilotare una drum machine, nel mio caso una Roland MC-303. Il sensore da come risultato la distanza in centimetri dell’oggetto che si trova davanti, per comodità io ho considerato la distanza come frequenza per fargli generare la nota midi. Sappiamo che ogni nota della scala musicale corrisponde ad una determinata frequenza, quindi io ho solo preso la frequenza più vicina ad una nota per poi inviarla via midi alla drum machine. Nella drum machine ogni nota corrisponde ad un certo pezzo della batteria (cassa, rullante, tom, etc…). Ho impostato 100 millisecondi tra una lettura e un’altra e quello che ne esce è, di fatto, un midimitra. midimitra Il circuito è piuttosto semplice, solo una resistenza ed un led, il resto tutto fili. I sensori di prossiminità ne esistono di due tipi, uno a 3 connettori e un altro a 4. La libreria di arduino si chiama Ultrasonic.h, ricercando con google viene fuori un sacco di documentazione. Anche il codice è abbastanza semplice:

#include “Ultrasonic.h” Ultrasonic ultrasonic(12,13); int unote; int stategrilletto = 0; const int buttongrilletto = 7; void setup() { pinMode(11, OUTPUT); pinMode(buttongrilletto, INPUT); Serial.begin(31250); } void loop() { stategrilletto = digitalRead(buttongrilletto); unote=ultrasonic.Ranging(CM); if(unote <= 33){ tone(8, 33, 250); digitalWrite(11, HIGH); } else if(unote == 34){ tone(8, 34, 250); digitalWrite(11, HIGH); noteOn(0×90, 0×18, 0×45); } else if(unote <= 37 && unote > 34){ tone(8, 37, 250); digitalWrite(11, HIGH); noteOn(0×90, 0×19, 0×45); } else if(unote <= 39 && unote > 37){ tone(8, 39, 250); digitalWrite(11, HIGH); noteOn(0×90, 0x1A, 0×45); } else if(unote <= 41 && unote > 39){ tone(8, 41, 250); digitalWrite(11, HIGH); noteOn(0×90, 0x1B, 0×45); } else if(unote <= 44 && unote > 41){ tone(8, 44, 250); digitalWrite(11, HIGH); noteOn(0×90, 0x1C, 0×45); } else if(unote <= 46 && unote > 44){ tone(8, 46, 250); digitalWrite(11, HIGH); noteOn(0×90, 0x1D, 0×45); } else if(unote <= 49 && unote > 46){ tone(8, 49, 250); digitalWrite(11, HIGH); noteOn(0×90, 0x1E, 0×45); } else if(unote <= 52 && unote > 49){ tone(8, 52, 250); digitalWrite(11, HIGH); noteOn(0×90, 0x1F, 0×45); } else if(unote <= 55 && unote > 52){ tone(8, 55, 250); digitalWrite(11, HIGH); noteOn(0×90, 0×20, 0×45); } else if(unote <= 58 && unote > 55){ tone(8, 58, 250); digitalWrite(11, HIGH); noteOn(0×90, 0×21, 0×45); } else if(unote <= 62 && unote > 58){ tone(8, 62, 250); digitalWrite(11, HIGH); noteOn(0×90, 0×22, 0×45); } else if(unote <= 67 && unote > 62){ tone(8, 67, 250); digitalWrite(11, HIGH); noteOn(0×90, 0×23, 0×45); } else if(unote <= 70 && unote > 67){ tone(8, 70, 250); digitalWrite(11, HIGH); noteOn(0×90, 0×24, 0×45); } else if(unote <= 74 && unote > 70){ tone(8, 74, 250); digitalWrite(11, HIGH); noteOn(0×90, 0×25, 0×45); } else if(unote <= 78 && unote > 74){ tone(8, 78, 250); digitalWrite(11, HIGH); noteOn(0×90, 0×26, 0×45); } else if(unote <= 83 && unote > 78){ tone(8, 83, 250); digitalWrite(11, HIGH); noteOn(0×90, 0×27, 0×45); } else if(unote <= 88 && unote > 83){ tone(8, 88, 250); digitalWrite(11, HIGH); noteOn(0×90, 0×28, 0×45); } else if(unote <= 93 && unote > 88){ tone(8, 93, 250); digitalWrite(11, HIGH); noteOn(0×90, 0×29, 0×45); } else if(unote <= 98 && unote > 93){ tone(8, 98, 250); digitalWrite(11, HIGH); noteOn(0×90, 0x2A, 0×45); } else if(unote <= 104 && unote > 98){ tone(8, 104, 250); digitalWrite(11, HIGH); noteOn(0×90, 0x2B, 0×45); } else if(unote <= 110 && unote > 104){ tone(8, 110, 250); digitalWrite(11, HIGH); noteOn(0×90, 0x2C, 0×45); } else if(unote <= 117 && unote > 110){ tone(8, 117, 250); digitalWrite(11, HIGH); noteOn(0×90, 0x2D, 0×45); } else if(unote <= 124 && unote > 117){ tone(8, 124, 250); digitalWrite(11, HIGH); noteOn(0×90, 0x2E, 0×45); } else if(unote <= 131 && unote > 124){ tone(8, 131, 250); digitalWrite(11, HIGH); noteOn(0×90, 0x2F, 0×45); } else if(unote <= 139 && unote > 131){ tone(8, 139, 250); digitalWrite(11, HIGH); noteOn(0×90, 0×30, 0×45); } else if(unote <= 147 && unote > 139){ tone(8, 147, 250); digitalWrite(11, HIGH); noteOn(0×90, 0×31, 0×45); } else if(unote <= 156 && unote > 147){ tone(8, 156, 250); digitalWrite(11, HIGH); noteOn(0×90, 0×31, 0×45); } else if(unote <= 165 && unote > 156){ tone(8, 165, 250); digitalWrite(11, HIGH); noteOn(0×90, 0×33, 0×45); } else if(unote <= 175 && unote > 165){ tone(8, 175, 250); digitalWrite(11, HIGH); noteOn(0×90, 0×34, 0×45); } else if(unote <= 185 && unote > 175){ tone(8, 185, 250); digitalWrite(11, HIGH); noteOn(0×90, 0×35, 0×45); } else if(unote <= 196 && unote > 185){ tone(8, 196, 250); digitalWrite(11, HIGH); noteOn(0×90, 0×36, 0×45); } else if(unote <= 208 && unote > 196){ tone(8, 208, 250); digitalWrite(11, HIGH); noteOn(0×90, 0×37, 0×45); } else if(unote <= 220 && unote > 208){ tone(8, 220, 250); digitalWrite(11, HIGH); noteOn(0×90, 0×38, 0×45); } else if(unote <= 233 && unote > 220){ tone(8, 233, 250); digitalWrite(11, HIGH); noteOn(0×90, 0×39, 0×45); } else if(unote <= 247 && unote > 233){ tone(8, 247, 250); digitalWrite(11, HIGH); noteOn(0×90, 0x3A, 0×45); } else if(unote <= 262 && unote > 247){ tone(8, 262, 250); digitalWrite(11, HIGH); noteOn(0×90, 0x3B, 0×45); } else if(unote <= 277 && unote > 262){ tone(8, 277, 250); digitalWrite(11, HIGH); noteOn(0×90, 0x3C, 0×45); } else if(unote <= 294 && unote > 277){ tone(8, 294, 250); digitalWrite(11, HIGH); noteOn(0×90, 0x3D, 0×45); } else if(unote <= 311 && unote > 294){ tone(8, 311, 250); digitalWrite(11, HIGH); noteOn(0×90, 0x3E, 0×45); } else if(unote <= 330 && unote > 311){ tone(8, 330, 250); digitalWrite(11, HIGH); noteOn(0×90, 0x3F, 0×45); } else if(unote <= 349 && unote > 330){ tone(8, 349, 250); digitalWrite(11, HIGH); noteOn(0×90, 0×40, 0×45); } else if(unote <= 370 && unote > 349){ tone(8, 370, 250); digitalWrite(11, HIGH); noteOn(0×90, 0×41, 0×45); } else if(unote <= 392 && unote > 370){ tone(8, 392, 250); digitalWrite(11, HIGH); noteOn(0×90, 0×42, 0×45); } else if(unote <= 415 && unote > 392){ tone(8, 415, 250); digitalWrite(11, HIGH); noteOn(0×90, 0×43, 0×45); } else if(unote <= 440 && unote > 415){ tone(8, 440, 250); digitalWrite(11, HIGH); noteOn(0×90, 0×44, 0×45); } else if(unote <= 466 && unote > 440){ tone(8, 466, 250); digitalWrite(11, HIGH); noteOn(0×90, 0×45, 0×45); } else if(unote <= 494 && unote > 494){ tone(8, 494, 250); digitalWrite(11, HIGH); noteOn(0×90, 0×46, 0×45); } Serial.println(unote); digitalWrite(11, LOW); delay(100); } void noteOn(int cmd, int pitch, int velocity) { Serial.write(cmd); Serial.write(pitch); Serial.write(velocity); }

La palla maggiore è stata scrivere tutti gli if per convertire la distanza in frequenza e poi ponderare la nota giusta. Come effetto coreografico ho aggiunto un led bianco (smontato da un affarino di star wars preso in un pacchetto di patatine) dentro il tubo di alluminio che si vede da un lato.

midimitra

Midi Mitra: visione d’insieme

Il led si accende, per poi spegnersi subito dopo, ad ogni nota suonata. E’ un midimitra a tutti gli effetti e, a quanto ne so, è il primo al mondo. (la scheda dietro non serve a niente, è solo per fare scena). Il risultato è una mitragliata di cassa o rullante o piatto o conga sparata dalle casse e dal subwoofer. Il risultato si può vedere nel video, anche se l’audio è un po’ distorto.

 

Gestiolus 0.1 is out

novembre 7th, 2012

Da circa 3 anni sto usando e sviluppando a velocità bradipo un gestionale per tenere traccia degli interventi e delle riparazioni nei vari laboratori di computer che gestisco. Svariate volte mi è capitato che mi fosse segnalato un guasto che non potevo sistemare subito per un motivo o per un altro e io, viste le mie ristrette capacità mentali, spesso me ne dimenticavo o, ancora peggio, me lo scrivevo su un foglio di carta. Non sia mai che nel 2012 sia ancora costretto a scrivere su un foglio di carta.

Gestiolus LogoPer questo motivo ho creato Gestiolus.

Esistono altri sistemi già pronti per la gestione dei ticket o cose simili, di prodotti ce ne sono tipo migliaia, ma li ho sempre trovati macchinosi e non immediati. Certo erano adatti comunque alle mie esigenze ma non mi soddisfacevano appieno.

Volevo un prodotto semplice e immediato, che facesse solo quello di cui ho bisogno, e poco più. Mi serviva anche avere un form scollegato dal sistema che potesse essere usato da tutti per segnalare l’intervento (in realtà questa funzione non l’ho ancora implementata).

All’indirizzo http://minucci.net/gestiolus-demo/ si può provare una demo funzionante.

Con Gestiolus è possibile aggiungere e rimuovere i laboratori o le aule su cui intervenire e tenere traccia di chi ha effettuato l’intervento. Alla fine è possibile generare dei report sul numero di interventi chiusi da un determinato nominativo.

E’ scritto in php e mysql, con qualche puntina di javascript, e potete scaricarlo da qua: http://code.google.com/p/gestiolus/

Occhio che c’è anche il git da cui prendere la versione più aggiornata.

celsiutter

marzo 28th, 2012

Dopo settimane di lavorazione sono riuscito a costruire celsiutter, un coso con Arduino che posta in automatico la temperatura su twitter.

Cosa vi serve?

Lo schema è questo:

E’ piuttosto semplice. L’LM35 c’ha 3 terminali: uno è la massa, l’altra è l’alimentazione che può essere da 4 volt in su e il pin centrale è quello che riporta la temperatura, un grado per ogni centesimo di volt. Ovvero se ci attacchiamo col teste sul centrale e questo misura 0,22 volt vuol dire che ci sono 22 gradi. Semplice.

I due led sono attaccati su uscite digitali diverse e libere, perchè l’Ethernet Shield ne usa lui alcune, non ho ben capito quali, sono andato a tentoni provando quali fossero libere. Quello verde serve a segnalare se il post è riuscito e se invece ritorna degli errori si accende quello rosso.

Poi ho collegato l’AREF ai 3,3 volt perchè, il codice che ho palesemente copiato da qui riadattandolo un po’ alle mie esigenze, calcola la temperatura usando come riferimento i 5 volt di Arduino. Siccome nei primi esperimenti non mi tornavano le temperature giuste, ho notato che in realtà i 5 volt del mio Arduino sono 4,88 e quindi, dopo aver fatto il calcolo, il risultato era un po’ sballato. Per evitare questo ho usato i 3,3 come riferimento che sono più precisi, misurando col tester segna 3,29 volta che va più che bene.

Per twitter ho usato questa libreria, che funziona bene e il codice non è troppo complesso.

Ora ecco il codice:

#include <SPI.h>
#include <Ethernet.h>
#include <Twitter.h>
#include <stdlib.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 10, 222 };
Twitter twitter(“TwitterToken”);
int pin = 0;
int temp = 0;
char tempchar[] = “”;
char testo[] = “”;
char fine[] = “”;
char msg[82] = “”;
int ledpost = 13;
int lederror = 8;
int i = 0;

void setup()
{
delay(1000);
Ethernet.begin(mac, ip);
Serial.begin(9600);
analogReference(EXTERNAL);
pinMode(ledpost, OUTPUT);
pinMode(lederror, OUTPUT);
}

void loop()
{
digitalWrite(ledpost, HIGH);
digitalWrite(lederror, LOW);
temp=(3.3 *analogRead(pin) *100.00) / 1024.0;
String testo = “Messaggio automatico generato da Arduino: a casa mia sono “;
String fine = ” gradi centigradi. “;
testo += temp;
testo += fine;
testo += i;
testo.toCharArray(msg, 82);
Serial.println(msg);
Serial.println(“connecting …”);
if (twitter.post(msg)) {
int status = twitter.wait(&Serial);
if (status == 200) {
Serial.println(“OK.”);
digitalWrite(ledpost, LOW);
} else {
Serial.print(“failed : code “);
Serial.println(status);
digitalWrite(lederror, HIGH);
}
} else {
Serial.println(“connection failed.”);
digitalWrite(lederror, HIGH);
}
Serial.print(i);
Serial.println(” Pausa di un’ora”);
i=i+1;
delay(3600000);
}

(indentatelo voi che io non c’ho voglia :) ) (dove c’è scritto TwitterToken dovete metterci il vostro token, lo generate dal sito della libreria)(nella variabile byte ip[] dovete metterci un indirizzi ip valido della vostra lan).

Il problema più grosso l’ho avuto nella conversione del formato delle variabili. twitter.post() accetta solo una char(), mentre la temperatura è un int() e ho dovuto concatenarla con una String e poi riconvertire tutto in char(). Se avete un metodo meno macchino segnalatelo pure nei commenti.

Alla fine del messaggio da postare su twitter ci ho dovuto mettere un valore incrementale altrimenti twitter lo vede come duplicato e non me lo fa postare. In questo modo, forse non troppo elegante, ho risolto il problema e inoltre mi tiene un log di quanti post ha effettuato (ovviamente ogni volta che spegnete Arduino ricomincia a contare da 0).

E’ tutto.

OpenWrt su 3Com 3CRWER200-75

marzo 13th, 2012

Un bel giorno la rete qua impazzì. I ping andavano a caso, i pacchetti si duplicavano, non arrivavano a destinazione, robe così. Un gran putiferio. Alla fine, dopo mille prove, siamo arrivati a dare la colpa ad un vecchio router 3com che usavamo come access point. Tolto questo affare dalla rete e tutto è tornato a funzionare regolarmente.

Questo affare poi è stato riposto in un armadio tra la roba non funzionante. A me dispiace vedere questi aggegi dimenticati e, visto che sono un fanatico di OpenWrt, ho provato a mettercelo visto che, nel sito, c’era la procedura per il modello 3CRWER100-75. In realtà io avevo un 3CRWER200-75, non so cosa cambi esattamente, so solo che la procedura ha funzionato regolarmente. Ed ecco quello che ho fatto io.

Innanzitutto tenetevi aprire la pagina apposita sul wiki, scaricatevi il kernel e il root fs, poi dovete installarvi un server tftp, io ho usato tftpd-hpa e ho installato anche putty. Di solito putty lo usavo su windows, ma ho scoperto che esiste anche per Linux. Putty serve semplicemente come terminale telnet, non ho usato il normale telnet già compreso in linux per motivi che spiegherò più avanti.

A questo punto dovete resettare il router per riportarlo alle impostazioni di fabbrica. Per fare questo basta tenere premuto il solito bottoncino e poi gli si da corrente e lo si tiene premuto per circa 10 secondi. Non so perchè ma l’ho dovuto rifare 3 volte.

Adesso il router torna all’impostazione di default e ha l’indirizzo 192.168.1.1, un ping ve lo confermerà, sempre che non abbiate in rete già un altro dispositivo con lo stesso indirizzo.

Ora non dovete fare altro che spegnere e riaccendere il router e lanciare il telnet sulla porta 9000 in un lasso di tempo indefinito in cui redboot ascolta su quella porta e vi da accesso al prompt. Facendolo a mano richiede culo e tempismo, roba che ci becchi tipo 1 volta su 10. Appena avuto accesso bisogna premere CTRL+C. Ed è proprio qua l’inceppo, pare che il telnet non riesco a mandare CTRL+C al prompt per qualche strambo motivo di tabella di caratteri o roba del genere, c’è in giro anche un hack usando netcat ma ho provato e non ha funzionato.

Ed ecco la mia elegante soluzione:

Innanzitto lanciate putty e configuratelo come in questa schermata

In pratica dovete settargli l’indirizzo ip, 192.168.1.1, la porta 9000, dirgli di usare il protocollo telnet e infine salvate la sessione. Io l’ho chiamato telnet9000.

A questo punto aprite il terminale e scrivete questo barbatrucco:

arping -f 192.168.1.1; putty -load telnet9000

Questo fa in modo che appena arping si accorge che l’ho desiderato, l’192.168.1.1, diventa attivo, lancia putty caricandogli, -load telnet9000, la sessione che abbiamo salvato prima: il succo del discorso è che fa il telnet sulla porta 9000 al momento giusto.

A questo punto dovreste avere una schermata di questo tipo:

ovvero siete arrivati al prompt di RedBoot, che è quello che ci interessa.

Ora, pre trasferire l’immagine del kernel e del rootfs, abbiamo bisogno di un server tftp da cui attigente.

Installate, come me, tftpd-hda, non perchè sia meglio di altri ma solo perchè sono riuscito a farlo funzionare alla svelta. Quindi

sudo apt-get install tftpd-hpa

(sudo perchè tanto lo so che usate tutti Ubuntu) poi create una directory per la root del server tftp, io per comodità l’ho creata nella root del file system, quindi /tftpboot, e gli date tutti i permessi del mondo di lettura e scrittura, sennò poi non il client non è contento.

Poi editate il file /etc/default/tftpd-hpa e fatelo diventare più o meno come questo:

# /etc/default/tftpd-hpa

TFTP_USERNAME=”tftp”
#TFTP_DIRECTORY=”/var/lib/tftpboot”
TFTP_DIRECTORY=”/tftpboot”
TFTP_ADDRESS=”192.168.1.101:69″
#TFTP_OPTIONS=”–secure”

L’indirizzo ip 192.168.1.101 non è casuale. Se tornate a putty e al prompt di RedBoot e scrivete

fsconfig -l

vi apparirà una roba tipo questa:

Praticamente RedBoot viene già di default con delle impostazioni sue: l’ip, il gateway e le altre robe. A noi interessa la riga:

Default server IP address: 192.168.1.101

che, praticamente, vuol dire che lui si aspetta che il server tftp sia su quell’indirizzo. Ora noi potremo andarci a leggere la documentazione di redboot e di fsconfig perchè un modo per cambiare quella voce c’è sicuramente, ma chi ce lo fa fare? Basta cambiare l’indirizzo ip della propria macchina che è molto più semplice :) Da qui spiegato il motivo del file di configurazione tftpd-hpa.

A questo punto siamo già un pezzo avanti e possiamo seguire pedissequamente la guida di OpenWrt. Quindi:

fis init

e premete y, poi, al prompt, scrivete:

load -r -b %{FREEMEMLO} /tftproot/openwrt-atheros-vmlinux.lzma
fis create -r 0×80041000 -e 0×80041000 vmlinux.bin.l7
load -r -b %{FREEMEMLO} /tftproot/openwrt-atheros-root.squashfs
fis free
fis create -l 0x2E0000 rootfs
fis list
reset

i due comando load hanno bisogno comunque del percorso assoluto, mistero, altrimenti se la prende a male e non trova il file. Se load ritorna errori di lettura vuol dire che non avete dati abbastanza permessi alla directory /tftproot, provate anche a dargli un chown -R nobody eventualmente.

Dopo il reset il router si riavvia e farà il boot con OpenWrt. Attenzione che il boot sarà un po’ più lento rispetto al firmware originale.

Per accedere telnettate l’192.168.1.1 e avrete accesso al prompt di OpenWrt, leggete le robe scritte, settando la password, con passwd, si imposta la password e si attiva automaticamente il server ssh.

Ora avete un router con OpenWrt e potete farci un po’ quello che vi pare

rockeat

febbraio 8th, 2012

sottotitolo: rockit e gli mp3 #2

(la descrizione sarà un po’ sommaria perchè mica mi ricordo esattamente tutti i passi della nostra ricerca)

Ebbene si, abbiamo (io e @eroispaziali, ma più che altro lui che si è smazzato il grosso del lavoro) trovato il modo di scaricare gli mp3 da rockit da dopo il restiling grafico che, di fanno, vanifica il vecchio procedimento.

Questa volta è un pelo più complicato, ma andiamo con ordine e prendiamo una pagina di esempio: i fine before you came con l’album ormai (che tanto c’è da scaricare anche dal loro sito quindi non facciamo male quasi a nessuno).

cominciamo a sbirciare tra il codice html e a cercare la sezione in cui carica il player di mp3: ad un certo punto carica il file player.swf, che è il player vero e proprio, e poi comincia a disegnare l’interfacca al player, i bottoni play, i titoli e tutto il resto. ma fino  a questo punto non si capisce niente, sembra funzionare per magia, invece sbirciando in fondo alla pagina viene caricato una libreria in javascript: lib.js. fai 2 + 2 e viene quasi naturale sbirciarci dentro.

tra le tante funzioni ce n’è una interessante:

function player_initSWF($data, $textStatus, $jqXHR) {

la player_initSWF(); ma, a parte i parametri tra parentesi, a noi interessa più una riga commentata:

// console.log( $data.url );

Facendo scrivere quella variabile, con un po’ di magheggi con firebug o robe simili, si riesce a risalire all’url del file mp3.

a questo punto magari dici: “ah, è fatta”, e invece no.

Torniamo a sbirciare l’html, ad ogni brano corrisponde un id:

<li class=”item” id=”id_139208_4068″><ul><li class=”play”><a href=”#” rel=”139208″>Play</a></li><li class=”playlist”><a href=”#” rel=”nofollow”>Aggiungi</a></li><li class=”title”><a href=”/finebeforeyoucame/canzone/dublino/139208” class=”titolo” rel=”nofollow”>1. Dublino</a></li></ul></li>

A parte gli <li> annidati notiamo che ad ogni canzone corrisponde un id della canzone e un id dell’album. In questo caso 4066 è l’id dell’album, mentre 139208 è l’id dell’mp3 che, come per magia, corrispondono alla variabile $data.url della funzione in javascript.

Ma ancora niente download diretto. E niente, magheggiando con altre robe tipo  HttpFox o simile si riesce a scoprire che il file viene presto tramite POST e non tramite GET quindi.

Sempre nel file lib.js c’è questo:

$('body').append('<form id="godown" '+$response.t+'><input type="hidden" name="rockitID" value="'+$response.k+'"/></form>');

che altri non è che un campo POST nascosto, e non visibile dall’html, che specifica una stringa, un id chiamato appunto rockitID.

Ma come viene generato questo rockitID? Mistero. Abbiamo chiesto a Giacobbo e a prima vista sembra una semplice stringa md5 che, sappiamo tutti, non è reversibile.

Non so quante combinazioni di stringhe ho provato a convertire ma niente, nessuna ritornava quella giusta.

La soluzione consiste nel decompilare il file player.swf.

Ad un certo punto, dentro il file .swf, c’è questo:

_loc_1.rockitID = MD5.hash(this.fileURL + “-PAROLASEGRETISSIMA”);

Dove PAROLASEGRETISSIMA ovviamente non è PAROLASEGRETISSIMA ma una stringa di testo che mi piace di più tenere segreta: un po’ come le strette di mano dei moti carbonari, o il modo di allacciare le scarpe delle spie, o anche la tizia che guidava la jeep nella contea di Hazzard.

Quindi basta calcolare l’hash md5 aggiungendo la PAROLASEGRETISSIMA in fondo alla stringa e viene ritornato il rockitID giusto. A quel punto basta usare wget, o curl, passandogli come POST rockitID la stringa md5 risultante e l’url del file mp3.

Semplice. Ecco il risultato (però con un altro album che i Fine Before You Came ce li ho già):

Semplice? Ora che lo so è semplice, ma prima non lo era affatto :)

In questa sede mi preme ringraziare non tanto rockit, che comunque è da un po’ di tempo ormai che mette on line album che non mi interessano, ma piuttosto ringrazio @eroispaziali che mi ha dato lo stimolo e mi ha motivato per trovare la soluzione.

Un po’ come quando il capitano Picard spiega a non mi ricordo quale razza aliena che parte del senso della vita è risolvere i problemi che ti si presentano man mano. E con problemi non intendo le bollette da pagare, quello si risolve pagando la bolletta, ma problemi inteso come dice wikipedia:

Un problema, comunemente inteso, è un ostacolo che rende difficile raggiungere un determinato obiettivo o soddisfare una certa esigenza, frapponendosi tra la volontà dell’individuo e la realtà oggettiva.

Quindi non è che uno mi dice “ah, ma che sfigato, non hai nient’altro da fare?”, si e no. Faccio le cose che mi diverte fare: in questo caso riuscire a scaricare gli mp3 da rockit. Altri preferiscono truccare i motorini, altri passano il tempo a lucidare la macchina, altri guardano il grande fratello, altri fanno altre cose. Il mio non lo considero affatto tempo perso. Ognuno impiega il proprio tempo come preferisce.

Uno dei miei motti è: d’altronde gianni morandi mangia la merda.

Chi sono io per giudicarlo? :)

 

Update: leggetevi però anche questo prima di giudicare.

rockeat

febbraio 8th, 2012

sottotitolo: rockit e gli mp3 #2

(la descrizione sarà un po’ sommaria perchè mica mi ricordo esattamente tutti i passi della nostra ricerca)

Ebbene si, abbiamo (io e @eroispaziali, ma più che altro lui che si è smazzato il grosso del lavoro) trovato il modo di scaricare gli mp3 da rockit da dopo il restiling grafico che, di fanno, vanifica il vecchio procedimento.

Questa volta è un pelo più complicato, ma andiamo con ordine e prendiamo una pagina di esempio: i fine before you came con l’album ormai (che tanto c’è da scaricare anche dal loro sito quindi non facciamo male quasi a nessuno).

cominciamo a sbirciare tra il codice html e a cercare la sezione in cui carica il player di mp3: ad un certo punto carica il file player.swf, che è il player vero e proprio, e poi comincia a disegnare l’interfacca al player, i bottoni play, i titoli e tutto il resto. ma fino  a questo punto non si capisce niente, sembra funzionare per magia, invece sbirciando in fondo alla pagina viene caricato una libreria in javascript: lib.js. fai 2 + 2 e viene quasi naturale sbirciarci dentro.

tra le tante funzioni ce n’è una interessante:

function player_initSWF($data, $textStatus, $jqXHR) {

la player_initSWF(); ma, a parte i parametri tra parentesi, a noi interessa più una riga commentata:

// console.log( $data.url );

Facendo scrivere quella variabile, con un po’ di magheggi con firebug o robe simili, si riesce a risalire all’url del file mp3.

a questo punto magari dici: “ah, è fatta”, e invece no.

Torniamo a sbirciare l’html, ad ogni brano corrisponde un id:

<li class=”item” id=”id_139208_4068″><ul><li class=”play”><a href=”#” rel=”139208″>Play</a></li><li class=”playlist”><a href=”#” rel=”nofollow”>Aggiungi</a></li><li class=”title”><a href=”/finebeforeyoucame/canzone/dublino/139208” class=”titolo” rel=”nofollow”>1. Dublino</a></li></ul></li>

A parte gli <li> annidati notiamo che ad ogni canzone corrisponde un id della canzone e un id dell’album. In questo caso 4066 è l’id dell’album, mentre 139208 è l’id dell’mp3 che, come per magia, corrispondono alla variabile $data.url della funzione in javascript.

Ma ancora niente download diretto. E niente, magheggiando con altre robe tipo  HttpFox o simile si riesce a scoprire che il file viene presto tramite POST e non tramite GET quindi.

Sempre nel file lib.js c’è questo:

$('body').append('<form id="godown" '+$response.t+'><input type="hidden" name="rockitID" value="'+$response.k+'"/></form>');

che altri non è che un campo POST nascosto, e non visibile dall’html, che specifica una stringa, un id chiamato appunto rockitID.

Ma come viene generato questo rockitID? Mistero. Abbiamo chiesto a Giacobbo e a prima vista sembra una semplice stringa md5 che, sappiamo tutti, non è reversibile.

Non so quante combinazioni di stringhe ho provato a convertire ma niente, nessuna ritornava quella giusta.

La soluzione consiste nel decompilare il file player.swf.

Ad un certo punto, dentro il file .swf, c’è questo:

_loc_1.rockitID = MD5.hash(this.fileURL + “-PAROLASEGRETISSIMA”);

Dove PAROLASEGRETISSIMA ovviamente non è PAROLASEGRETISSIMA ma una stringa di testo che mi piace di più tenere segreta: un po’ come le strette di mano dei moti carbonari, o il modo di allacciare le scarpe delle spie, o anche la tizia che guidava la jeep nella contea di Hazzard.

Quindi basta calcolare l’hash md5 aggiungendo la PAROLASEGRETISSIMA in fondo alla stringa e viene ritornato il rockitID giusto. A quel punto basta usare wget, o curl, passandogli come POST rockitID la stringa md5 risultante e l’url del file mp3.

Semplice. Ecco il risultato (però con un altro album che i Fine Before You Came ce li ho già):

Semplice? Ora che lo so è semplice, ma prima non lo era affatto :)

In questa sede mi preme ringraziare non tanto rockit, che comunque è da un po’ di tempo ormai che mette on line album che non mi interessano, ma piuttosto ringrazio @eroispaziali che mi ha dato lo stimolo e mi ha motivato per trovare la soluzione.

Un po’ come quando il capitano Picard spiega a non mi ricordo quale razza aliena che parte del senso della vita è risolvere i problemi che ti si presentano man mano. E con problemi non intendo le bollette da pagare, quello si risolve pagando la bolletta, ma problemi inteso come dice wikipedia:

Un problema, comunemente inteso, è un ostacolo che rende difficile raggiungere un determinato obiettivo o soddisfare una certa esigenza, frapponendosi tra la volontà dell’individuo e la realtà oggettiva.

Quindi non è che uno mi dice “ah, ma che sfigato, non hai nient’altro da fare?”, si e no. Faccio le cose che mi diverte fare: in questo caso riuscire a scaricare gli mp3 da rockit. Altri preferiscono truccare i motorini, altri passano il tempo a lucidare la macchina, altri guardano il grande fratello, altri fanno altre cose. Il mio non lo considero affatto tempo perso. Ognuno impiega il proprio tempo come preferisce.

Uno dei miei motti è: d’altronde gianni morandi mangia la merda.

Chi sono io per giudicarlo? :)

 

Update: leggetevi però anche questo prima di giudicare.

Update: è cambiato tutto di nuovo, tenetevi aggiornati.

Arduino Vj System

gennaio 6th, 2012

Sono mesi che avevo in mente questo progetto usando Arduino e la libreria TV Out, finalmente sono riuscito a produrre qualcosa di funzionante ed è anche giunta l’ora di rendere pubblico il tutto.

La libreria per il tv out serve, come si intuisce dal nome, a generare dei segnali video. Vista la scarsa potenza di Arduino, si riescono soltanto a generare segnali video in bianco e nero e con una risoluzione di 128×96 pixel. Per capirci si riescono a fare cose come questo o questo o quest’altro. Sono vecchi esperimenti che avevo fatto tempo fa. E’ roba molto limitata ma, visti i limiti, la sfida diventa ancora più interessante.

La mia idea era costruire un coso da utilizzare come visual durante un concerto. La definizione di vj di wikipedia è abbastanza esaustiva. In pratica un affare con dei comandi per interagire in tempo reale, o quasi, con gli effetti video generati da Arduino.

Questo è il risultato:

Per comodità ho scelto di costruire il circuito su una millefori da inserire direttamente su Arduino. Nella foto si possono vedere i 3 switch per selezionare gli effetti, il connettore RCA giallo per l’uscita video, il potenziometro per regolare la velocità dell’effetto e il led verde che segnala l’accensione – il led rosso in realtà non serve a niente.

Questo è lo schema:

Per disegnarlo ho usato Fritzing e potete anche scaricarvi il file con gli schemi.

Per ottimizzare ho usato solo 3 interruttori coi quali si possono selezionare 8 diversi effetti video. Ecco l’elenco:

  • 000: face();
  • 001: point();
  • 010: strobo();
  • 011: star();
  • 100: square();
  • 101: bug();
  • 110: cube();
  • 111: circle();

(le prime tre cifre indicano lo stato degli switch A, B e C; 0 è spento, 1 è acceso)

Potete scaricarvi il sorgente per Arduino. Dentro il codice ci sono varie funzione che si chiamano nello stesso modo elencato qui sopra. Da notare l’effetto bug() che in realtà doveva fare tutt’altro, almeno per come l’avevo pensato, ma per colpa di non so quale bug genera un effetto video che non mi dispiaceva affatto, per cui l’ho lasciato così com’è.

Per l’effett face() ho tentato di usare la funzione interna della libreria TV Out per caricare le bitmap, opportunamente convertite, ma non ci sono riuscito per cui, visto che dovevo sbrigarmi a finire tutto l’ambaradan, ho optato per un sistema empirico: tipo che disegno le faccie pixel per pixel, questo ovviamente ha portato ad un riempimento smodato della memoria di Arduino tant’è che ci sono state solo due faccie :) .

Ecco il risultato proiettato dal vivo durante il nostro concerto:

Al minuci 3:05 si può vedere l’effetto bug() in azione.

Se vi interessa qua, qua, qua e qua ci sono le parti rimanenti del concerto.

Ogni tanto, mettendo in sequenza alcuni effetti video, Arduino perdeva il controllo, credo per il troppo casino a video, e bisognava resettare tutto il sistema.

zelda

novembre 22nd, 2011

ho comprato, per IL wii, il nuovo gioco di zelda, ecco le foto dell’unboxing:
http://www.flickr.com/apps/slideshow/show.swf?v=109615

tra l’altro ci sto giocando a randello tutti i giorni

casa nuova, adsl nuova

febbraio 4th, 2011

presto cambierò casa, tutti i dettagli al più presto, e prima del trasloco ho pensato bene di far partire la macchina burocratica per avere una nuova adsl.

tralascio le avventure per il passaggio della mia attuale adsl al nuovo indirizzo che mi hanno portato a optare per la disdetta e passaggio a nuovo operatore viste le lungaggini e le vaghezze riscontrate nei ticket aperti.

comunque, la prima cosa da fare è controllare la copertura, più o meno tutti i provider hanno, nel proprio sito, una casellina dove inserire il tuo numero di telefono o di un tuo vicino (nel caso tu non abbia ancora il telefono e nel caso non lo voglia nemmeno, come nel mio caso) per vedere se in quella zona è raggiungibile. mi sembra semplice come processo.

ok, sono sfigato e tutti gli operatori  che ho provato ( fastweb, alice, cheapnet e ngi) danno che non è disponibile.

tutti tranne alice, alice è l’unica che dice che la mia zona è raggiunta.

il punto a cui voglio arrivare, a parte i discorsi sul digital divide, è che perchè ngi usa il servizio di telecom, questo, per vedere la disponibilità della linea e da esito negativo mentre alice, che è sempre di telecom, da esito positivo? c’è qualcosa che non torna, puzza un po’…