10 marzo 2011

Prendere dimestichezza con Google App Engine

Ho trovato il tempo di impratichirmi con Google App Engine, in particolare inglobando il codice per calcolare la lunghezza totale dei filmati preferiti su YouTube dentro una applicazione web, realizzata con il supporto di Google App Engine. Non è stato complicato, ed effettivamente al momento il risultato è spartano, ma è stato molto istruttivo. Oltre al guadagno intellettuale ho riscontrato un notevole miglioramento delle prestazioni del mio codice, cosa buona e giusta.

Adesso, volendo continuare con questo filone, sarebbe interessante fornire la mia applicazione web di una grafica più carina (con qualche disegno, codice html e css, ecc.)

Il risultato lo trovate qui (mettete il vostro nome utente di YouTube e cliccate Go!)

16 febbraio 2011

Childgrove: ballata popolare scozzese

Sempre alla ricerca di temi musicali da rielaborare, e da suonare, ho trovato questo splendido libro: "Complete Scottish and English country dance master for recorders" e subito mi ha colpito Childgrove. Ho ascoltato e trascritto, in LilyPond, questo tema e due variazioni (tratte da una versione che ho ascoltato e, secondo me, molto istruttive). Nel libro si trova una seconda voce, probabilmente scritta dalla O'Scannell, che non ho elaborato -per ora-

Ecco lo spartito al momento attuale.


9 febbraio 2011

Contare tempo malato passato su YouTube

Per prendere pratica con le API dello zio Google, gdata, e per non dimenticarmi come si programma in Python, ho scritto questo programmino che scandaglia i preferiti di un utente YouTube (username="106ohm", per esempio) e ne estrae la durata in secondi; sommando le durate si ottiene una stima di quanto una persona è malata di youtubite...

Ho riscontrato i seguenti problemi:

1. con yt_service.GetYouTubeVideoFeed(uri) si possono estrarre Feed di massimo 50 Entry: bisogna fare un ciclo generale -io l'ho fatto di 20 Entry*- che modifica l'uri; dunque è necessario conoscere lo schema dell'uri...

2. yt_service.GetYouTubeVideoFeed(uri) smatta se riceve un uri non corretto. Nel nostro caso significa che sono finiti i chuck, e dunque ci si può fermare (occorrono due controlli dunque sulla suddetta: il primo per assicurarsi che favorites_feed_chuck non sia vuota, il secondo per assicurarsi che contenga informazioni sensate)

3. anche se la entry è non vuota potrebbe non essere definito entry.media.duration.seconds (capita per esempio quando un utente segna un video come preferito, ma questo viene ritirato in seguito dall'autore o dai gestori) e dunque c'è bisogno di un try in più.

4. Convertire in modo brutale i secondi in anni, giorni, ore, minuti e secondi è una palla.

=>Inizio codice

#!/usr/bin/env python

#importo cio' che mi occorre
import gdata.youtube
import gdata.youtube.service

#inizializzo questo oggetto prima di fare qualsiasi cosa
yt_service= gdata.youtube.service.YouTubeService()

##
#DEFINIZIONE FUNZIONI UTILI
##


#definisco una funzione per estrarre informazioni dalle entry
def PrintEntryDetails(entry):
print 'Video title: %s' % entry.media.title.text
## print 'Video published on: %s ' % entry.published.text
## print 'Video description: %s' % entry.media.description.text
## print 'Video category: %s' % entry.media.category[0].text
## print 'Video tags: %s' % entry.media.keywords.text
## print 'Video watch page: %s' % entry.media.player.url
## print 'Video flash player URL: %s' % entry.GetSwfUrl()
## print 'Video duration: %s' % entry.media.duration.seconds

# non entry.media attributes
#print 'Video geo location: %s' % entry.geo.location()
## print 'Video view count: %s' % entry.statistics.view_count
## print 'Video rating: %s' % entry.rating.average

# show alternate formats
## for alternate_format in entry.media.content:
## if 'isDefault' not in alternate_format.extension_attributes:
## print 'Alternate format: %s | url: %s ' % (alternate_format.type, alternate_format.url)

# show thumbnails
## for thumbnail in entry.media.thumbnail:
## print 'Thumbnail url: %s' % thumbnail.url

#definisco una funzione che lancia PrintEntryDetails per ogni entry di un dato feed

def PrintVideoFeed(feed):
for entry in feed.entry:
PrintEntryDetails(entry)

##
#FINE DEFINIZIONE FUNZIONI
##


##stampo i primi 20 video preferiti
##username="106ohm"
##uri= 'http://gdata.youtube.com/feeds/api/users/%s/favorites?v=2&start-index=1&max-results=20' % username
##favorites_feed = yt_service.GetYouTubeVideoFeed(uri)
##PrintVideoFeed(favorites_feed)



#sommo le durate dei video preferiti

username="106ohm"
max_results=20
uri= 'http://gdata.youtube.com/feeds/api/users/%s/favorites?v=2&start-index=1&max-results=%s' % (username, max_results)
favorites_feed_chuck = yt_service.GetYouTubeVideoFeed(uri)
count = 0
chuck=0
start_index=1
while favorites_feed_chuck is not None:
for entry in favorites_feed_chuck.entry:
if entry is not None:
try:
count = count + int(entry.media.duration.seconds)
except:
#per sapere quali video non vengono considerati
#print PrintEntryDetails(entry)
pass
chuck = chuck + 1
start_index = start_index + 20
uri= 'http://gdata.youtube.com/feeds/api/users/%s/favorites?v=2&start-index=%s&max-results=%s' % (username, start_index, max_results)
try:
favorites_feed_chuck = yt_service.GetYouTubeVideoFeed(uri)
except:
break

print 'totale: %s secondi' % count

#converto in termini di secondi, minuti, ore, giorni ed anni

minuts = count / 60
seconds = count - minuts*60
hours = minuts / 60
minuts = minuts - hours*60
days = hours / 24
hours = hours - days * 24
years = days / 365
days = days - years * 356

print 'durata totale: %s anni %s giorni %s ore %s minuti %s secondi' % (years, days, hours, minuts, seconds)


=>Fine codice

Commenti:

ho commentato tante altre belle cose... Forse in seguito troverò il tempo di usarle per qualche figata.

*la scelta di max_results=20 implica un maggior numero di cicli while, ma un minor numero di cicli for entry in ... A voi decidere se cambiarlo o meno.

28 gennaio 2011

Karaoke fatto in casa...

Di neccessità virtù. Volendo fare un pò di Karaoke (dal giapponese "vuota orchestra") in breve tempo, ho rispolverato gli appunti del Laboratorio Sperimentale di Matematica Computazonale, la cui terza parte è dedicata all'elaborazione audio digitale. Quello che descrivo è -in pratica- come costruire un cannone per sparare alle mosche, ma spesso funziona, e può far comodo. Ovviamente se volete fare Karaoke con GNU\Linux avete a disposizione strumenti professionali, ma questa soluzione è interessante a prescindere.

Ci sono sostanzialmente due modi di togliere la voce principale da una canzone, così da poterci cantare sopra:

* Eliminare le frequenze che corrispondono alla voce umana (si applica una trasformata discreta di Fourier ~oppure una trasformata discreta wavelet~ si diminuiscono le frequenze dove cade la voce, che cambia da uomo a donna, ed in base al timbro del cantante, e poi di anti-trasforma)

[i CD hanno come parametri standard: 2 canali a 16 bit, si memorizzano interi, a freq 44100]

* Si fa la differenza fra il canale destro e quello sinistro (per le canzoni pop viene -spesso- prima registrata la base musicale -dove ogni strumento risulta maggiormente su un canale o su l'altro- e poi la voce viene equamente distribuita sui due canali) in questo modo la voce si abbassa drasticamente, e si danneggia poco la base musicale

Per mettere in pratica questo, ho preso un programmino scritto dal prof. Steffè

http://www.dm.unipi.it/pages/steffe/public_html/DIDA/LSMC-2010/parte3/program1/mono.f90

ed ho modificato la riga "soundds=(soundds+soundsn)/2.0" con "soundds=soundds-soundsn"

Questo programmino legge file in formato cdr, cioè da CD, dunque se volete lavorare con gli MP3 potete scrippettare come segue:

mpg123 --cdr file.cdr NomeFile.mp3

f95 mono.f90 -o mono (o compilare con altri compilatori, possibilmente liberi, come gfortran)

./mono (inserite file.cdr e poi elaborato.cdr)

sox elaborato.cdr elaborato.wav

lame elaborato.wav karaoke.mp3

ed ecco fatto.

Ho sperimentato questo approccio con qualche canzone, e i risultati sono buoni.

AVVERTENZE:

Con canzoni registrate in mono, ovviamente, questo trucchetto non funziona (neanche con canzoni registrate in mono, messe in stereo per essere commercializzate su CD od in MP3)

Con RAP a due (o simil) funziona male perché il "botta e risposta" è basato anche sulla differenziazione dei canali.

Potrebbe capitare che i due canali siano talmente simili da rendere il risultato molto basso di volume.

Con canzoni dalla base musicale elaborata possono presenzarsi sgradevoli rumori (tanto a noi interessava lavorare su canzoni pop :)

4 gennaio 2011

Cloud Computing...

Interssanti, fra i tanti, articoli: questo(da Wired) e questo(dal Guardian)

Penso sia interessante sperimentare, con criterio, questa nuova via.