La Web del Programador: Comunidad de Programadores
 
    Pregunta:  9269 - COMO CREAR UN CHAT DE VOZ
Autor:  José Manuel Botubol Ares
Mi pregunta va referida a como incorporar un chat de voz a mi página web. Mi página está hecha en lenguaje HTML. Por favor contestar pronto, me urge vuestra respuesta.

Atentamente

  Respuesta:  Óscar Javier García Baudet
En principio HTML no te ofrece ninguna ayuda al respecto.

Todo deberías programarlo en Java. Es más, deberías crearte un servidor aparte del servidor chat web o adaptar éste para facilitar las ips de los clientes a los usuarios.

La técnica es sencilla:

Por parte del cliente:
Capturamos audio y lo comprimimos usando algún algoritmo rápido (o potente, a gusto del programador). Recomiendo ADPCM, es fácil de implementar, consume pocos recursos de cálculo y proceso y ocupa en ancho de banda casi lo mismo que el formato MPEG Layer 2.
Esta información se envía directamente al cliente destino que escuchará nuestra voz preferiblemente en paquetes UDP numerados por secuencias a ser posible de 32 o 64 bits.

Por parte del servidor:
Cuando un cliente quiere comunicarse con otro cliente, el servidor debe facilitarle el número IP para que la comunicación sea directa y no se sature el servidor por información que va a ser reenviada.

Codificación ADPCM:
Explicación sencilla: Se usan x bits por muestra, si son por ejemplo 3 bits, podemos crear la siguiente tabla:

0 0 0 -> subir 8 niveles
0 0 1 -> subir 4 niveles
0 1 0 -> subir 2 niveles
0 1 1 -> subir 1 nivel
1 0 0 -> bajar 1 nivel
1 0 1 -> bajar 2 niveles
1 1 0 -> bajar 4 niveles
1 1 1 -> bajar 8 niveles

A esto se le llama codificación diferencial. Se basa en calcular la diferencia entre una muestra y la anterior. Si no hay sonido (valor 0) se produce un ruido llamado granular, debido a la subida/bajada del valor, ya que no existe una codificación para "estarse parado". Cuando se codifican dos (se puede configurar tres o cuatro mejor) veces un subir o bajar máximo (8) se multiplica por 2 los niveles, pasando a ser...

0 0 0 -> subir 16 niveles
0 0 1 -> subir 8 niveles
0 1 0 -> subir 4 niveles
0 1 1 -> subir 2 nivel
1 0 0 -> bajar 2 nivel
1 0 1 -> bajar 4 niveles
1 1 0 -> bajar 8 niveles
1 1 1 -> bajar 16 niveles

También podrías probar a multiplicar por 3 o 4 (preferiblemente 4, es potencia de 2).

Cuando se codifican dos (o ya hemos dicho que podemos programar más tiempo) subidas/bajadas mínimas (1 al principio, cuando se multiplican por dos ya sería 2, y asi sucesivamente), dividimos entre dos los niveles.

No sé si me he explicado caramente. Si quieres detalles de implementación de estándares reales, mándame un email y te mando las fórmulas reales usadas (éstas son caseras para agilizar la programación ;).

Tipo de sonido obtenido:
Si los paquetes UDP no se pierden, el cliente puede ir reproduciendo el sonido correctamente. Si los paquetes se retrasan, se escucharan saltos y el sonido se desfasará (se podrían crear ecos molestos).
Cuando se satura alguna conexión y se pierden paquetes UDP, se escuchan espacios en blanco o saltos de sonido.
Nota: esto es mucho mejor que implementar TCP, que en caso de perder tramas, las solicita de nuevo y puede provocar retardos de sonido MUY elevados.

A nivel de programación en Java no sabría decirte ahora mismo cómo implementarlo. Espero que con la idea del modo de transmisión y codificación te haya bastado para continuar con tu proyecto.