
Há um tempo atrás (especificamente 2004), publiquei um tutorial no site da comunidade do JavaFree.org, cujo título era Desenvolvendo um sequenciador MIDI com java. Agora, estudando um pouco mais o padrão de projeto Proxy, e fazendo alguns testes, vi que a api java.sound possui um recurso para desabilitar/habilitar trilhas em uma música.
Vamos ver como isso funciona?
O padrão funciona de forma a definir um objeto transparente que procure outro objeto, através de uma implementação interna. Com isso temos benefícios como desacloplamento, controle de acesso e cache, por exemplo.
Utilizaremos este padrão para executar uma música MIDI, e disponibilizar a opção de tocar as faixas da mesma separadamente. Primeiramente temos a classe que é o RealSubject da nossa pequena aplicação, ela é responsável para interação com o dispositivo MIDI do sistema operacional. Ela contém todas as funções para a execução, parada ou desabilitação das suas trilhas.
RealMidi.java
import java.io.File;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;
public class RealMidi implements IMidi {
private Sequencer sequencer;
private Sequence sequence;
public RealMidi(String arquivo) {
try {
sequencer = MidiSystem.getSequencer();
sequence = MidiSystem.getSequence(new File(arquivo));
sequencer.open();
sequencer.setSequence(sequence);
} catch (Exception e) {
e.printStackTrace();
}
}
public int getTracks(){
return sequence.getTracks().length;
}
@Override
public void enable(int numero) {
sequencer.setTrackMute(numero, !sequencer.getTrackMute(numero));
if (sequencer.getTrackMute(numero)) {
System.out.println(numero + " [OFF]");
} else {
System.out.println(numero + " [ON]");
}
}
@Override
public void start() {
sequencer.start();
}
@Override
public boolean isRunning() {
return sequencer.isRunning();
}
@Override
public void stop() {
sequencer.stop();
sequencer.close();
}
}
Percebemos que esta classe implementa uma interface, que também é implementada pela classe que será o nosso proxy.
IMidi.java
public interface IMidi {
void enable(int numero);
void start();
boolean isRunning();
void stop();
}
Temos a classe que será o proxy e que irá, além de repassar chamadas para a classe RealMidi, fazer um cache do arquivo MIDI. Isso evitará que o mesmo seja acessado diversas vezes desnecessariamente. isto pode ser verificado nas operações start, stop e isRunnig.
ProxyMidi.java
public class ProxyMidi implements IMidi{
private RealMidi realMidi;
private String arquivo;
public ProxyMidi(String arquivo) {
this.arquivo = arquivo;
}
@Override
public void enable(int numero) {
if (numero < realmidi ="=" realmidi =" new">
Agora temos um sequenciador implementado com uma função a mais, que é a de escolher as trilhas que devem ser desabilitadas. Agora é só fazer uma classe que seja o cliente do padrão.
JPlayer.java
import java.util.Scanner;
public class JPlayer {
public static void main(String[] args) {
Scanner teclado = new Scanner(System.in);
IMidi midi = new ProxyMidi("sua_musica.mid");
midi.start();
System.out.println("Informe o número da trilha para habilitar/desabilitar a saída de som:");
int numero;
while (midi.isRunning()) {
numero = teclado.nextInt();
midi.enable(numero);
}
midi.stop();
}
}
Bom, como o resultado disso não dá pra colocar aqui (só ouvindo mesmo), então fica o convite para que você mesmo teste, ok ?
Indicações:
[1] http://dofactory.com/Patterns/PatternProxy.aspx
[2] http://www.javafree.org/javabb/topic-3102-Desenvolvendo+um+sequenciador+MID+com+java
[3] http://www.midinet.com.br/ (Para quem não tem arquivos MIDI)

1 comentários:
Haw!
Só uma sugestão: coloca os códigos entre tags <pre></pre>, assim não fica com a identação zuada (se você copiar de um lugar [eclipse, netbeans, etc] que esteja identado) fica mais fácil de ler.
(exemplo aqui)
E se quiser deixar mais pro tem uns esquemas (google it!) pra syntax highlight.
Valewz!? Gostei do post.
Postar um comentário