sexta-feira, 16 de julho de 2010

Alterando o Volume e Ganho com JavaSound

Não foi incomum que algumas pessoas me perguntassem como alterar o volume de um Clip ou uma Stream de Áudio usando a API de som do Java, o JavaSound. Vamos à explicação rápida!!

  • Qual a Diferença Entre Volume e Ganho??

Muitas bibliotecas de execução e manipulação de som (especialmente as mais baixo nível) não têm controle de volume, mas sim de ganho. Ganho é a medida em deciBels (dB) que regula a intensidade do som (mais detalhes aqui). Volume é uma medida adimensional e escalar de intensidade de som.
Tudo estaria resolvido se o ganho variasse da mesma maneira que o volume, já que os dois medem, na prática, a mesma coisa. Porém, o ganho é uma medida logarítmica, ou seja, ela varia muito mais numa extremidade e muito menos na outra, dados os cálculos em exponensiais. O volume é uma interpretação desta variação, porém de maneira escalar, de forma que varie sempre da mesma forma.


  • Implementando Mudaças de Volume em JavaSound

Primeiramente, é preciso se obter o controle de ganho (MASTER_GAIN). Depois, é preciso que se transforme o valor do volume (uma simples percentagem, ou seja, um número entre 0 e 1) em deciBels, usando a fórmula logarítmica abaixo. Com este valor em deciBel, basta agora atribuí-lo ao controle de ganho.

public void setVolume(int percent) {
FloatControl gainControl =
(FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
double gain = percent/100; // deve ser entre 0 (mudo) e 1 (mais forte)
float dB = (float) (Math.log(gain) / Math.log(10.0)*20.0);
gainControl.setValue(dB);
}

Cuidado: não tente obter o controle VOLUME, a não ser que você saiba o que está fazendo, já que ele não costuma existir em muitos sistemas de som, vindo a retornar uma referência nula.


  • Trocando Entre Mudo e Não-Mudo

A rigor, definir o valor como mudo significa simplesmente atribuir valor zero para o ganho. Mas, existe uma maneira mais simples para se trocar entre mudo e audível, mantendo o ganho inicial:

BooleanControl muteControl =
(BooleanControl) clip.getControl(BooleanControl.Type.MUTE);
muteControl.setValue(true); // Define como mudo
muteControl.setValue(false); // Retorna para audível

É isso aí, gente!! Agora ficou fácil!! Claro, é bom lembrar: COMENTEM!!!

Nenhum comentário: