Dati MIDI in Java Lezione 19 Programmazione MIDI (Prof. Luca A. Ludovico)
Introduzione Obiettivi conseguiti: Ripasso/acquisizione delle basi sintattiche di Java Rudimenti della programmazione a oggetti Esempi orientati al MIDI (senza usare e usando il package javax.sound.midi) Nuovo obiettivo: comprendere la logica di descrizione di dati e dispositivi MIDI da parte del package Un tutorial completo si trova nella documentazione ufficiale in lingua inglese: http://docs.oracle.com/javase/tutorial/sound/overview-MIDI.html Programmazione MIDI (Prof. Luca A. Ludovico) 19. Dati MIDI in Java
VECTOR Strutture dati dinamiche Programmazione MIDI (Prof. Luca A. Ludovico) 19. Dati MIDI in Java
Strutture dati dinamiche I tipi primitivi (int, char, …) e i tipi strutturati (array) visti finora hanno dimensioni predefinite Nel caso degli array, nella dichiarazione è necessario: stabilire il tipo base per gli elementi del vettore stabilire il numero di elementi complessivi Una volta fissati questi aspetti, non possono più essere modificati Esistono invece strutture dati dinamiche, le cui dimensioni possono variare «dinamicamente» a seconda delle esigenze Programmazione MIDI (Prof. Luca A. Ludovico) 19. Dati MIDI in Java
La classe public class Vector<E> La classe Vector<E> implementa un array di dimensioni variabili. Ai suoi elementi si accede tramite indice, come negli array non ridimensionabili Richiede: import java.util.Vector; Costruttori: Vector() Vector(Collection<? extends E> c) costruisce un vettore che contiene gli elementi della collezione specificata, nel loro ordine originario Vector(int initialCapacity) Vector(int initialCapacity, int capacityIncrement) Programmazione MIDI (Prof. Luca A. Ludovico) 19. Dati MIDI in Java
Aggiunta, inserimento e ricerca di elementi public boolean add(E e) aggiunge l’elemento e in coda al vettore public E set(int index, E element) rimpiazza l’elemento all’indice specificato con element public E get(int index) public E elementAt(int index) restituiscono l’elemento alla posizione specificata public int indexOf(Object o) public int indexOf(Object o, int index) public int lastIndexOf(Object o) restituiscono l’indice corrispondente rispettivamente alla prima occorrenza, alla prima occorrenza a partire da un dato indice e all’ultima occorrenza dell’oggetto o, oppure -1 se l’oggetto non viene trovato Programmazione MIDI (Prof. Luca A. Ludovico) 19. Dati MIDI in Java
Rimozione di elementi public void clear() public void removeAllElements() rimuovono tutti gli elementi del vettore e ne impostano la dimensione a 0 public E remove(int index) public void removeElementAt(int index) rimuovono l’elemento all’indice dato public boolean remove(Object o) public boolean removeElement(Object o) rimuove la prima occorrenza dell’oggetto o protected void removeRange(int fromIndex, int toIndex) rimuove tutti gli elementi il cui indice sta tra fromIndex (incluso) e toIndex (escluso) Programmazione MIDI (Prof. Luca A. Ludovico) 19. Dati MIDI in Java
Metodi per il dimensionamento di un Vector public void trimToSize() riduce la capacità del vettore a quella corrente, minimizzando l’occupazione di spazio in memoria public void ensureCapacity(int minCapacity) incrementa se necessario la capacità per supportare il numero minimo di elementi specificato public void setSize(int newSize) imposta le dimensioni del vettore: se superiori a quelle attuali il vettore viene riempito alla fine di elementi null, se inferiori si scartano gli elementi in eccesso public int capacity() restituisce la capacità corrente del vettore (cioè la lunghezza dell’array di dati, indipendentemente dal suo effettivo riempimento) public int size() restituisce il numero di elementi del vettore public boolean isEmpty() verifica se il vettore non abbia elementi Programmazione MIDI (Prof. Luca A. Ludovico) 19. Dati MIDI in Java
Size e capacity Istanza di un nuovo Vector size = 0, capacity = 10 Dopo due operazioni di add size = 2, capacity = 10 Dopo un’operazione di trimToSize size = 2, capacity = 2 Ab Ki Ab Ki EsempioVector.java MIDIPitchArray2.java Programmazione MIDI (Prof. Luca A. Ludovico) 19. Dati MIDI in Java
Dati midi Rappresentazione dei Programmazione MIDI (Prof. Luca A. Ludovico) 19. Dati MIDI in Java
Messaggi MIDI La classe MidiMessage è astratta e fornisce una descrizione “generica” dei messaggi MIDI. Ha tre sottoclassi: ShortMessage (vedi lezione precedente) SysexMessage per i System Exclusive MetaMessage per i metaeventi, ossia eventi generalmente utili per i sequencer ma insignificanti per i sintetizzatori Le tre sottoclassi ereditano da (e rendono concreta) la classe MidiMessage. Programmazione MIDI (Prof. Luca A. Ludovico) 19. Dati MIDI in Java
MetaMessage Costruttori public MetaMessage() public MetaMessage(int type, byte[] data, int length) throws InvalidMidiDataException I contenuti del messaggio si possono impostare anche con il metodo setMessage Parametri: type – il tipo di metamessaggio (deve essere < 128) data – i byte di dati length – il numero di byte nell’array di dati (deve essere non negativo e ≤ data.length) Programmazione MIDI (Prof. Luca A. Ludovico) 19. Dati MIDI in Java
Eventi MIDI Gli standard MIDI file contengono eventi temporizzati. La classe MidiEvent rappresenta questo tipo di informazione, cioè un messaggio nella forma in cui sarebbe memorizzato in uno standard MIDI file La classe presenta metodi per impostare e leggere il valore della temporizzazione dell’evento E’ inoltre possibile ottenere il messaggio MIDI “grezzo”, istanza di una delle sottoclassi di MidiMessage Programmazione MIDI (Prof. Luca A. Ludovico) 19. Dati MIDI in Java
Sequenze e tracce Negli SMF gli eventi sono disposti in trace. La strutturazione Java prevede le seguenti entità: Sequence Track MidiEvent ove la sequenza (istanza di) Sequence è una collezione di tracce (istanze di) Track, e una traccia è una collezione di eventi (istanze di) MidiEvent. Attenzione: non si tratta di una gerarchia tra classi! Difatti le tre classi ereditano direttamente da java.lang.Object. Programmazione MIDI (Prof. Luca A. Ludovico) 19. Dati MIDI in Java
Sequenze, tracce, eventi e messaggi Livello 3 Livello 2 Livello 1 Sequence Track MidiEvent Ogni evento MidiEvent è definito da {ShortMessage | SysExMessage | MetaMessage} + temporizzazione Programmazione MIDI (Prof. Luca A. Ludovico) 19. Dati MIDI in Java
Sequenze e tracce Le sequenze, ossia le istanze della classe Sequence, possono essere: lette dai file MIDI create da zero editate aggiungendo o rimuovendo tracce Le tracce rappresentano il livello intermedio della gerarchia a 3 livelli, posizionandosi tra le sequenze che un sequencer può gestire e gli eventi MIDI Analogamente gli eventi MIDI, ossia le istanze della classe MidiEvent, possono essere aggiunti o rimossi dalle tracce di una data sequenza Programmazione MIDI (Prof. Luca A. Ludovico) 19. Dati MIDI in Java
Istanziare una sequenza Come si istanzia una sequenza? Costruttori: public Sequence(float divisionType, int resolution) Public Sequence(float divisionType, int resolution, int numTracks) Possibili valori per divisionType, in accordo con SMF: PPQ, SMPTE_24, SMPTE_25, SMPTE_30, SMPTE_30DROP La risoluzione temporale esprime i tick per beat Per conoscere la temporizzazione assoluta, è necessario il BPM (default = 120) Programmazione MIDI (Prof. Luca A. Ludovico) 19. Dati MIDI in Java
Istanziare una traccia Come si istanzia una traccia? Track miaTraccia = new Track(); dà errore!!! Non è possibile definirla al di fuori di una sequenza, in quanto questa ne determina la temporizzazione e la risoluzione temporale. E’ dunque necessario invocare il metodo Sequence.createTrack() Programmazione MIDI (Prof. Luca A. Ludovico) 19. Dati MIDI in Java
Aggiunta e rimozione di eventi MIDI public class Track extends Object boolean add(MidiEvent event) MidiEvent get(int index) boolean remove(MidiEvent event) int size() restituisce il numero di eventi nella traccia long ticks() restituisce la lunghezza della traccia in MIDI ticks EsempioSequenze.java Programmazione MIDI (Prof. Luca A. Ludovico) 19. Dati MIDI in Java
Far suonare le sequenze La prossima lezione sarà dedicata alla rappresentazione dei dispositivi MIDI, tra cui sequencer e sintetizzatori Al momento: Sequencer mioSeq = MidiSystem.getSequencer(); mioSeq.open(); mioSeq.setSequence(sequence); mioSeq.start(); … mioSeq.stop(); // da richiamare in risposta a un’azione dell’utente CreateSequence.java Programmazione MIDI (Prof. Luca A. Ludovico) 19. Dati MIDI in Java