- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
实现 Peak Meter 的正确方法是什么?就像 Logic Pro 中的那些使用网络音频 API AnalyserNode
?
我知道AnalyserNode.getFloatFrequencyData()
返回分贝值,但如何组合这些值以获得要在仪表中显示的值?您是否像下面的代码示例一样取最大值(其中 analyserData
来自 getFloatFrequencyData()
:
let peak = -Infinity;
for (let i = 0; i < analyserData.length; i++) {
const x = analyserData[i];
if (x > peak) {
peak = x;
}
}
检查仅取最大值的一些输出使得这看起来不是正确的方法。我错了吗?
或者,改用 ScriptProcessorNode
会更好吗?这种方法有何不同?
最佳答案
如果您在一帧中取 getFloatFrequencyData()
结果的最大值,那么您测量的是单个频率的音频功率(取其最强大)。您实际想要测量的是任何频率处的峰值——换句话说,您想要不使用频率数据,但未处理的样本未被分成频率仓。
问题是您必须自己计算分贝功率。这是相当简单的算术:你取一些样本(一个或多个),对它们进行平方,然后取平均值。请注意,即使是“峰值”仪表也可能会进行平均 - 只是在更短的时间范围内。
这是一个完整的例子。 (警告:发出声音。)
document.getElementById('start').addEventListener('click', () => {
const context = new(window.AudioContext || window.webkitAudioContext)();
const oscillator = context.createOscillator();
oscillator.type = 'square';
oscillator.frequency.value = 440;
oscillator.start();
const gain1 = context.createGain();
const analyser = context.createAnalyser();
// Reduce output level to not hurt your ears.
const gain2 = context.createGain();
gain2.gain.value = 0.01;
oscillator.connect(gain1);
gain1.connect(analyser);
analyser.connect(gain2);
gain2.connect(context.destination);
function displayNumber(id, value) {
const meter = document.getElementById(id + '-level');
const text = document.getElementById(id + '-level-text');
text.textContent = value.toFixed(2);
meter.value = isFinite(value) ? value : meter.min;
}
// Time domain samples are always provided with the count of
// fftSize even though there is no FFT involved.
// (Note that fftSize can only have particular values, not an
// arbitrary integer.)
analyser.fftSize = 2048;
const sampleBuffer = new Float32Array(analyser.fftSize);
function loop() {
// Vary power of input to analyser. Linear in amplitude, so
// nonlinear in dB power.
gain1.gain.value = 0.5 * (1 + Math.sin(Date.now() / 4e2));
analyser.getFloatTimeDomainData(sampleBuffer);
// Compute average power over the interval.
let sumOfSquares = 0;
for (let i = 0; i < sampleBuffer.length; i++) {
sumOfSquares += sampleBuffer[i] ** 2;
}
const avgPowerDecibels = 10 * Math.log10(sumOfSquares / sampleBuffer.length);
// Compute peak instantaneous power over the interval.
let peakInstantaneousPower = 0;
for (let i = 0; i < sampleBuffer.length; i++) {
const power = sampleBuffer[i] ** 2;
peakInstantaneousPower = Math.max(power, peakInstantaneousPower);
}
const peakInstantaneousPowerDecibels = 10 * Math.log10(peakInstantaneousPower);
// Note that you should then add or subtract as appropriate to
// get the _reference level_ suitable for your application.
// Display value.
displayNumber('avg', avgPowerDecibels);
displayNumber('inst', peakInstantaneousPowerDecibels);
requestAnimationFrame(loop);
}
loop();
});
<button id="start">Start</button>
<p>
Short average
<meter id="avg-level" min="-100" max="10" value="-100"></meter>
<span id="avg-level-text">—</span> dB
</p>
<p>
Instantaneous
<meter id="inst-level" min="-100" max="10" value="-100"></meter>
<span id="inst-level-text">—</span> dB
</p>
关于javascript - Web Audio API 使用 AnalyserNode 创建峰值计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44360301/
我想捕捉一个小时间窗口(即 ~1 秒)的傅里叶变换。 let audioCtx = new AudioContext(); let analyser = audioCtx.createAnalyser
WebAudio的AnalyserNode有一个FFT来获取声音信号的频域数据。我不明白 FFT 的窗口函数是如何定义的。是否可以更改窗口大小甚至窗口函数(即 Hanning 或 Blackman)?
我正在尝试使用 Web Audio API 编写自相关算法。自相关仅依赖于时域中的数据,而不依赖于频域中的数据,因此我仅使用 getByteTimeDomainData()。我很难找到有关 Analy
我正在使用 Web Audio API 来显示正在播放的音频的可视化效果。我有一个 控制播放的元素,然后我通过创建 MediaElementSource 将它连接到 Web Audio API来自
代码应该流式传输任何 url 并提供音频的可视化。不幸的是,可视化工具无法正常工作。可视化依赖于来自 AnalyzerNode 的数据,它总是返回空数据。为什么这段代码中的 AnalyserNode
我想我可能对使用 AnalyserNode 有点困惑。我目前将我的 userAudio 流“输入”连接到 AnalyserNode。然后我使用 getByteFrequencyData() 填充一个
在Web Audio API中,AnalyserNode的getFloatFrequencyData()和 getByteFrequencyData()方法为我们提供FFT分析数据,其域是频率,余域是
我正在使用 Web Audio API,但有些行为我无法理解。 var audio = document.querySelector('audio'); var context = new Audio
我无法在移动设备中使用 AudioContext.createMediaElementSource 使 AnalayserNode 工作。它不适用于 iOS 上的 Safari,也不适用于 Andro
背景 我的目标是创建一个基于 JavaScript 的网络应用程序来分析和显示音频源中的频率信息,包括页面内源( 标记)和从客户端麦克风流出的信号。我正在路上:) 作为一名敏锐的萨克斯管演奏者,我的目
所以我想我明白 getFloatFrequencyData很不错。如 getFloatFrequencyData返回一个包含 1024 个值的数组,每个值代表一个频率区间/范围的音量。在采样率为 44
实现 Peak Meter 的正确方法是什么?就像 Logic Pro 中的那些使用网络音频 API AnalyserNode ? 我知道AnalyserNode.getFloatFrequencyD
我正在尝试使用 Web-Audio 的分析器节点并不断从中得到奇怪的结果。 代码: var self = this; var bufferSize = 512; var spectrum = new
这似乎是一个常见问题 - Javascript Web Audio API AnalyserNode Not Working - 但我不确定我是否在我的实现中找到了边缘案例。 我使用 createMe
我一整天都被这个问题困扰了。尝试从 getUserMedia 中分离源并分别可视化左 channel 和右 channel 。无论我做什么,每个可视化工具都停留在单声道状态。我使用的源是立体声(如果我
网络浏览器中的音频分析可以通过 AnalyserNode of Web Audio API 轻松执行。 Node.js 有类似的东西吗? 最佳答案 您可能对 https://www.npmjs.com
我是一名优秀的程序员,十分优秀!