gpt4 book ai didi

java - GUI 事件未一致触发

转载 作者:行者123 更新时间:2023-12-02 07:34:33 27 4
gpt4 key购买 nike

我有一个小程序来录制和播放 .wav 文件。在 GUI 类中,我为“停止”按钮添加了以下代码:

private AudioCapture audCap = new AudioCapture();

stopBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
captureBtn.setEnabled(true);
stopBtn.setEnabled(false);
playBtn.setEnabled(true);
audCap.stopCapture = true; // this doesn't work
audCap.stopPlayback = true; // this does
}
}

在 AudioCapture() 类中,我有以下用于播放的代码,当单击停止按钮时,它会正确停止:

class PlayThread extends Thread {
byte tempBuffer[] = new byte[10000];

public void run() {

stopPlayback = false;

try {
sourceDataLine.open(audioFormat);
sourceDataLine.start();

int cnt;
while ((cnt = audioInputStream.read(tempBuffer, 0,
tempBuffer.length)) != -1 && stopPlayback == false) {
if (cnt > 0) {
sourceDataLine.write(tempBuffer, 0, cnt);
}
}
sourceDataLine.drain();
sourceDataLine.close();

} catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
}
}

我还有这段用于录制/捕获的代码,单击停止按钮时不会停止:

class CaptureThread extends Thread {
// An arbitrary-size temporary holding buffer
byte tempBuffer[] = new byte[10000];

public void run() {

stopCapture = false;
// record as wave
AudioFileFormat.Type fileType = AudioFileFormat.Type.WAVE;
// takes user input file name and appends filetype
audioFile = new File(wavName + ".wav");

try {
while (!stopCapture) {

int cnt = targetDataLine.read(tempBuffer, 0,
tempBuffer.length);
if (cnt > 0) {
AudioSystem.write(new AudioInputStream(targetDataLine),
fileType, audioFile);
}
}
targetDataLine.stop();
targetDataLine.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

stopCature 和 stopPlayback 是 AudioCapture() 类中的实例变量。

我正在使用 Eclipse 并尝试在“while (!stopCapture)”处设置断点,但它似乎永远不会超出这个范围。有谁知道上面的代码中是否有任何内容会导致第一个方法按预期运行但第二个方法不运行?

-编辑-我尝试将程序的精简版本放入 SSCE,但它仍然运行到几百行:

import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.Mixer;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.TargetDataLine;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class audioTest extends JFrame {

private static final long serialVersionUID = 1L;
AudioCapture audCap = new AudioCapture();

public static void main(String[] args) {
new audioTest();
}

public audioTest() {

layoutTransporButtons();
getContentPane().setLayout(new FlowLayout());
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(350, 100);
setVisible(true);
}

public void layoutTransporButtons() {

final JPanel guiButtonPanel = new JPanel();
final JButton captureBtn = new JButton("Record");
final JButton stopBtn = new JButton("Stop");
final JButton playBtn = new JButton("Playback");
guiButtonPanel.setLayout(new GridLayout());
this.add(guiButtonPanel);
captureBtn.setEnabled(true);
stopBtn.setEnabled(false);
playBtn.setEnabled(true);

// Register anonymous listeners
captureBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
captureBtn.setEnabled(false);
stopBtn.setEnabled(true);
playBtn.setEnabled(false);
// Capture input data from the microphone
audCap.captureAudio();
}
});
guiButtonPanel.add(captureBtn);

stopBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
captureBtn.setEnabled(true);
stopBtn.setEnabled(false);
playBtn.setEnabled(true);
audCap.stopRecordAndPlayback = true;
}
});
guiButtonPanel.add(stopBtn);

playBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
stopBtn.setEnabled(true);
audCap.playAudio();
}
});
guiButtonPanel.add(playBtn);
}

