O Pacote Java MIDI. Roteiro Principais Classes e Interfaces do Pacote MIDI Acessando Recursos MIDI Carregando Seqüências MIDI Transmitindo e Recebendo.

Slides:



Advertisements
Apresentações semelhantes
TIPOS ABSTRATOS DE DADOS
Advertisements

Python: Entrada e Saída
I/O Carlos Bazilio Depto de Ciência e Tecnologia
Objetos Implícitos Contextuais
Comunicação entre processos distribuídos
Sistemas de Informação Redes de Computadores
Padrão de Projeto Iterator
Streams Java.
Endereçamento de hardware e identificação de quadros
Banco de Dados Oracle AESO.
9 Controle de fluxo Seqüenciadores. Jumps. Escapes. Exceções.
Classes e objetos P. O. O. Prof. Grace.
Estrutura de Dados em Java
Capítulo 10 Strings & File I/O. Strings Strings são um conjunto de Caracteres ASCII. No Controle de Instrumentação pode-se converter valores numéricos.
Como instalar e executar o programa
Sistemas Operacionais I
JAVA: Conceitos Iniciais
Classes, Objetos e Encapsulamento
Polimorfismo em C#.
Aula prática 13 Orientação a Objetos – C++ Parte 1
Streams –input e output
Laboratório de Programação I Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação.
Web Services Uninorte Semana de Tecnologia da Informação
Rodrigo Cristiano Silva
Chamada Remota de Procedimentos
Aula Prática 12 Operações com Arquivos Monitoria
Linguagem de Programação JAVA
Instalação  A tela abaixo é a primeira a aparecer durante a instalação do Caché 5. O diretório selecionado será usado para salvar alguns arquivos usados.
Computação Musical e Processamento de Som – 06.1
O Pacote Java MIDI.
General MIDI Arquivos MIDI Standard
Conteúdo Processos e threads Partes do processo
Pilhas Profa. Nádia Félix.
Programação Orientada à Objetos
Prof. Roberto Rosa Aula 8.  A partir de agora vamos aprender como ver qual é o erro que está acontecendo em nosso projeto. Para.
Aulas 2 e 3 – Java – Prof. Marcelo Heitor # O método main e argumentos na linha de comando; # Fluxo padrão de entrada e saída; # A classe JOptionPane;
Concorrência e thread Petrônio Júnior(pglj) Márcio Neves(mmn2)
Sistemas Operacionais
Profa. Patrícia A. Jaques
CONPROVE INDÚSTRIA & COMÉRCIO SIMULADOR IEC - GOOSE GOOSE Simulator.
Tratamento de Exceções
Programação para Web Unidade 06 – Java Beans e BDs Prof.: Henrique Santos.
Interfaces POO Avançado.
Estrutura de Controle em JAVA
Exceções Suzana Fragoso (smpf) Adaptado do material de Guilherme Carvalho (gvc)
Laboratório de Programação
Operações com Arquivos Monitoria A estrutura FILE  É como um tipo de dado, mas não é um tipo propriamente dito  Definido no arquivo cabeçalho.
Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8 th Edition Capítulo 10: Interface de Sistemas de Arquivos.
Aula Prática 11 Operações com Arquivos Monitoria
Diagrama de Colaboração. Diagramas de Interação Expressam informações bastante similares porém de maneira diferente Diagrama de seqüência: – Interação.
Coleções em Java - Parte 2
Aglets.
Copyright 1998, Departamento de Informática da UFPE. Todos os direitos reservados sob a legislação em vigor. Variáveis e métodos estáticos, Passagem de.
Socket em Java.
Tarciane Andrade Análise de Casos de Uso Tarciane Andrade
POO - I PROF.: JEAN CARLO MENDES
RMI Remote Method Invocation
Orientação a Objetos e Java Graduação em Ciência da Computação  Centro de Informática, UFPE Alexandre Mota
© Copyright 2008 Algoritmos e Estruturas de Dados 1 IF672 - Algoritmos e Estruturas de Dados CIn - UFPE Adriana Libório Fernandes Lins Arthur Cavalcanti.
Array e ArrayList LPOO – 01/09/14.
Capítulo 15 – Tratamento de Exceções
Desenvolvimento WEB II Professora: Kelly de Paula Cunha.
Redes de Computadores Prof. Msc. Moisés Pereira Bastos.
CURSO JAVA BÁSICO Módulo 9 – slide 1 Módulo 10 Threads.
Prof. Ivair Teixeira Redes de Computadores.
SOCKET - É um canal de comunicação entre processos que estabelece uma conexão entre eles na forma de cliente-servidor. Por meio de sockets, os computadores.
Questionário (Básico) Autor: Skyup Informática. Atividade - Questionário O módulo permite criar uma série de questões, que deverão ser respondida pelos.
Strings e Arrays Prof. Gustavo Wagner (Alterações) Prof. Tiago Massoni (Slides Originais) Desenvolvimento de Sistemas FATEC-PB  Centro de Informática,
ProgramaçãoConcorrente Glêdson Elias
Linguagem de Programação – Aula 04 Prof. Me. Ronnison Reges Vidal.
Transcrição da apresentação:

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 é uma classe abstrata que representa uma mensagem MIDI pura; Possui três 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 arquivos MIDI, contem, por exemplo, configurações de tempo;

