o pacote java midi. roteiro principais classes e interfaces do pacote midi acessando recursos midi...

Click here to load reader

Post on 07-Apr-2016

230 views

Category:

Documents

8 download

Embed Size (px)

TRANSCRIPT

  • O Pacote Java MIDI

  • RoteiroPrincipais Classes e Interfaces do Pacote MIDI

    Acessando Recursos MIDI

    Carregando Seqncias MIDI

    Transmitindo e Recebendo Mensagens MIDI

    Gravando e Editando Seqncias MIDI

    Recursos Avanados de Sequencer

    Sintetizando Som

  • Principais Classes e Interfaces do Pacote MIDI

  • Classe MidiMessageMidiMessage uma classe abstrata que representa uma mensagem MIDI pura;

    Possui trs subclasses:ShortMessages : tipo mais comum, possui um byte de status e no mximo dois de dados (Ex.: Note On);

    SysexMessages: podem possuir muito bytes e contm instrues especificas do fabricante;

    MetaMessages: ocorre apenas em arquivos MIDI, contem, por exemplo, configuraes de tempo;

  • Classe MidiEvent

    MidiEvent uma classe que engloba mensagens MIDI puras junto com informao de tempo;

    A classe MidiEvent possui mtodos para especificar e tambm obter informao de timestamp:long getTick () void setTick (long tick)

  • Classe Sequence

    Sequence representa uma composio musical que pode ser lida de um arquivo ou criada em tempo real;

    composto por uma coleo de Tracks onde esto armazenados os MidiEvents;

  • Interface MidiDevice

    Objetos que implementem a interface MidiDevice so capazes de enviar e receber mensagens MIDI;

    Possui mtodos para abrir e fechar um dispositivo;

    Inclui uma classe interna, MidiDevice.Info, que fornece uma descrio 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 SequencerUm sequenciador um dispositivo para captura e execuo de seqncias de eventos MIDI;

    Normalmente, possui tanto transmissores quanto receptores;

    Sequenciadores implementam a interface Sequencer que uma subinterface de MidiDevice;

  • Interface SynthesizerSintetizadores 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 MidiSystemAssim 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 Padres

    Uma aplicao tpica inicia obtendo os dispositivos necessrios (sequenciadores, sintetizadores, etc.);

    A classe MidiSystem inclui mtodos para obter dispositivos padro:static Sequencer getSequencer ();static Synthesizer getSynthesizer ();static Receiver getReceiver ();static Transmitter getTransmitter ();

  • Obtendo Dispositivos Instalados

    A classe MidiSystem possui um mtodo para obter informaes sobre os dispositivos instalados:static MidiDevice.Info[] getMidiDeviceInfo ()

    Para obter um dispositivo deve-se utilizar o mtodo: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 exceo}if (device instanceof Synthesizer) {synthInfos.add (infos[i]);}}

  • Abrindo Dispositivos

    Para reservar um dispositivo : mtodo open() da interface MidiDevice:

    if (!device.isOpen ()) {try { device.open ();} catch (MidiUnavailableException e) { // tratar ou throw a exceo}}

  • Carregando Seqncias MIDI

  • Carregando um Arquivo MIDIDuas 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 (Necessrio quando se deseja editar uma seqncia 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 exceo}

  • 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 mtodo que permite estabelecer a conexo com o Receiver para o qual sero enviadas as mensagens:void setReceiver (Receiver receiver)

    Aps terminada a conexo deve-se invocar o mtodo 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 exceo}

  • Exerccio 1Abrir 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 mtodos 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 SintetizadorSequencer seq;Synthesizer synth;MidiDevice inputPort;// Obter e abrir os trs 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 exceo}

  • Quando Usar um Sequenciador possvel enviar mensagens MIDI diretamente para um dispositivo sem usar um sequenciador;

    Essa tcnica pode ser utilizada quando o prprio programa cria as mensagens em tempo real;Ex.: Programa que simula um piano

    Sequenciadores so utilizados para lidar com dados lidos de um arquivo MIDI e tambm para gravar dados MIDI;

  • Enviando Mensagem para um Receptor sem Usar um Transmissor

    A interface Receiver contm um mtodo que envia mensagens para o receptor:void send (MidiMessage message, long timeStamp)

    Criar um objeto ShortMessage e usar o mtodo: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);

  • Exerccio 2Enviar mensagens MIDI diretamente para um sintetizador sem usar um Sequenciador

  • RoteiroPrincipais Classes e Interfaces do Pacote MIDI

    Acessando Recursos MIDI

    Carregando Seqncias MIDI

    Transmitindo e Recebendo Mensagens MIDI

    Gravando e Editando Seqncias MIDI

    Recursos Avanados de Sequencer

    Sintetizando Som

  • Gravando e Editando Seqncias MIDI

  • TracksArquivos MIDI so organizados em tracks;

    Normalmente cada track contem as notas de um nico instrumento (no obrigado pelo padro);

    Arquivos MIDI so organizados em uma hierarquia de trs nveis:Sequence;Track;MidiEvents;

  • MidiEvents e Ticks

    Em um MidiEvent o tempo expresso tendo como base o conceito de tick;

    A durao de um tick varia de acordo com a sequncia MIDI e seu valor armazenado no cabealho 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)Obtenha um Sequencer atravs de MidiSystem;

    Estabelea a conexo entre o Sequencer e o objeto que transmitir as mensagens MIDI;

    Crie um novo objeto Sequence:Sequence (floatdivisionType, intresolution )Sequence (floatdivisionType, intresolution, intnumTracks )

    Crie um objeto Track caso isso no seja feito no construtor:Sequence.createTrack();

  • Gravando e Salvando Sequences (2/2)Relacione o objeto Sequence criado com o Sequencer usado:Sequencer.setSequence(Sequence sequence)

    Chame o mtodo Sequencer.recordEnable ();

    Chame o mtodo Sequence.startRecording ();

    Quando terminar, chame Sequencer.stop () ou Sequencer.stopRecording ();

    Salve o objeto Sequence gravado usando MididSystem.write();

  • Editando uma Seqncia

    Objetos do tipo Sequence permitem que sejam adicionados ou removidos Tracks:Track createTrack ()Boolean deleteTrack (Track track)

    As Tracks so armazenadas em um objeto Sequence atravs de um Vector;

  • Editando uma Seqncia

    Os MidiEvents contidos em uma Track tambm so armazenados em um Vector;

    Os mtodos de Track so:boolean add (MidiEvent event)MidiEvent get (int index)boolean remove (MidiEvent event)int size ()long ticks ()

  • Exerccio 3Criar alguns eventos MIDI, com mensagens Note On e Note Off, e grav-los em um SMF (Usar PPQ com, por exemplo, resoluo 12;

  • Recursos Avanados de Sequencer

  • Posio de uma Sequence

    Obtendo a posio corrente do Sequencer em um Sequence:Long getTickPosition ()Long getMicrosecondPosition ()

    Movendo para um ponto arbitrrio em um objeto Sequence:void setTickPosition (long Tick)void setMicrosecondPosition (long microsecond)

  • Mudando a Velocidade de Execuo

    A velocidade de uma seqncia indicada pelo seu tempo;

    Pode-se mudar o tempo de uma seqncia atravs de eventos MIDI ou atravs da chamada de mtodos de Sequencer:void setTempoInBPM (float bpm)void setTempoInMPQ (float mpq)void setTempoFactor (float factor)

  • Mute e Solo em Tracks

    Pode-se escolher que Tracks iro 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 EspeciaisEspecificando Listeners para eventos especiais:

    Int[] addControllerEventListener (ControllerEventListener listener, int[] controllers)

    Boolean addMetaEventListener (MetaEventListener listener)

  • Exerccio 4Alterar o tocador MIDI de modo que seja possvel executar Mute e Solo em Tracks especificas;

  • Sintetizando Som

  • A Sntese de Sons em JavaA arquitetura para sntese de sons em Java composta de trs interfacesSynthesizerMidiChannelSoundbank

    E quatro classes:InstrumentPatchSoundbankResourceVoiceStatus

  • Verificando Quais Instrumentos Esto Carregados

    Para carregar o Soundbank padro deve-se usar o seguinte mtodo de Synthesizer:

    Soundbank getDefaultSoundbank ()

    Para descobrir quais instrumentos esto atualmente carregados deve-se usar o seguinte mtodo de Synthesizer:

    Instrument[] getLoadedInstruments()

  • Carregando InstrumentosPara descobrir quais instrumentos pertencem ao Sintetizador:Instrument[] getAvailableInstruments ()

    Um instrumento pode ser carregado usando:boolean loadInstrument (Intrument instrument)

    O instrumento ser carregado na posio 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 nmero do banco e nmero do programa;

    possvel carregar o instrumento em um outro local atravs do seguinte mtodo de Synthesizer:

    boolean remapIntrument (Intrument from, Instrument to)

  • Descarregando Instrumentos

    Existem trs mtodos para descarregar instrumentos:

    void unloadAllInstruments (Soundbanksoundbank)

    void unloadInstrument(Instrumentinstrument)

    void unloadInstruments(Soundbanksoundbank, Patch[]patchList)

  • Acessando CanaisExistem 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 atravs do mtodo send ();

    Outra opo seria interagir diretamente com objetos MidiChannel;

  • Exemplo 6: Exemplo 4 Usando Canais

    Synthesizer synth = MidiSystem.getSynthesizer ();// Obtem todos os canais do sintetizadorMidiChannel chan[] = synth.getChannels ();

    // Checa se o canal existeif (chan[4] != null) {chan[4].noteOn (60, 93);}

  • Mute e Solo em CanaisA API Java Sound adiciona a noo de Solo e Mute por canais;

    Essa operao similar as de Mute e Solo para Tracks;

    So fornecidos quatro mtodos: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 !

  • Exerccio 5Enviar mensagens Note On e Note Off diretamente para o canal de um sintetizador (sem usar MidiMessages). Permitir tambm a mudana de Instrumentos;