Java:在声音扬声器上生成无限正弦音调

Java:在声音扬声器上生成无限正弦音调,java,audio,Java,Audio,我试图使用Java Audio API生成具有两个不同频率的正弦波的立体声,但我既不能使用双通道系统,也不能使用我的音调,因为某种原因,在播放时中断并重新启动 我的源代码: public class GeradorSinal extends javax.swing.JFrame { int fs = 48000; AudioFormat af = new AudioFormat(fs, 8, 1, true, true); SourceDataLine line; Thread generat

我试图使用Java Audio API生成具有两个不同频率的正弦波的立体声,但我既不能使用双通道系统,也不能使用我的音调,因为某种原因,在播放时中断并重新启动

我的源代码:

public class GeradorSinal extends javax.swing.JFrame {

int fs = 48000;
AudioFormat af = new AudioFormat(fs, 8, 1, true, true);
SourceDataLine line;
Thread generator;
boolean parar = false;
byte[] senoid = new byte[1];

/**
 * Creates new form GeradorSinal
 */
public GeradorSinal() {
    initComponents();
    try {
        line = AudioSystem.getSourceDataLine(af);
        line.open(af, fs);
    } catch (LineUnavailableException e) {
        System.err.println(e.getMessage());
    }
}

public static double scale(
        double x,
        double old_min, double old_max,
        double new_min, double new_max) {
    double old_range = old_max - old_min;
    double new_range = new_max - new_min;
    return new_min + (x - old_min) * new_range / old_range;
}                     

private void bt_gerarActionPerformed(java.awt.event.ActionEvent evt) {                                         
    // TODO add your handling code here:
    generator = new Thread(new Runnable() {

        @Override
        public void run() {
            long t = 0;
            long f = Long.parseLong(ln_freq.getText());
            line.start();
            while (!parar) {
                senoid[0] = (byte) scale(Math.sin(2 * Math.PI * f * t++ / fs),
                        -1.0, 1.0, Byte.MIN_VALUE, Byte.MAX_VALUE);
                line.write(senoid, 0, 1);
            }
            line.stop();
        }
    });
    generator.start();
}                                        

private void bt_pararActionPerformed(java.awt.event.ActionEvent evt) {                                         
    // TODO add your handling code here:;
    parar = true;
    try {
        generator.join();
    } catch (InterruptedException e) {
        System.err.println(e.getMessage());
    }
    parar = false;
}                                        

private void bt_salvarActionPerformed(java.awt.event.ActionEvent evt) {                                          
    // TODO add your handling code here:
    try {
        FileWriter fstream = new FileWriter("testes.txt", true);
        try (BufferedWriter fbw = new BufferedWriter(fstream)) {
            DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
            Date date = new Date();
            fbw.write(dateFormat.format(date));
            fbw.write("\t");
            fbw.write(ln_freq.getText());
            fbw.write("\t");
            fbw.write(String.valueOf(1.2 * Double.parseDouble(ln_freq.getText())));
            fbw.write("\t");
            fbw.write(ln_volume.getText());
            fbw.newLine();
        }
    } catch (IOException e) {
        System.err.println(e.getMessage());
    }

}          

}

尝试生成一个完整的样本数组,而不是一次只写入一个样本。我也尝试过,同样的问题。请注意,流无限循环,这是典型的声音API所需要的,它更好地处理发送缓冲区的问题,而不是尝试一次写入一个样本。尝试至少500或1000个样本的缓冲液。另外,虽然这不会影响声音的起伏,但是
parar
变量需要是可变的,或者
generator
线程没有义务看到它的变化。我看到您在打开行时使用的缓冲区大小与写入它的缓冲区大小不同。这也可能是一个问题。老实说,我不知道当你尝试这样做时会发生什么。文件没有涵盖它。尝试在不使用建议的缓冲区大小的情况下打开该行,或者使用与写入该行相同的大小打开该行。