Ответ 1
Есть две основные причины, по которым нужно получить "объем": 1) обнаруживают, когда источник "зажимает", то есть абсолютное значение сигнала проходит на заданном уровне, обычно очень близком к 1.0, где он начнет отсекать. 2) дать пользователю почувствовать, насколько громко их сигнал.
Причина, по которой я перечисляю их отдельно, состоит в том, что сначала требуется, чтобы вы обрабатывали каждый образец, потому что в противном случае вы могли бы пропустить короткий переходный период. Для этого вам нужно будет использовать ScriptProcessor node, и вам придется перебирать каждый образец в буфере внутри onaudioprocess, чтобы искать абсолютные значения выше уровня вашего клипа. Тогда вы могли бы просто определить уровень RMS - просто суммируйте квадраты каждого образца, разделите на N и возьмите квадратный корень. НЕ обрабатывайте изнутри onaudioprocess, хотя - задайте значения, которые вы получаете по запросуAnimationFrame.
Вы также можете использовать AnalyserNode для определения уровня и просто усреднить данные, вроде того, что приведенный выше ответ в getAverageVolume. Однако вышеприведенный ответ НЕ является хорошим использованием ScriptProcessor - на самом деле он вообще не обрабатывает script node, даже не передавая данные, просто используя его, как обратный вызов таймера. Вы были бы лучше, если бы использовались requestAnimationFrame в качестве визуального обратного вызова; никогда не устанавливайте макеты или визуальные параметры изнутри onaudioprocess, как это, или вы попрошайки трясти свою аудиосистему. Если вам не требуется обнаружение клипов, просто сделайте getByteFrequencyCount/getAverageVolume сверху на AnalyserNode (но вы должны свести к минимуму количество групп в Анализаторе - 64 - это минимум, я думаю), и вы должны предварительно распределить и повторно использовать Uint8Array, а не выделять его каждый раз (что будет усиливать сбор мусора).