gpt4 book ai didi

java - java中如何计算音频信号的分贝并录制音频?

转载 作者:行者123 更新时间:2023-12-02 02:17:26 28 4
gpt4 key购买 nike

public TargetDataLine targetDataLine;
private static AudioFormat getAudioFormat()
{
return new AudioFormat(16000, 16, 2, true, false);
}
AudioFormat a = getAudioFormat();
DataLine.Info info = new DataLine.Info(TargetDataLine.class, a);
targetDataLine = (TargetDataLine) AudioSystem.getLine(info);
targetDataLine.open(a);
targetDataLine.start();
AudioInputStream ais = new AudioInputStream(targetDataLine);
AudioSystem.write(ais, AudioFileFormat.Type.WAVE, new File("record.wav"));
  1. 如何同时计算音频的分贝数?
  2. 如何计算现有 wav 文件的分贝?

最佳答案

假设一:您希望在录制结束时处理并保存数据。

  • 使用 TargetDataLine.read() 将数据读入临时短缓冲区
  • 使用 ByteArrayOutputStream.write() 将数据写入 ByteArrayOutputStream
  • ByteArrayOutputStream 转换为 byte[] 数组。
  • 将字节数据编码为样本
  • 计算 RMS、峰值等并将其转换为分贝。
  • 使用 byte[] 数组构造 ByteArrayInputStream
  • 使用 AudioSystem.write() 生成音频文件

    int numBytesRead = 0;
    byte[] buffer = new byte[1024];
    ByteArrayOutputStream outStream = new ByteArrayOutputStream();
    boolean stopRecording = false;

    while (!stopRecording) {
    numBytesRead = targetDataLine.read(buffer, 0, buffer.length);
    //short[] samples = encodeToSample(buffer, buffer.length);
    // process samples - calculate decibels

    if (numBytesRead > 0) {
    outStream.write(buffer, 0, numBytesRead);
    }
    }

    outStream.close();

    byte[] data = outStream.toByteArray();
    ByteArrayInputStream bais = new ByteArrayInputStream(data);
    AudioInputStream ais = new AudioInputStream(bais, a, data.length);

    AudioSystem.write(ais, AudioFileFormat.Type.WAVE, new File("record.wav"));

假设二:您希望连续读取、处理和保存数据。

您需要一个中间类才能将 ByteArrayOutputStream 转换为 ByteArrayInputStream。在后台线程中捕获音频数据,并在另一个线程中处理并在所需数据量可用时保存数据。

编码:您可以对 byte[] 数组中的音频样本进行编码。在您的情况下,两个连续的字节产生一个样本。您将陆续获得两个 channel 的样本。如果您有任何特定于 channel 的处理,那么您需要分离每个 channel 的样本。以下代码片段可能会帮助您进行编码 -

public static short[] encodeToSample(byte[] srcBuffer, int numBytes) {
byte[] tempBuffer = new byte[2];
int nSamples = numBytes / 2;
short[] samples = new short[nSamples]; // 16-bit signed value

for (int i = 0; i < nSamples; i++) {
tempBuffer[0] = srcBuffer[2 * i];
tempBuffer[1] = srcBuffer[2 * i + 1];
samples[i] = bytesToShort(tempBuffer);
}

return samples;
}

public static short bytesToShort(byte [] buffer) {
ByteBuffer bb = ByteBuffer.allocate(2);
bb.order(ByteOrder.BIG_ENDIAN);
bb.put(buffer[0]);
bb.put(buffer[1]);
return bb.getShort(0);
}

分贝:Db 是给定电平与引用电平的对数比。例如,如果您想以 dBFS 为单位计算 RMS/Peak,以下代码片段可能会对您有所帮助。

public static void calculatePeakAndRms(short [] samples) {
double sumOfSampleSq = 0.0; // sum of square of normalized samples.
double peakSample = 0.0; // peak sample.

for (short sample : samples) {
double normSample = (double) sample / 32767; // normalized the sample with maximum value.
sumOfSampleSq += (normSample * normSample);
if (Math.abs(sample) > peakSample) {
peakSample = Math.abs(sample);
}
}

double rms = 10*Math.log10(sumOfSampleSq / samples.length);
double peak = 20*Math.log10(peakSample / 32767);
}

关于java - java中如何计算音频信号的分贝并录制音频?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49097889/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com