简体   繁体   English

在Web Audio API中,有没有办法设置最大音量?

[英]In the Web Audio API, is there a way to set a maximum volume?

I know you can boost or reduce volume with gain.我知道您可以通过增益来提高或降低音量。 I was wondering if there was a way (perhaps via a node) to cap the maximum volume of the output - not reducing any audio below that max value.我想知道是否有办法(可能通过节点)来限制 output 的最大音量 - 不会减少低于该最大值的任何音频。 It is acceptable if there is distortion for audio that gets capped like this.如果像这样被封顶的音频存在失真,这是可以接受的。

An alternative that might be simpler is to use a WaveShaperNode .另一种可能更简单的方法是使用WaveShaperNode I think a curve equal to [-1, 0, 1] will do what you want, clamping values to +/-1.我认为等于 [-1, 0, 1] 的curve可以满足您的要求,将值钳制为 +/-1。 If you don't oversample, there won't be any additional delay.如果您不过度采样,则不会有任何额外的延迟。

Note that I'm pretty sure all browsers implement this kind of clamping before sending audio to the speakers.请注意,我很确定所有浏览器都会在向扬声器发送音频之前实现这种钳位。

This is not possible with any of the built-in AudioNodes.这对于任何内置的 AudioNode 都是不可能的。 But it can be achieved with a custom AudioWorklet.但这可以通过自定义 AudioWorklet 来实现。 I recently published a package which does exactly that.我最近发布了一个 package 正是这样做的。 It's called limiter-audio-worklet .它被称为limiter-audio-worklet

It exports two functions:它导出两个函数:

import { addLimiterAudioWorkletModule, createLimiterAudioWorkletNode } from 'limiter-audio-worklet';

The first function can be used to add the AudioWorklet to a particular AudioContext .第一个 function 可用于将AudioWorklet添加到特定的AudioContext

await addLimiterAudioWorkletModule((url) => {
    audioContext.audioWorklet.addModule(url);
});

Once that is done the actual AudioWorkletNode can be created like this:完成后,可以像这样创建实际的AudioWorkletNode

const limiterAudioWorkletNode = createLimiterAudioWorkletNode(
    AudioWorkletNode,
    audioContext,
    { attack: 0 }
);

If you set the attack two zero you get the desired effect.如果您将attack设置为两个零,您将获得所需的效果。 Everything above +1/-1 gets clamped. +1/-1 以上的所有内容都会被限制。 If you increase the attack it will transition smoother using a look ahead.如果你增加attack ,它会使用前瞻来平滑过渡。 This will introduce a small delay (of the same size) but sounds much nicer.这将引入一个小的延迟(相同大小),但听起来要好得多。

Of course it's also necessary to connect the previously created limiterAudioWorkletNode close to the end of your audio graph.当然,还需要将先前创建的limiterAudioWorkletNode连接到靠近音频图的末尾。

yourLastAudioNode
    .connect(limiterAudioWorkletNode)
    .connect(audioContext.destination);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM