作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在制作一个程序,可捕获麦克风中的声音,并在扬声器上收听(完成)并同时将其保存到wav文件中。我在这个问题上搜索了三到四天。我相信,Stackoverflow可以帮助我。
我需要做的就是在用户实时收听的同时,将来自麦克风的声音写入到wav文件中。请帮助或指出正确的方向。我认为我可以以某种方式直接将字节写入文件,但是由于缺少 header ,这会很麻烦。
这是我的课:
public class RadioListener {
private Runnable mRunnable, mFounderR;
private Thread mThread, mFounderT;
private SourceDataLine mSourceLine;
private TargetDataLine mTargetLine;
private DataLine.Info mTargetInfo;
private DataLine.Info mSourceInfo;
private static final AudioFormat mFormat = new AudioFormat(44100, 16, 2, true, false);
private Mixer.Info[] mixers;
private Mixer mFoundMixer = null;
private Config mConfig;
private boolean isCommunicating = false;
private boolean isRetranslating = false;
File wavFile = null;
AudioFileFormat.Type fileType = AudioFileFormat.Type.WAVE;
AudioInputStream ais;
public RadioListener (Config cfg) {
mConfig = cfg;
mixers = AudioSystem.getMixerInfo();
mSourceInfo = new DataLine.Info(SourceDataLine.class, mFormat);
mTargetInfo = new DataLine.Info(TargetDataLine.class, mFormat);
try {mSourceLine = (SourceDataLine) AudioSystem.getLine(mSourceInfo);}
catch (LineUnavailableException e) {System.out.println("RadioListener output error");}
wavFile = new File("E:/RecordAudio.wav");
}
public void Start() {
if (Defines.strToIntDef(mConfig.getProperty("debugOut"), 0) == 1)
showMixers();
if (mFoundMixer == null) searchDevice();
else startCommunication();
}
public void Stop() {
if (mFoundMixer == null) return;
try {
mSourceLine.stop();
mSourceLine.close();
mTargetLine.stop();
mTargetLine.close();
} catch (Exception e) {}
finally {
isCommunicating = false;
}
}
public void Mute() {
isRetranslating = false;
}
private void searchDevice() {
mFounderR = new RadioFinder();
mFounderT = new Thread(mFounderR);
mFounderT.start();
}
private void startThread() {
startCommunication();
mRunnable = new Communicator();
mThread = new Thread(mRunnable);
mThread.start();
}
private void startCommunication() {
if (isCommunicating) {
isRetranslating = true;
return;
}
try {
mTargetLine.open(mFormat);
mTargetLine.start();
mSourceLine.open(mFormat);
mSourceLine.start();
//Line line = mFoundMixer.getLine(mSourceInfo);
//FloatControl control = (FloatControl)line.getControl(FloatControl.Type.MASTER_GAIN);
//control.setValue(limit(control,10000));
//control.setValue(-10);
isCommunicating = true;
isRetranslating = true;
//When I'm uncommenting this two lines sound is writing to file, but I don't hear it.
//ais = new AudioInputStream(mTargetLine);
//AudioSystem.write(ais, fileType, wavFile);
} catch (Exception e) {
isCommunicating = false;
isRetranslating = false;
}
}
private class RadioFinder implements Runnable {
@Override
public void run() {
Line.Info targetDLInfo = new Line.Info(TargetDataLine.class);
for (Mixer.Info info : mixers) {
Mixer tmp = AudioSystem.getMixer(info);
//if (myMixer.isLineSupported(Port.Info.LINE_IN) || myMixer.isLineSupported(Port.Info.MICROPHONE)) {
if (tmp.isLineSupported(targetDLInfo)) {
String s = tmp.getMixerInfo().getName();
if (s.toLowerCase().contains(mConfig.getProperty("radioName").toLowerCase())) {
mFoundMixer = tmp;
try {
mTargetInfo = new DataLine.Info(TargetDataLine.class, mFormat);
mTargetLine = (TargetDataLine) mFoundMixer.getLine(mTargetInfo);
System.out.println("Found radio device: " + mFoundMixer.getMixerInfo().getName());
startThread();
} catch (Exception e) {
System.out.println("RadioListener input error");
mFoundMixer = null;
}
break;
}
}
}
}
}
private static void showMixers() {
ArrayList<Mixer.Info> mixInfos = new ArrayList<Mixer.Info>(Arrays.asList(AudioSystem.getMixerInfo()));
Line.Info sourceDLInfo = new Line.Info(SourceDataLine.class);
Line.Info targetDLInfo = new Line.Info(TargetDataLine.class);
Line.Info clipInfo = new Line.Info(Clip.class);
Line.Info portInfo = new Line.Info(Port.class);
String support;
for (Mixer.Info mixInfo: mixInfos) {
Mixer mixer = AudioSystem.getMixer(mixInfo);
support = ", supports ";
if (mixer.isLineSupported(sourceDLInfo))
support += "SourceDataLine ";
if (mixer.isLineSupported(clipInfo))
support += "Clip ";
if (mixer.isLineSupported(targetDLInfo))
support += "TargetDataLine ";
if (mixer.isLineSupported(portInfo))
support += "Port ";
System.out.println("Mixer: " + mixInfo.getName() + support + ", " + mixInfo.getDescription());
}
}
private class Communicator implements Runnable {
@Override
public void run() {
int numBytesRead;
byte[] targetData = new byte[mTargetLine.getBufferSize() / 5];
while (isCommunicating) {
numBytesRead = mTargetLine.read(targetData, 0, targetData.length);
System.out.println(numBytesRead);
if (numBytesRead == -1) break;
if (isRetranslating)
mSourceLine.write(targetData, 0, numBytesRead);
}
}
}
}}
最佳答案
好吧,我来了下面的工作代码。
我创建了新的“空” wav文件,
ais = new AudioInputStream(mTargetLine);
AudioSystem.write(ais, fileType, wavFile);
public class RadioListener {
private Runnable mRunnable, mFounderR;
private Thread mThread = null, mFounderT = null;
private SourceDataLine mSourceLine;
private TargetDataLine mTargetLine;
private DataLine.Info mTargetInfo;
private DataLine.Info mSourceInfo;
private static final AudioFormat mFormat = new AudioFormat(44100, 16, 2, true, false);
private Mixer.Info[] mixers;
private Mixer mFoundMixer = null;
private Config mConfig;
private boolean isCommunicating = false;
private boolean isRetranslating = false;
private static final String mHeader = "header.wav";
//private File wavFile = null;
AudioFileFormat.Type fileType = AudioFileFormat.Type.WAVE;
AudioInputStream ais;
private FileOutputStream fos;
private boolean isRecording = false;
public RadioListener (Config cfg) {
mConfig = cfg;
mixers = AudioSystem.getMixerInfo();
mSourceInfo = new DataLine.Info(SourceDataLine.class, mFormat);
mTargetInfo = new DataLine.Info(TargetDataLine.class, mFormat);
try {mSourceLine = (SourceDataLine) AudioSystem.getLine(mSourceInfo);}
catch (LineUnavailableException e) {System.out.println("RadioListener output error");}
//wavFile = new File("E:/RecordAudio.wav");
}
public void Start() {
if (Defines.strToIntDef(mConfig.getProperty("debugOut"), 0) == 1)
showMixers();
if (mFoundMixer == null) searchDevice();
else startCommunication();
}
public void Stop() {
if (mFoundMixer == null) return;
try {
mSourceLine.stop();
mSourceLine.close();
mTargetLine.stop();
mTargetLine.close();
} catch (Exception e) {}
finally {
isCommunicating = false;
}
}
public void disposeListener() {
if (isRecording) stopRecording();
Stop();
if (mFounderT != null)
if (mFounderT.isAlive())
mFounderT.interrupt();
if (mThread != null)
if (mThread.isAlive())
mThread.interrupt();
}
public void Mute() {
isRetranslating = false;
}
public void enableRecording (boolean f) {
if (f) startRecording();
else stopRecording();
}
public boolean isRecording() {
return isRecording;
}
private void startRecording() {
final DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
Date date = new Date(System.currentTimeMillis());
String dt = formatter.format(date);
final InputStream stream = this.getClass().getResourceAsStream("/" + mHeader);
byte b[] = new byte[44];
try {
fos = new FileOutputStream(Defines.getCurrentFolder() + File.separator + dt + ".wav", true);
try {
stream.read(b, 0, 44);
fos.write(b);
} catch (IOException e) {
try {fos.close();}
catch (IOException e1) {;}
isRecording = false;
return;
}
} catch (FileNotFoundException e) {
isRecording = false;
}
isRecording = true;
}
private void stopRecording() {
isRecording = false;
try {fos.close();}
catch (IOException e) {;}
isRecording = false;
}
private void searchDevice() {
mFounderR = new RadioFinder();
mFounderT = new Thread(mFounderR);
mFounderT.start();
}
private void startThread() {
startCommunication();
mRunnable = new Communicator();
mThread = new Thread(mRunnable);
mThread.start();
}
private void startCommunication() {
if (isCommunicating) {
isRetranslating = true;
return;
}
try {
mTargetLine.open(mFormat);
mTargetLine.start();
mSourceLine.open(mFormat);
mSourceLine.start();
//Line line = mFoundMixer.getLine(mSourceInfo);
//FloatControl control = (FloatControl)line.getControl(FloatControl.Type.MASTER_GAIN);
//control.setValue(limit(control,10000));
//control.setValue(-10);
isCommunicating = true;
isRetranslating = true;
//ais = new AudioInputStream(mTargetLine); //ok
//AudioSystem.write(ais, fileType, wavFile); //ok
} catch (Exception e) {
isCommunicating = false;
isRetranslating = false;
}
}
private class RadioFinder implements Runnable {
@Override
public void run() {
Line.Info targetDLInfo = new Line.Info(TargetDataLine.class);
for (Mixer.Info info : mixers) {
Mixer tmp = AudioSystem.getMixer(info);
//if (myMixer.isLineSupported(Port.Info.LINE_IN) || myMixer.isLineSupported(Port.Info.MICROPHONE)) {
if (tmp.isLineSupported(targetDLInfo)) {
String s = tmp.getMixerInfo().getName();
if (s.toLowerCase().contains(mConfig.getProperty("radioName").toLowerCase())) {
mFoundMixer = tmp;
try {
mTargetInfo = new DataLine.Info(TargetDataLine.class, mFormat);
mTargetLine = (TargetDataLine) mFoundMixer.getLine(mTargetInfo);
System.out.println("Found radio device: " + mFoundMixer.getMixerInfo().getName());
startThread();
} catch (Exception e) {
System.out.println("RadioListener input error");
mFoundMixer = null;
}
break;
}
}
}
}
}
private static void showMixers() {
ArrayList<Mixer.Info> mixInfos = new ArrayList<Mixer.Info>(Arrays.asList(AudioSystem.getMixerInfo()));
Line.Info sourceDLInfo = new Line.Info(SourceDataLine.class);
Line.Info targetDLInfo = new Line.Info(TargetDataLine.class);
Line.Info clipInfo = new Line.Info(Clip.class);
Line.Info portInfo = new Line.Info(Port.class);
String support;
for (Mixer.Info mixInfo: mixInfos) {
Mixer mixer = AudioSystem.getMixer(mixInfo);
support = ", supports ";
if (mixer.isLineSupported(sourceDLInfo))
support += "SourceDataLine ";
if (mixer.isLineSupported(clipInfo))
support += "Clip ";
if (mixer.isLineSupported(targetDLInfo))
support += "TargetDataLine ";
if (mixer.isLineSupported(portInfo))
support += "Port ";
System.out.println("Mixer: " + mixInfo.getName() + support + ", " + mixInfo.getDescription());
}
}
private class Communicator implements Runnable {
@Override
public void run() {
int numBytesRead;
byte[] targetData = new byte[mTargetLine.getBufferSize() / 5];
while (isCommunicating) {
numBytesRead = mTargetLine.read(targetData, 0, targetData.length);
if (numBytesRead == -1) break;
if (isRetranslating)
mSourceLine.write(targetData, 0, numBytesRead);
if (isRecording) {
try {fos.write(targetData);}
catch (IOException e) {stopRecording();}
}
}
}
}
}
关于java - java捕获声音并听到并同时将其录制到WAV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47268870/
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: The element ‘behavior’ has invalid child element ‘myFa
我是一名优秀的程序员,十分优秀!