Jplayfine
Contingut
Recursos
Partitures en format lilypond i del domini públic:
Idees
PlayFine pretén ser una aplicació escrita en C per aprendre i millorar passatges musicals. És útil per instruments que siguin controladors MIDI (per tant no val per a qualsevol instrument). És una aplicació personal pensada per ser utilitzada per mi, que requereix de la llibreria MidiShare, fluidsynt,... per tant no és una aplicació per què una persona sense coneixements la pugui utilitzar.
Volem estudiar i practicar un passatge musical. Partim d'un fitxer de lilypond on hem escrit aquest passatge. El fitxer tindrà dos veus: la 1a el metrònom, la segona el passatge que volem estudiar.
El primer objectiu que s'ha d'aconseguir és fer sonar aquest passatge. En el passatge no tindrem en compte dinàmiques, només ens interessarà quines notes són, quan es toquen, i durada de les notes.
El segon objectiu és poder tocar amb el WX5 (o similar, virtual keyboard), i registrar les notes que estic tocant. Que aparegui per pantalla quina nota he tocat i en quin instant l'he tocat.
El tercer objectiu és poder treure una nota que em digui si he tocat o no, una nota objectiva que em doni el grau de fiabilitat. Per obtenir la nota em centraré en les notes equivocades, i en les notes fora de temps, penalitzant els errors. Per ex
Hi ha dos arrays: un que guarda les notes que s'han de tocar, un altre que guarda el temps en què s'han de tocar. La dimensió de l'array és el número de notes que s'han de tocar.
Els esdeveniments que s'han de controlar són doncs 2*num_notes.
Els errors són num_errors_nota i num_errors_temps.
Una primera aproximació a la nota final vindrà donat per
NOTA=100-((num_errors_nota + num_errors_temps)/(2*num_notes))
de manera que si no tinc errors tindria un 100, i si tinc tots els errors tinc un 0. Ara bé, no és el mateix entrar tard 0.1 s que 0.3 s, o avançar-se molt o poc. Per tant, num_errors_temps serà de fet un valor decimal que tindrà en compte aquesta causística, i a més tindrà en compte el tempo de la melodia, doncs no és el mateix equivocar-se de 0.1 s quan toquem a un tempo de 80 que a un tempo de 120.
En canvi, equivocar-se de mig to és equivalent a equivocar-se de dos tons: es detecta de seguida l'error.
hem d'obtenir una nota del 0 al 100.
Varis modes de fer servir el programa: tocar a sobre la melodia o no; tocar amb metrònom o no (en aquest cas, hi haurà una intro o no). El metrònom també pot ser visual.
En principi ho programaré amb llenguatge C, utilitzant la llibreria MidiShare, i una possible crida de l'executable seria:
play_fine -f fitxer.ly -p -f fitxer.ly: fitxer font del lilypond -p: que soni la melodia -m [s|sv|v]: que soni o es vegi el metrònom. s només so; v només pantalla: sv so i pantalla -i num: intro (que soni la intro del metrònom, num temps d'espera) -v verbose -l num: fer loops num vegades -s log.txt. Registra els resultats en un format que pot ser útil per portar unes estadístiques: fitxer.ly;data;nota.
Aquest log no s'esborra sinó que es va afegint.
En una segona fase hauria de poder automatitzar l'engegada d'aplicacions que necessito (fluidsynth, alsa,...) (això ja ho tenia fet). També seria bo poder escollir el soundfont (metrònom, original lilypond, playback)
hi ha un projecte similar d'aquell que feia una cosa similar per aprendre el piano...: http://pianobooster.sourceforge.net/
update desembre 2011
events midi: poden ser Note ON, Note Off. He de mirar el número total d'events. Cada event (per exemple un Note On) té dues qualitats a avaluar: la nota i el timing.
Jo sé que vindrà un event perquè l'aplicació retrassa 1 segon el tocar les notes. Per tant, jo les notes les espero (sé quina nota sonarà i en quin moment). Poden passar vàries coses:
a) Notes correctes: mirem el timing
- la nota està bé però m'avanço molt -> 0
- la nota està bé però m'avanço poc -> 0,5
- la nota està bé però m'avanço molt poc-> 1
- la nota està bé però em retrasso molt poc -> 1
- la nota està bé però em retrasso poc -> 0.5
- la nota està bé però em retraasso molt ->0
b)Notes que falten -> 0
quan una nota no la faig es considera el mateix que avançar-se o retrassar-se molt.
c) Notes afegides: han de computar d'alguna manera negativament
d) Notes equivocades (substituïdes): és una nota afegida (que computa negativament) + nota que falta (0 en l'event corresponent)
Per tant, la nota principal vindrà de posar una nota als events que tenim, i modificarem aquesta nota amb els events afegits.
He de definir dos delta_times per controlar si m'avanço molt o poc (i si em retrasso molt o poc). Però això no treu que en pugui definir més delta_times intermitjos.
Aproximació per ficar una nota:
nota1 = (sumatori(nota_event))*100/num_events notes afegides: nota2 = [(num_notes_afegides * 100)/num_events] * factor el factor dependrà del número de notes totals nota=nota1-nota2
ex: suposem que hi ha 1000 events, i tots els events els faig bé, però afegeixo sense voler notes equivocades. Si considero que cada 50 notes és un punt menys
1=50*100/1000 * factor; factor=0.2
play_fine -f fitxer.midi play_fine -f peter_wolf.midi -c2 -u -p5 -t -v -w peter_wolf.txt -f fitxer.midi: fitxer smf (obligatori) -c (--channel_lead): canal on està la melodia del SMF (1-16) (opcional, per defecte.-c 1) -l (--lead): sona la melodia del SMF (per defecte no sona la melodia, és una aplicació de play-along) -p (--playalong_channel): canal per on sona el controlador (1-16) (<>10) (per defecte, -p 16) -i --instrument: es pot definir el programa amb què sona el controlador. S'envia un event program change. És el número del programa, però també es pot enviar text sempre i quan hi hagi una taula GM per comparar l'instrument amb el número del programa, i el soundfont que hagi carregat sigui compatible GM. -> NO CAL. És el controlador el que ha de definir l'instrument, no? Per exemple, en el jack-keyboard defineixo el programa, i en el Axiom 25 també. -m (--mode). Paràmetre molt important: -m 0: valor per defecte.m Sona el que toco pel controlador -m 1: sona el midi: no fa cas al controlador -m 2: mode playfine. L'objectiu és eliminar les errades de la interpretació musical de la peça, assegurant-nos que el que sona sona bé. Els events correctes (inclòs un marge definit en l'aplicació) es fan sonar, però els incorrectes es substitueixen per l'equivalent correcte del SMF. Puc treballar en qualsevol mode, però al final sempre em dóna la nota. -t (--tick) metrònom. jplayfine utilitza klick com a metrònom per defecte. klick s'executa en el script d'inici. El que fa jplayfine és connectar o desconnectar klick a la ports físics d'àudio. jplayfine ha de funcionar com a Time Master, i klick seguirà el time master. -v, -vv verbose o molt verbose -w log.txt. Registra els resultats en un format que pot ser útil per portar unes estadístiques: fitxer.midi;data;nota. -g (--gain). Gain. És el gain/mixer del controlador respecte el SMF. Per exemple, un valor de 1.2 significa que el volum del controlador es multiplica per 1.2, i el volum del SMF es divideix per 1.2. Típicament pot agafar valors entre 0.8 i 1.2.
Desenvolupament
ús del metrònom
Les possibilitats d'utilitzar klic amb jPlayfine estan explicades a:
La idea bàsica és utilitzar jPlayfine com a Time Master (tindrà l'obligació d'enterar-se del tempo i el ritme que vénen del SMF), i klick senzillament seguirà el jPlayfine.
ToDo
- connexió de klick amb system:playback. Des de l'aplicació s'ha de poden connectar/desconnectar programàticament el klick i el system (que soni o no el metrònom). Recordem que la idea és que la meva aplicació és el master del temps, i que el metrònom el segueix. Segurament és millor incloure aquesta funcionalitat en un procediment apart (en comptes de reutilitzar el proc connect2clients, doncs està orientat a midi en comptes d'audio, i a connectar un port en comptes de dos: la funcionalitat és massa diferent).
- fer que jPlayFine sigui màster del temps.
- utilitzar llistes en comptes de cues? El problema de les queues és que només puc accedir al valor que li toca. Però si per exemple jo toco abans de temps, m'interessa comparar aquest valor amb un que no serà el primer de la cua. He d'entrar a fer comparacions a dins de la cua, i per tant és millor utilitzar llistes enllaçades (és això el que necessito?)