JavaSoundRecorder TargetDataLine 不关闭?
JavaSoundRecorder TargetDataLine does not close?
我创建了一个 JavaSoundRecorder,如下所示。当我创建 class 的对象并调用 finish() 函数时,该行不会 stop/close 并保持活动状态(未达到空状态)。这意味着我只能用录音机进行一次录音。我该怎么做才能解决这个问题?
import java.io.*;
import javax.sound.sampled.*;
import java.util.Set;
public class JavaSoundRecorder {
private TargetDataLine line;
private AudioFileFormat.Type fileType;
private File savedWav;
private AudioFormat audioForm;
private DataLine.Info info;
public int errorNum;
public void setFile(File savedWav) {
this.savedWav = savedWav;
}
/*constructs class*/
public JavaSoundRecorder() {
fileType = AudioFileFormat.Type.WAVE;
audioForm = getAudioFormat();
info = new DataLine.Info(TargetDataLine.class, audioForm);
}
/*
* Defines an audio format
*/
AudioFormat getAudioFormat() {
float sampleRate = 16000;
int sampleSizeInBits = 16;
int channels = 1;
boolean signed = true;
boolean BigEndian = true;
AudioFormat format = new AudioFormat(sampleRate, sampleSizeInBits, channels , signed, BigEndian);
return format;
}
/*Captures the sound and records in WAV fiLE, creates a new thread for recording*/
protected int startRecording(String path) {
setFile(new File(path));
errorNum = 0;
if(line == null) {
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
try {
//check if system supports the data line
if(!AudioSystem.isLineSupported(info)) {
System.out.println("not supported")
}
line = (TargetDataLine) AudioSystem.getLine(info);
line.open(audioForm);
line.start();
AudioInputStream ais = new AudioInputStream(line);
//write recoding to file..
AudioSystem.write(ais, fileType, savedWav);
}
catch(LineUnavailableException e) {
errorNum = 3;
e.printStackTrace();
}
catch(IOException e) {
errorNum = 4;
e.printStackTrace();
}
}
});
thread2.start();
}
return errorNum;
}
/*stops recording*/
public void finish() {
line.stop();
line.close();
}
}
我会考虑使用松耦合模式。 finish()
方法应该 建议 记录线程执行关闭和清理工作,而不是实际自己执行该工作。因此,finish()
翻转一个 布尔值 ,命名为 isRunning
到 false
。布尔值可以是 volatile
,以帮助确保立即跨不同线程读取值的变化。
这样,将关闭和清理的代码移动到 run()
方法的末尾,并用 while(isRunning)
块包围执行 write()
的代码。
现在,我对细节还不够了解,无法从头脑中了解所需的确切更改,但我认为您还必须进行一些重构,因此写作是一个重复的动作,即在每次写入操作后,重复将控制权交还给封闭的 while()
。
我创建了一个 JavaSoundRecorder,如下所示。当我创建 class 的对象并调用 finish() 函数时,该行不会 stop/close 并保持活动状态(未达到空状态)。这意味着我只能用录音机进行一次录音。我该怎么做才能解决这个问题?
import java.io.*;
import javax.sound.sampled.*;
import java.util.Set;
public class JavaSoundRecorder {
private TargetDataLine line;
private AudioFileFormat.Type fileType;
private File savedWav;
private AudioFormat audioForm;
private DataLine.Info info;
public int errorNum;
public void setFile(File savedWav) {
this.savedWav = savedWav;
}
/*constructs class*/
public JavaSoundRecorder() {
fileType = AudioFileFormat.Type.WAVE;
audioForm = getAudioFormat();
info = new DataLine.Info(TargetDataLine.class, audioForm);
}
/*
* Defines an audio format
*/
AudioFormat getAudioFormat() {
float sampleRate = 16000;
int sampleSizeInBits = 16;
int channels = 1;
boolean signed = true;
boolean BigEndian = true;
AudioFormat format = new AudioFormat(sampleRate, sampleSizeInBits, channels , signed, BigEndian);
return format;
}
/*Captures the sound and records in WAV fiLE, creates a new thread for recording*/
protected int startRecording(String path) {
setFile(new File(path));
errorNum = 0;
if(line == null) {
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
try {
//check if system supports the data line
if(!AudioSystem.isLineSupported(info)) {
System.out.println("not supported")
}
line = (TargetDataLine) AudioSystem.getLine(info);
line.open(audioForm);
line.start();
AudioInputStream ais = new AudioInputStream(line);
//write recoding to file..
AudioSystem.write(ais, fileType, savedWav);
}
catch(LineUnavailableException e) {
errorNum = 3;
e.printStackTrace();
}
catch(IOException e) {
errorNum = 4;
e.printStackTrace();
}
}
});
thread2.start();
}
return errorNum;
}
/*stops recording*/
public void finish() {
line.stop();
line.close();
}
}
我会考虑使用松耦合模式。 finish()
方法应该 建议 记录线程执行关闭和清理工作,而不是实际自己执行该工作。因此,finish()
翻转一个 布尔值 ,命名为 isRunning
到 false
。布尔值可以是 volatile
,以帮助确保立即跨不同线程读取值的变化。
这样,将关闭和清理的代码移动到 run()
方法的末尾,并用 while(isRunning)
块包围执行 write()
的代码。
现在,我对细节还不够了解,无法从头脑中了解所需的确切更改,但我认为您还必须进行一些重构,因此写作是一个重复的动作,即在每次写入操作后,重复将控制权交还给封闭的 while()
。