我正在使用Java开发概念验证应用程序。我注意到,当我运行它时,我的Java应用程序比CSharp版本要慢。我想要一个概念或建议来改善表现。
我从我的麦克风中捕获声音,使用一个线程,在此线程中,我有另一个线程:
不幸的是,代码很长而且SSCCE(很难提取功能代码,以便发布短代码)。
我想要一些建议来发现我对这段代码的逻辑缺陷。
final AudioFormat audioformat = new AudioFormat(16000 /*Frequency*/,
16 /* two bytes per sample */, 2 /*Stereo*/, true /*Signed*/, true /*bigEndian*/);
final DataLine.Info dlInfo = new DataLine.Info(TargetDataLine.class, audioformat);
if (!AudioSystem.isLineSupported(dlInfo)) {
System.out.println("Line not supported");
}
try {
final TargetDataLine tdLine = (TargetDataLine) AudioSystem.getLine(dlInfo);
if (jtbCapture.isSelected()) {
fileRecordedWav = new File("Some/Path/Filename.wav");
final AudioFileFormat.Type afType = AudioFileFormat.Type.WAVE;
thrdRecording = new Thread() {
@Override
public void run() {
try {
tdLine.open(audioformat);
int bufferSize = (int) audioformat.getSampleRate()
* audioformat.getFrameSize(); //1Sec/40 = 25 milli Second
System.out.println("bufferSize:" + bufferSize);
//INI Save File
final PipedOutputStream SrcSavePOStream = new PipedOutputStream();
final PipedInputStream SnkSavePIStream = new PipedInputStream();
SnkSavePIStream.connect(SrcSavePOStream);
aisRecording = new AudioInputStream((InputStream)SnkSavePIStream,
audioformat, AudioSystem.NOT_SPECIFIED);
Runnable runnableSave = () -> {
try {
AudioSystem.write(aisRecording, afType, fileRecordedWav);
} catch (IOException ex) { /*Pipe broken*/}
};
Thread threadSave = new Thread(runnableSave);
threadSave.start();
//END Save File
// INI Graph File
final PipedOutputStream SrcPlotPOStream = new PipedOutputStream();
final PipedInputStream SnkPlotPIStream = new PipedInputStream();
SnkPlotPIStream.connect(SrcPlotPOStream);
Runnable runnablePlot = () -> {
try {
int qtyBytes;
byte[] incomingBytes = new byte[bufferSize];
int numBytesPerSample = audioformat.getSampleSizeInBits()/8;
int numChannels = audioformat.getChannels();
int frameSize = audioformat.getFrameSize();
int bytesframeSize = numBytesPerSample*numChannels;
Double sampleRateTime = (double)audioformat.getSampleRate();
while ((qtyBytes = SnkPlotPIStream.read(incomingBytes)) != -1) {
byte[] bytesSamples = new byte[qtyBytes];
System.arraycopy(incomingBytes, 0, bytesSamples, 0, qtyBytes);
int qtySamples = qtyBytes/frameSize;
double[] samplesTime = getSamplesBuffer(bytesSamples,
numBytesPerSample, numChannels, "left", 0, qtySamples);
double pow = Math.floor(Math.log(qtySamples) / Math.log(2.0));
int sizePower2 = (int)Math.pow(2.0, pow);
double[] freqs = new double[qtySamples];
double[] samplesPower2 = new double[sizePower2];
System.arraycopy(samplesTime, 0, samplesPower2, 0, sizePower2);
double[] time = new double[qtySamples];
double counter = 0.0;
for (int i = 0; i < time.length; i++) {
time[i] = counter / sampleRateTime;//
counter++;
freqs[i] = (double)i/qtySamples*sampleRateTime/1000.0;
}
// INI Time
SwingWorker swingWorkerPlotTime = new SwingWorker() {
PanelChart panelChartTimeSound = new PanelChart();
@Override protected Void doInBackground() throws Exception {
panelChartTimeSound.addVble("sound", time, samplesTime, Color.GREEN);
return null;
}
@Override protected void done() {
if (panelChartTimeSound.hasPlottable()) {
setPanelInPanel(jpMakeSoundTime,
panelChartTimeSound.getChart(jpMakeSoundTime.getWidth(), jpMakeSoundTime.getHeight()));
panelChartTimeSound.delAllVble();
panelChartTimeSound = null;
}
}
};
swingWorkerPlotTime.execute();
// END Time
// INI FFT
double[] fft = FourierTransform.customFFT(samplesPower2);
double[] halfFFT = new double[sizePower2/2];
double[] halfFreq = new double[sizePower2/2];
System.arraycopy(freqs, 0, halfFreq, 0, halfFreq.length);
System.arraycopy(fft, 0, halfFFT, 0, halfFFT.length);
SwingWorker swingWorkerPlotFreq = new SwingWorker() {
PanelChart panelChartFreqSound = new PanelChart();
@Override protected Void doInBackground() throws Exception {
panelChartFreqSound.addVble("sound", halfFreq, halfFFT, new Color(0, 255, 192));
return null;
}
@Override protected void done() {
if (panelChartFreqSound.hasPlottable()) {
setPanelInPanel(jpMakeSoundFFT,
panelChartFreqSound.getChart(jpMakeSoundFFT.getWidth(), jpMakeSoundFFT.getHeight()));
panelChartFreqSound.delAllVble();
panelChartFreqSound = null;
}
}
};
swingWorkerPlotFreq.execute();
// END FFT
}
} catch (IOException ex) {
System.out.println("runnablePlot:" + ex.toString());
}
};
Thread threadPlot = new Thread(runnablePlot);
threadPlot.start();
// END Graph File
// INI Microphone Capture
byte[] buffer = new byte[bufferSize];
tdLine.start();
while (true) {
int count = tdLine.read(buffer, 0, buffer.length);
if (count > 0) {
SrcSavePOStream.write(buffer);
SrcPlotPOStream.write(buffer);
}
}
// END Microphone Capture
} catch (LineUnavailableException | IOException ex) {
System.out.println("thrdRecording.run:" + ex.toString());
}
}
};
thrdRecording.start();
}