Quiero generar sonidos en función de la acción del usuario en Java. Incluso si configuré el tamaño del búfer en SourceDataLine al valor más pequeño posible (1 fotograma), aún tengo un retraso de aproximadamente 1 segundo.cómo transmitir sonido en java sin demora utilizando SourceDataLine
Debido a que un fragmento de código vale más que mil palabras (? O era una imagen), aquí está el código:
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;
import javax.swing.JFrame;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class SoundTest {
private static int sliderValue = 500;
public static void main(String[] args) throws Exception {
final JFrame frame = new JFrame();
final JSlider slider = new JSlider(500, 1000);
frame.add(slider);
slider.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
sliderValue = slider.getValue();
}
});
frame.pack();
frame.setVisible(true);
final AudioFormat audioFormat = new AudioFormat(44100, 8, 1, true, true);
final DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat, 1);
final SourceDataLine soundLine = (SourceDataLine) AudioSystem.getLine(info);
soundLine.open(audioFormat);
soundLine.start();
byte counter = 0;
final byte[] buffer = new byte[1];
byte sign = 1;
while (frame.isVisible()) {
if (counter > audioFormat.getFrameRate()/sliderValue) {
sign = (byte) -sign;
counter = 0;
}
buffer[0] = (byte) (sign * 30);
soundLine.write(buffer, 0, 1);
counter++;
}
}
}
trate de mover el cursor mientras se escucha el sonido. ¿Es posible, o debo crear búferes en memoria y envolverlos en instancias Clip?
Gracias. Estaba cegado por el argumento _bufferSize_ en _new DataLine.Info (SourceDataLine.class, audioFormat, 1) _. Por supuesto que no voy a usar un buffer tan pequeño. Esto fue solo para mostrar mi problema. – andi
@Florian gracias por este ejemplo. ¿Y qué significa si 'int n = soundLine.write (buffer, 0, bufferSize);' n devuelve 0 valor después de 2 primera escritura? – user390525
@ user390525, según la especificación de SourceDataLine.write(), solo puede devolver menos del tamaño de búfer especificado en caso de error (parámetros mal formados) o si SourceDataLine se detuvo, se vació o se cerró. Si está 100% seguro de que ninguna de esas condiciones se aplica, puede haber un error en la implementación de Java de esa SourceDataLine. – Florian