Classe MidiEvent MidiEvent é uma classe que engloba mensagens MIDI puras junto com informação de tempo; A classe MidiEvent possui métodos para especificar e também obter informação de timestamp: long getTick () void setTick (long tick)

Classe Sequence Sequence representa uma 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 Objetos que implementem a interface MidiDevice são capazes de enviar e receber mensagens MIDI; Possui métodos para abrir e fechar um dispositivo; Inclui uma classe interna, MidiDevice.Info, que fornece uma descrição textual do dispositivo;

Interfaces Transmitter e Receiver Dispositivos MIDI possuem objetos transmissores e objetos receptores; Objetos transmissores implementam a interface Transmitter e objetos receptores implementam a interface Receiver ;

Interface Sequencer Um sequenciador é um dispositivo para captura e execução de seqüências de eventos MIDI; Normalmente, possui tanto transmissores quanto receptores; Sequenciadores implementam a interface Sequencer que é uma subinterface de MidiDevice ;

Interface Synthesizer Sintetizadores implementam a interface Synthesizer (subinterface de MidiDevice ); Um sintetizador possui canais, representados por objetos que implementem a interface MidiChannel ; Normalmente um sintetizador gera sons em resposta a mensagens enviadas aos seus receptores;

Acessando Recursos MIDI

Classe MidiSystem Assim como a classe AudioSystem, permite descobrir e acessar os dispositivos instalados no sistema; 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.); A classe MidiSystem inclui métodos para obter dispositivos padrão: static Sequencer getSequencer (); static Synthesizer getSynthesizer (); static Receiver getReceiver (); static Transmitter getTransmitter ();

Obtendo Dispositivos Instalados A classe MidiSystem possui um método para obter informações sobre os dispositivos instalados: static MidiDevice.Info[] getMidiDeviceInfo () Para obter um dispositivo deve-se utilizar o método: static MidiDevice getMidiDevice (MidiDevice.Info info)