class AudioCapture {

volatile boolean stopRecordAndPlayback = false;
AudioFormat audioFormat;
TargetDataLine targetDataLine;
AudioInputStream audioInputStream;
SourceDataLine sourceDataLine;
private String wavName;
private File audioFile;
/**
* capture audio input from microphone and save as .wav file
*/
public void captureAudio() {

wavName = JOptionPane.showInputDialog(null,
"enter name of file to be recorded:");
try {
Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();
// Select an available mixer
Mixer mixer = AudioSystem.getMixer(mixerInfo[1]);
// Get everything set up for capture
audioFormat = getAudioFormat();
DataLine.Info dataLineInfo = new DataLine.Info(
TargetDataLine.class, audioFormat);
// Get a TargetDataLine on the selected mixer.
targetDataLine = (TargetDataLine) mixer.getLine(dataLineInfo);
// Prepare the line for use.
targetDataLine.open(audioFormat);
targetDataLine.start();
// Create a thread to capture the microphone
Thread captureThread = new CaptureThread();
captureThread.start();
} catch (Exception e) {
System.out.println(e);
System.exit(0);
}
}

/**
* This method plays back the audio data that has
* been chosen by the user
*/
public void playAudio() {
// add file chooser
JFileChooser chooser = new JFileChooser();
chooser.setCurrentDirectory(audioFile);
int returnVal = chooser.showOpenDialog(chooser);
// retrieve chosen file
if (returnVal == JFileChooser.APPROVE_OPTION) {
// create the file
audioFile = chooser.getSelectedFile();
}
// play chosen file
try {
audioInputStream = AudioSystem.getAudioInputStream(audioFile);
audioFormat = audioInputStream.getFormat();
DataLine.Info dataLineInfo = new DataLine.Info(
SourceDataLine.class, audioFormat);
sourceDataLine = (SourceDataLine) AudioSystem
.getLine(dataLineInfo);
// Create a thread to play back the data
new PlayThread().start();
} catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
}
/**
* This method creates and returns an AudioFormat object
*/
private AudioFormat getAudioFormat() {
float sampleRate = 44100.0F;
// 8000,11025,16000,22050,44100
int sampleSizeInBits = 16;
// 8,16
int channels = 1;
// 1,2
boolean signed = true;
// true,false
boolean bigEndian = false;
// true,false
return new AudioFormat(sampleRate, sampleSizeInBits, channels,
signed, bigEndian);
}

/**
* Inner class to capture data from microphone
*/
class CaptureThread extends Thread {
// An arbitrary-size temporary holding buffer
byte tempBuffer[] = new byte[10000];

public void run() {
// reset stopCapture to false
stopRecordAndPlayback = false;
// record as wave
AudioFileFormat.Type fileType = AudioFileFormat.Type.WAVE;
// take user input file name and append file type
audioFile = new File(wavName + ".wav");

try {
targetDataLine.open(audioFormat);
targetDataLine.start();
while (!stopRecordAndPlayback) {
AudioSystem.write(new AudioInputStream(targetDataLine),
fileType, audioFile);
}
targetDataLine.stop();
targetDataLine.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* Inner class to play back the data
*/
class PlayThread extends Thread {
byte tempBuffer[] = new byte[10000];

public void run() {
// reset stop button
stopRecordAndPlayback = false;

try {
sourceDataLine.open(audioFormat);
sourceDataLine.start();
int cnt;
while ((cnt = audioInputStream.read(tempBuffer, 0,
tempBuffer.length)) != -1
&& stopRecordAndPlayback == false) {
if (cnt > 0) {
sourceDataLine.write(tempBuffer, 0, cnt);
}
}
sourceDataLine.drain();
sourceDataLine.close();
} catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
}
}
}

}

最佳答案

您没有提供所有需要的信息,但很可能的原因是您的程序中存在数据争用。

由于您在不同的线程中运行事物,因此需要在线程之间使用某种形式的同步,以确保您在一个线程中所做的更改在另一个线程中可见。

通常,在您的情况下,将 boolean 变量声明为 volatile 就足够了。

编辑

一种可能性是 while 循环中的条件没有像您想象的那样经常被评估(如果有的话) - 您可以添加一些日志记录来查看发生了什么:

stopBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//your code here
System.out.println("in actionPerformed: " + stopCatpure);
}
}

class CaptureThread extends Thread {
//same code
while (!stopCapture) {
System.out.println("in while: " + stopCapture);
//rest of your code
}
}

关于java - GUI 事件未一致触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12437137/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com