我正在制作一个程序,用于从麦克风中捕获声音,在声音扬声器上听到它(已完成)并同时将其保存到wav文件中。我正在寻找这个问题三四天。我相信,Stackoverflow可以帮助我。
我需要做的就是将来自麦克风的声音写入wav文件,同时用户正在收听它。请帮忙或指向正确的方向。我认为不知怎的,我可以直接将文件写入文件,但由于缺少标题,这将是混乱。
这是我的班级:
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);
}
}
}
}}
谢谢!
答案 0 :(得分:0)
好吧,我来了以下工作代码。
我使用
创建了新的“空”wav文件 <catalog_category_default translate="label">
<label>Catalog Category (Non-Anchor)</label>
<reference name="left">
<block type="catalog/navigation" name="catalog.leftnav" after="currency" template="catalog/navigation/left.phtml"/>
</reference>
<reference name="content">
我有44个字节的wav文件,其中标题存储。
当我需要录制一个wav文件时,当我正在实时监听它时,我需要执行以下操作:创建一个空的wav文件,编写该头文件(存储在jar中),在链接线程中追加字节。 (在我的例子中是Communicator类)它将SourceLine中的字节指向TargetLine(基本上是从麦克风到扬声器)。以下是我的问题中更新课程的代码。
P.S。:标题仅适用于指定的AudioFormat。如果你需要另一个,那么你可以单独“生成”它们。 P.S.S:抱歉我的英语不好:)
代码:
ais = new AudioInputStream(mTargetLine);
AudioSystem.write(ais, fileType, wavFile);