Exemplo 1: Obtendo os sintetizadores instalados Vector synthInfo; MidiDevice device; MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo (); for (int i = 0; i < infos.length; i++) { try { device = MidiSystem.getMidiDevice (infos[i]); } catch (MidiUnavailableException e) { // tratar ou throw a exceção } if (device instanceof Synthesizer) { synthInfos.add (infos[i]); }

Abrindo Dispositivos Para reservar um dispositivo : método open() da interface MidiDevice : if (!device.isOpen ()) { try { device.open (); } catch (MidiUnavailableException e) { // tratar ou throw a exceção }

Carregando Seqüências MIDI

Carregando um Arquivo MIDI Duas maneiras: Carregar um arquivo MIDI em um InputStream e depois usar: Sequencer.setSequence (InputStream stream) Criar, explicitamente, um objeto Sequence e depois carregá-lo em um Sequencer (Necessário quando se deseja editar uma seqüência MIDI)

Exemplo 2: 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 possibilitando que dados fluam entre eles; MidiDevice possui um ou mais objetos auxiliares que implementam as interfaces Transmitter ou Receiver ; Cada transmissor só pode ser conectado a um receptor e vice-versa;

Conectando-se a um Dispositivo A interface Transmitter possui um método que permite estabelecer a conexão com o Receiver para o qual serão enviadas as mensagens: 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;

Exemplo 2: Conectando um Sequenciador a um Sintetizador Sequencer seq; Transmitter seqTrans; Synthesizer synth; Receiver synthRcvr; try { seq = MidiSystem.getSequencer (); seqTrans = seq.getTransmitter (); synth = MidiSystem.getSynthesizer (); synthRcvr = synth.getReceiver (); seqTrans.setReceiver (synthRcvr); } catch (MidiUnavailableException e) { // tratar ou throw a exceção }

Exercício 1 Abrir e tocar um arquivo MIDI;

Como enviar a mesma mensagem para diferentes dispositivos ? Basta usar 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 3: Conectando um Porta de Entrada a um Sequenciador e a um Sintetizador Sequencer seq; Synthesizer synth; MidiDevice inputPort; // Obter e abrir os três dispositivos Transmitter 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 }

Quando Usar um Sequenciador É possível enviar mensagens MIDI diretamente para um dispositivo sem usar um sequenciador; Essa técnica pode ser utilizada quando o próprio programa cria as mensagens em tempo real; Ex.: Programa que simula um piano Sequenciadores são utilizados para lidar com dados lidos de um arquivo MIDI e também para gravar dados MIDI;

Enviando Mensagem para um Receptor sem Usar um Transmissor A interface 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 4: Enviando uma Mensagem sem Usar um Transmissor ShortMessage msg = new ShortMessage (); // Tocar a nota Middle C (60) com velocidade = 93 msg.setMessage (ShortMessage.NOTE_ON, 0, 60, 93); long timeStamp = -1; Receiver rcvr = MidiSystem.getReceiver (); Rcvr.send (msg, timeStamp);

Exercício 2 Enviar mensagens MIDI diretamente para um sintetizador sem usar um Sequenciador

Roteiro Principais Classes e Interfaces do Pacote MIDI Principais Classes e Interfaces do Pacote MIDI Acessando Recursos MIDI Acessando Recursos MIDI Carregando Seqüências MIDI Carregando Seqüências MIDI Transmitindo e Recebendo Mensagens MIDI Transmitindo 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 contem as notas de um único instrumento (não é obrigado pelo padrão); 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 tendo como base o conceito de tick; A duração de um tick varia de acordo com a sequência MIDI e seu valor é armazenado no cabeçalho de um arquivo MIDI; O tamanho de um tick pode ser dado em duas unidades: Pulsos por quarto de nota (PPQ) Ticks por frame (SMPTE) 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 o objeto Sequence criado com o Sequencer usado: 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 ; Os métodos de Track são: boolean add (MidiEvent event) MidiEvent get (int index) boolean remove (MidiEvent event) int size () long ticks ()

Exercício 3 Criar alguns eventos MIDI, com mensagens Note On e Note Off, e gravá-los em um SMF (Usar PPQ com, por exemplo, resolução 12;

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 tempo; Pode-se mudar o tempo 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)

Sincronizando com Outros Dispositivos Sequencer possui uma classe interna Sequencer.SyncMode que representa os modos como um Sequencer pode ser sincronizado; Um Sequencer pode ser sincronizado como Master e/ou Slave: void setMasterSyncMode (Sequencer.SyncMode sync) void setSlaveSyncMode (Sequencer.SyncMode sync)

Listeners par Eventos Especiais Especificando Listeners para eventos especiais: Int[] addControllerEventListener (ControllerEventListener listener, int[] controllers) Boolean addMetaEventListener (MetaEventListener listener)

Exercício 4 Alterar o tocador MIDI de modo que seja possível executar Mute e Solo em Tracks especificas;

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 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: Como já foi visto, pode-se enviar uma mensagem diretamente a um receptor do sintetizador através do método send (); Outra opção seria interagir diretamente com objetos MidiChannel ;

Exemplo 6: Exemplo 4 Usando Canais Synthesizer synth = MidiSystem.getSynthesizer (); // Obtem todos os canais do sintetizador MidiChannel chan[] = synth.getChannels (); // Checa se o canal existe if (chan[4] != null) { chan[4].noteOn (60, 93); }

Mute e Solo em Canais A API Java Sound adiciona a noção de Solo e Mute por canais; Essa operação é similar as de Mute e Solo para Tracks; São fornecidos quatro métodos: boolean getMute () boolean getSolo () void setMute (boolean muteState) void setSolo (boolean soloState)

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) OBS.: Instrumento deve estar carregado no sintetizador !

Exercício 5 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;