o pacote java midi. roteiro principais classes e interfaces do pacote midi acessando recursos midi...
TRANSCRIPT
O Pacote Java MIDI
Roteiro Principais Classes e Interfaces do Pacote MIDI
Acessando Recursos MIDI
Carregando Seqüências MIDI
Transmitindo e Recebendo Mensagens MIDI
Gravando e Editando Seqüências MIDI
Recursos Avançados de Sequencer
Sintetizando Som
Principais Classes e Interfaces do Pacote MIDI
Classe MidiMessage MidiMessage
classe abstrata que representa uma mensagem MIDI pura
3 subclasses: ShortMessages : tipo mais comum, possui um byte de
status e no máximo dois de dados (Ex.: Note On) SysexMessages: podem possuir muito bytes e contém
instruções especificas do fabricante MetaMessages: ocorre apenas em SMF, contem, por
exemplo, letra da música
Classe MidiEvent
MidiEvent Mensagens MIDI + momento em que
ocorre Métodos para especificar e
também obter informação de tempo: long getTick () void setTick (long tick)
Classe Sequence Sequence
Composição musical que pode ser lida de um arquivo ou criada em tempo real
É composto por uma coleção de Tracks onde estão armazenados os MidiEvents
Sequence
Tracks
MidiEvents
Interface MidiDevice São capazes de enviar e receber
mensagens MIDI Métodos para reservar (open) e liberar
(close) o uso do dispositivo MidiDevice.Info
fornece uma descrição textual do dispositivo; Objetos transmissores implementam a
interface Transmitter e objetos receptores implementam a interface Receiver
Interface Sequencer
Dispositivo para captura e execução de seqüências de eventos MIDI Responsável por manter os dados
sincronizados Possui transmissores e receptores Sequencer é uma subinterface de MidiDevice
Interface Synthesizer
Representa o dispositivo que efetivamente produz a onda sonora
Subinterface de MidiDevice Um sintetizador possui canais
Interface MidiChannel Possui apenas receptores
Acessando Recursos MIDI
Classe MidiSystem Similar ao AudioSystem do pacote
sampled Permite obter os seguintes recursos:
Sequenciadores Sintetizadores Transmissores Receptores Dados a partir de arquivos MIDI Dados a partir de arquivos de soundbank
Obtendo Dispositivos Padrões
Uma aplicação típica inicia obtendo os dispositivos necessários (sequenciadores, sintetizadores, etc.)
Métodos para obter dispositivos padrão: static Sequencer getSequencer (); static Synthesizer getSynthesizer (); static Receiver getReceiver (); static Transmitter getTransmitter ();
Exemplo 1
Obtendo informações sobre os MidiDevices Exercício 1: Listar apenas os
Sintetizadores
Carregando Seqüências MIDI
Criando e Carregando um Objeto Sequence
try {
File midiFile = new File (“seq1.mid”);
Sequence seq = MidiSystem.getSequence (midiFile);
sequencer.setSequence (seq);
} catch (Exception e) {
// tratar ou throw a exceção
}
Transmitindo e Recebendo Mensagens MIDI
Dispositivos, Receptores e Transmissores
Diferentes MidiDevice podem ser interconectados
Um MidiDevice possui um ou mais objetos com interface Transmitter e/ou Receiver;
Cada transmissor só pode ser conectado a um receptor e vice-versa;
Conectando-se a um Dispositivo
Interface Transmitter void setReceiver (Receiver receiver)
Após terminada a conexão deve-se invocar o método close() de Transmitter e Receiver para que os mesmos sejam liberados;
Exercício 2
Abrir e tocar um arquivo MIDI
Como enviar a mesma mensagem para diferentes dispositivos ?
Usando mais de um transmissor e mais de um receptor
MidiDevice possui métodos para descobrir quantos transmissores e receptores um dispositivo suporta:
int getMaxTransmitters () int getMaxReceivers ()
Exemplo 2: Conectando uma Porta de Entrada a um Sequenciador e a um Sintetizador
Sequencer seq;Synthesizer synth;MidiDevice inputPort;// Obter e abrir os três dispositivosTransmitter inPortTrans1, inPortTrans2;Receiver synthRcvr, seqReceiver;
try {inPortTrans = inputPort.getTransmitter ();synthRcvr = synth.getReceiver ();inPortTrans1.setReceiver (synthRcvr);inPortTrans2 = inputPort.getTransmitter ();seqRcvr = seq.getReceiver (); inPortTrans2.setReceiver (seqRcvr);
} catch (MidiUnavailableException e) {// tratar ou throw a exceção
}
Enviando Mensagem para um Receptor sem Usar um Transmissor
Receiver contém um método que envia mensagens para o receptor void send (MidiMessage message, long timeStamp)
Criar um objeto ShortMessage e usar o método void setMessage (int command, int channel, int data1, int data2)
Exemplo 3:
Enviando uma Mensagem sem Usar um Transmissor
Exercício 3 FileToMIDI : Lê arquivo qualquer e toca seus
bytes como Notas Monofônico Para cada note ON, existe um note OFF
correspondente As notas tem a mesma duração
Roteiro Principais Classes e Interfaces do Pacote MIDIPrincipais Classes e Interfaces do Pacote MIDI
Acessando Recursos MIDIAcessando Recursos MIDI
Carregando Seqüências MIDICarregando Seqüências MIDI
Transmitindo e Recebendo Mensagens MIDITransmitindo e Recebendo Mensagens MIDI
Gravando e Editando Seqüências MIDI
Recursos Avançados de Sequencer
Sintetizando Som
Gravando e Editando Seqüências MIDI
Tracks Arquivos MIDI são organizados em tracks Normalmente, cada track agrupa
informações que possuem forte relação entre si Notas de determinado instrumento
Arquivos MIDI são organizados em uma hierarquia de três níveis:
Sequence Track MidiEvents
Sequence
Tracks
MidiEvents
MidiEvents e Ticks Em um MidiEvent o tempo é expresso em
ticks, que é o menor intervalo de tempo em um SMF
O tamanho de um tick é um valor relativo pode ser dado em duas unidades:
Pulsos por semínima (PPQ) Ticks por frame (SMPTE)
O valor absoluto do tick é calculado no momento do sequenciamento
Na API Java os valores de tick medem tempo cumulativo;
Gravando e Salvando Sequences (1/2)
1. Obtenha um Sequencer através de MidiSystem;
2. Estabeleça a conexão entre o Sequencer e o objeto que transmitirá as mensagens MIDI;
3. Crie um novo objeto Sequence:Sequence (float divisionType, int resolution )Sequence (float divisionType, int resolution,
int numTracks )
4. Crie um objeto Track caso isso não seja feito no construtor:
Sequence.createTrack();
Gravando e Salvando Sequences (2/2)
5. Relacione Sequence com o Sequencer usando:Sequencer.setSequence(Sequence sequence)
6. Chame o método Sequencer.recordEnable ();7. Chame o método Sequence.startRecording ();8. Quando terminar, chame Sequencer.stop () ou
Sequencer.stopRecording ();9. Salve o objeto Sequence gravado usando
MididSystem.write();
Editando uma Seqüência Objetos do tipo Sequence permitem que sejam
adicionados ou removidos Tracks: Track createTrack () Boolean deleteTrack (Track track)
As Tracks são armazenadas em um objeto Sequence através de um Vector;
Editando uma Seqüência Os MidiEvents contidos em uma Track também
são armazenados em um Vector Métodos de Track
boolean add (MidiEvent event) MidiEvent get (int index) boolean remove (MidiEvent event) int size () long ticks ()
Exercício 4 Gravar Exercício 3 em arquivo
Formato 1 120 PPQ Tick é acumulativo
Recursos Avançados de Sequencer
Posição de uma Sequence
Obtendo a posição corrente do Sequencer em um Sequence:
Long getTickPosition () Long getMicrosecondPosition ()
Movendo para um ponto arbitrário em um objeto Sequence:
void setTickPosition (long Tick) void setMicrosecondPosition (long
microsecond)
Mudando a Velocidade de Execução
A velocidade de uma seqüência é indicada pelo seu andamento (tempo)
Pode-se mudar o andamento de uma seqüência através de eventos MIDI ou através da chamada de métodos de Sequencer: void setTempoInBPM (float bpm) void setTempoInMPQ (float mpq) void setTempoFactor (float factor)
Mute e Solo em Tracks Pode-se escolher que Tracks irão contribuir
para o stream de mensagens MIDI gerados pelo Sequencer;void setTrackMute (int track, boolean mute)
void setTrackSolo (int track, boolean solo)
Para verificar o status de uma Track: boolean getTrackMute (int track) boolean getTrackSolo (int track)
Exercício 5 Adicionar código ausente no MidiPlayer
Pause e Parar Acelerar 2x Aplicar Mute e Solo em alguma track
Sintetizando Som
A Síntese de Sons em Java A arquitetura para síntese de sons em Java é
composta de três interfaces Synthesizer MidiChannel Soundbank
E quatro classes: Instrument Patch SoundbankResource VoiceStatus
Verificando Quais Instrumentos Estão Carregados Soundbank é um repositório de Instruments Instruments são classes responsáveis pela síntese do
som Além de determinar seu Patch (posição na memória do
Sintetizador) O Patch tem dois componentes: o Bank e o Program que
funcionam como índices (2 dimensões) na memória do sintetizador
Cada bank possui até 128 programs Para carregar o Soundbank padrão deve-se usar o
seguinte método de Synthesizer:Soundbank getDefaultSoundbank ()
Para descobrir quais instrumentos estão atualmente carregados deve-se usar o seguinte método de Synthesizer:Instrument[] getLoadedInstruments()
Carregando Instrumentos Para descobrir quais instrumentos pertencem
ao Sintetizador:Instrument[] getAvailableInstruments ()
Um instrumento pode ser carregado usando:boolean loadInstrument (Intrument instrument)
O instrumento será carregado na posição especificada pelo seu objeto Patch;
Carregando Instrumentos
Cada objeto do tipo Instrument possui um objeto Patch que especifica onde o instrumento deverá ser carregado;
Esse local é definido pelo número do banco e número do programa;
É possível carregar o instrumento em um outro local através do seguinte método de Synthesizer:
boolean remapIntrument (Intrument from, Instrument to)
Descarregando Instrumentos
Existem três métodos para descarregar instrumentos:
void unloadAllInstruments (Soundbank soundbank)
void unloadInstrument(Instrument instrument)
void unloadInstruments(Soundbank soundbank, Patch[] patchList)
Acessando Canais Existem 2 maneiras para controlar o
sintetizador sem usar um sequenciador: Através do seu Receiver Interagir direta com objetos MidiChannel
Alterando o Instrumento de um Canal
Para descobrir qual o instrumento atualmente alocado a um canal deve-se usar:int getProgram ()
Para modificar o instrumento associado:void programChange (int program)void programChange(int bank,int program)
OBS.: Instrumento deve estar carregado no sintetizador !
Exercício 6
Adicionar código ao programa TocaNotas para enviar mensagens Note On e Note Off diretamente para o canal de um sintetizador (sem usar MidiMessages). Permitir também a mudança de Instrumentos;