Javaでユーザのアクションに基づいてサウンドを生成したい。 SourceDataLineのバッファサイズをできるだけ小さな値(1フレーム)に設定しても、約1秒の遅延があります。SourceDataLineを使用してjavaで遅延なくサウンドを流す方法
コードスニペットは、千の言葉の価値があるので、ここでのコードがある(あるいは、それは絵だった?):
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++;
}
}
}
は、音を聞きながら、スライダーを移動してみてください。それは可能ですか、またはインメモリバッファを作成してクリップインスタンスにラップする必要がありますか?
ありがとう:
はSourceDataLineを設定した後、このコードを使用します。私は_new DataLine.Info(SourceDataLine.class、audioFormat、1)_の_bufferSize_引数で目が見えませんでした。もちろん、私はそのような小さなバッファを使用するつもりはありません。これは私の問題を示すためのものでした。 – andi
@Florianこの例はありがとうございます。 'int n = soundLine.write(buffer、0、bufferSize);' nは2回の最初の書き込みの後に0の値を返します。 – user390525
@ user390525では、SourceDataLine.write()の仕様に従って、エラー(不正なパラメータ)が発生した場合、またはSourceDataLineが停止、フラッシュ、またはクローズした場合に、指定されたバッファサイズよりも小さい値を返すことができます。 これらの条件がどれも適用されないことを100%確信している場合は、そのSourceDataLineのJava実装にバグが存在する可能性があります。 – Florian