Чтение WAV-файла и вычисление RMS

Итак, я пытаюсь протестировать код, который анализирует объем некоторых данных 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. Однако я все еще не понимаю, как рассчитать объем. Значения лучше, но все еще трудно расшифровать, и я не уверен, в каких единицах измерения находится мое среднеквадратичное значение и в каких единицах должно быть эталонное значение.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
1 353
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Другие вопросы по теме