在网上搜索了数周,我来到了以下代码 计算Java中给定
.wav
文件的幅度。现在 问题是它无法像大型音频文件那样很好地扩展 假设30分钟,生产数组很大。
要绘制它,我使用的是JavaFX created this repository(ps的代码可能会有所不同,因为我现在有几天没提交)。
所以:
/**
* Get Wav Amplitudes
*
* @param file
* @return
* @throws UnsupportedAudioFileException
* @throws IOException
*/
private int[] getWavAmplitudes(File file) throws UnsupportedAudioFileException , IOException {
System.out.println("Calculting WAV amplitudes");
int[] amplitudes = null;
//Get Audio input stream
try (AudioInputStream input = AudioSystem.getAudioInputStream(file)) {
AudioFormat baseFormat = input.getFormat();
Encoding encoding = AudioFormat.Encoding.PCM_UNSIGNED;
float sampleRate = baseFormat.getSampleRate();
int numChannels = baseFormat.getChannels();
AudioFormat decodedFormat = new AudioFormat(encoding, sampleRate, 16, numChannels, numChannels * 2, sampleRate, false);
int available = input.available();
amplitudes = new int[available];
//Get the PCM Decoded Audio Input Stream
try (AudioInputStream pcmDecodedInput = AudioSystem.getAudioInputStream(decodedFormat, input)) {
final int BUFFER_SIZE = 4096; //this is actually bytes
System.out.println(available);
//Create a buffer
byte[] buffer = new byte[BUFFER_SIZE];
//Read all the available data on chunks
int counter = 0;
while (pcmDecodedInput.readNBytes(buffer, 0, BUFFER_SIZE) > 0)
for (int i = 0; i < buffer.length - 1; i += 2, counter += 2) {
if (counter == available)
break;
amplitudes[counter] = ( ( buffer[i + 1] << 8 ) | buffer[i] & 0xff ) << 16;
amplitudes[counter] /= 32767;
amplitudes[counter] *= WAVEFORM_HEIGHT_COEFFICIENT;
}
} catch (Exception ex) {
ex.printStackTrace();
}
} catch (Exception ex) {
ex.printStackTrace();
}
//System.out.println("Finished Calculting amplitudes");
return amplitudes;
}
然后我像这样处理振幅:
/**
* Process the amplitudes
*
* @param sourcePcmData
* @return An array with amplitudes
*/
private float[] processAmplitudes(int[] sourcePcmData) {
System.out.println("Processing WAV amplitudes");
//The width of the resulting waveform panel
int width = waveVisualization.width;
System.out.println("P Width :" + width);
float[] waveData = new float[width];
int samplesPerPixel = sourcePcmData.length / width;
//Calculate
float nValue;
for (int w = 0; w < width; w++) {
//if (isCancelled())
// break;
//For performance keep it here
int c = w * samplesPerPixel;
nValue = 0.0f;
//Keep going
for (int s = 0; s < samplesPerPixel; s++) {
//if (isCancelled())
// break;
nValue += ( Math.abs(sourcePcmData[c + s]) / 65536.0f );
}
//Set WaveData
waveData[w] = nValue / samplesPerPixel;
}
System.out.println("Finished Processing amplitudes");
return waveData;
}
输出是这样的:
答案 0 :(得分:1)
找到了一个非常好的解决方案,尽管我不确定最终数组的最大大小应该是多少,经过一些实验@receiver(post_save, sender= ww_manholes)
def copy_id(sender, **kwargs):
data = ww_manholes.objects.get(id=kwargs.get('instance').id)
data.no_man = data.id
data.save()
似乎是一个很好的数字。
因此方法 getWavAmplitudes 变为:
100.000
非常欢迎任何建议和改进。