【问题标题】:using WebAudio AnalyserNode.getFloatFrequencyData() to shift pitch of a BufferSource使用 WebAudio AnalyserNode.getFloatFrequencyData() 来改变 BufferSource 的音高
【发布时间】:2020-11-23 18:59:06
【问题描述】:

我有一个 BufferSource,我是这样创建的:

const proxyUrl = location.origin == 'file://' ? 'https://cors-anywhere.herokuapp.com/' : '';
const request = new XMLHttpRequest();
request.open('GET', proxyUrl + 'http://heliosophiclabs.com/~mad/projects/mad-music/non.mp3', true);
// request.open('GET', 'non.mp3', true);
request.responseType = 'arraybuffer';
request.onload = () => {
    audioCtx.decodeAudioData(request.response, buffer => {
        buff = buffer;
    }, err => {
        console.error(err);
    });
}
request.send();

是的,CORS 解决方法很可悲,但这是我发现无需运行 HTTP 服务器即可在本地工作的方式。总之……

我想改变这个缓冲区的音高。我尝试了各种不同的形式:

const source = audioCtx.createBufferSource();
source.buffer = buff;

const analyser = audioCtx.createAnalyser();
analyser.connect(audioCtx.destination);
analyser.minDecibels = -140;
analyser.maxDecibels = 0;

analyser.smoothingTimeConstant = 0.8;
analyser.fftSize = 2048;
const dataArray = new Float32Array(analyser.frequencyBinCount);
source.connect(analyser);
analyser.connect(audioCtx.destination);
source.start(0);
analyser.getFloatFrequencyData(dataArray);
console.log('dataArray', dataArray);

一切都无济于事。无论我尝试什么,dataArray 总是充满 -Infinity 值。

我的想法是获取这个频域数据,然后将所有频率向上/向下移动一些量,并从中创建一个新的振荡器节点,如下所示:

    const wave = audioCtx.createPeriodicWave(real, waveCompnents);
    oscillator.setPeriodicWave(wave);

无论如何。如果有人对如何改变音高有更好的想法,我很想听听。可悲的是,detune 和 PlaybackRate 似乎都在做基本相同的事情(为什么有两种方法可以做同样的事情?),即只是加快或减慢播放速度,所以不是这样。

【问题讨论】:

    标签: web-audio-api audiobuffer


    【解决方案1】:

    首先,代码存在一个小问题:您将analyser 连接到目的地两次。您实际上根本不需要连接它。

    其次,我认为您获得所有 -infinity 值的原因是因为您在启动源代码后立即调用getFloatFrequencyData。很有可能没有播放任何样本,因此分析器只有全零的缓冲区。

    您需要在一段时间后调用getFloatFrequencyData 才能看到非零值。

    第三,我认为这根本不起作用,即使是用于改​​变振荡器的音高。 getFloatFrequencyData 只返回幅度信息。您将需要谐波的相位信息才能正确移动所有内容。目前无法获取相位信息。

    第四,如果您有一个包含所需数据的AudioBuffer,请考虑使用playbackRate 更改音高。不确定这是否会产生您想要的转变。

    【讨论】:

    • 我终于通过使用 Uint8Array 和 getByteFrequencyData 而不是 Float32Array 和 getFloatFrequencyData 使分析器工作。但是,是的,您缺少相位信息是对的,所以这很糟糕。至于使用playbackRate,没有。就像我说的:可悲的是,失谐和回放率似乎都在做基本相同的事情(为什么有两种方法可以做同样的事情?),即只是加快或减慢播放速度,所以不是这样。
    • 这对我来说没有意义。 getByteFrequencyData 基本上是 getFloatFrequencyData,其浮点值映射到范围 0-255。如果一个有效,另一个也应该。但我很高兴你能做到这一点。太糟糕了,它不能为您提供所需的东西。人们已经要求在 WebAudio 中使用音高转换器。
    • 至于音高转换,这是本练习的重点,我发现:github.com/ChenMachluf/pitch-shift-node。现在......我只需要弄清楚如何在严格的客户端(不是 NodeJS)应用程序中使用 npm 包。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-13
    • 2011-12-17
    • 2013-08-23
    • 2019-05-21
    • 2012-01-20
    • 1970-01-01
    • 2010-09-10
    相关资源
    最近更新 更多