Итак, я пытаюсь протестировать код, который анализирует объем некоторых данных PCM. Я получаю некоторые странные измерения объема, которые не имеют смысла с данными, которые я получаю от дерзости. Кажется, что мои измерения повсюду.
Я не уверен, связана ли моя ошибка с тем, как я читаю данные WAV, или с тем, как я вычисляю объем.
Итак, вот где я читаю данные в виде байтов и преобразовываю их в короткие, поскольку это 16-битный PCM.
InputStream pcmStream = this.getClass().getClassLoader().getResourceAsStream("Test-16Bit-PCM.wav");
ArrayList<Byte> bytes = new ArrayList<>();
int b = pcmStream.read();
while(b != -1)
{
bytes.add((byte)b);
b = pcmStream.read();
}
// First 44 bytes of WAV file are file info, we already know PCM properties since we recorded test audio
byte [] bytesArray = new byte[bytes.size()-44];
for(int i = 44; i < bytes.size(); i++)
{
bytesArray[i-44] = bytes.get(i);
}
bytes = null;
pcmStream = null;
short [] pcm = new short[bytesArray.length/2];
ByteBuffer bb = ByteBuffer.wrap(bytesArray).asShortBuffer().get(pcm);
bb.order(ByteOrder.LITTLE_ENDIAN);
bb.asShortBuffer().get(pcm);
bytesArray = null;
Затем этот short [] передается непосредственно моему анализатору, затем я разбиваю данные на временные интервалы по 0,1 секунды и усредняю объем по каждому временному шагу.
Здесь я рассчитываю среднеквадратичное значение и дБ
double sumOfSamples = 0;
double numOfSamples = settings.shortsPerTimeStep();
for(int i = start; i < start+settings.shortsPerTimeStep(); i++)
{
sumOfSamples = originalPcm[i]*originalPcm[i];
}
double rms = Math.sqrt(sumOfSamples/numOfSamples);
// Convert to decibels
calculatedVolume = 20*Math.log10(rms/20);
Звук, который я читаю, был записан с разрешением 44100 MONO и сохранен как WAV 16 Signed PCM в Audacity. Не уверен, что я делаю неправильно.
Любая помощь будет оценена! Спасибо
Обновлено: Выяснилось, что я неправильно читал данные WAV. Я исправил это, добавив end little endianess. Однако я все еще не понимаю, как рассчитать объем. Значения лучше, но все еще трудно расшифровать, и я не уверен, в каких единицах измерения находится мое среднеквадратичное значение и в каких единицах должно быть эталонное значение.




У вас есть ошибка в ваших вычислениях - sumOfSamples = originalPcm[i]*originalPcm[i]; должно быть sumOfSamples += originalPcm[i]*originalPcm[i];, поэтому вы будете накапливать значения.
Что касается эталонного значения - почему вы используете 20? Обычно вы используете наименьшее возможное значение (которое в данном случае равно 1), или вы можете использовать максимальное значение (которое равно sqrt (32768)), и все ваши значения будут ниже этого, поэтому вы получите отрицательные значения дБ. .