0

我有一个 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 似乎都在做基本相同的事情(为什么有两种方法可以做同样的事情?),即只是加快或减慢播放速度,所以不是这样。

4

1 回答 1

1

First, there's a small issue with the code: you connect the analyser to the destination twice. You don't actually need to connect it at all.

Second, I think the reason you're getting all -infinity values is because you call getFloatFrequencyData right after you start the source. There's a good chance that no samples have been played so the analyser only has buffers of all zeros.

You need to call getFloatFrequencyData after a bit of time to see non-zero values.

Third, I don't think this will work at all, even for shifting the pitch of an oscillator. getFloatFrequencyData only returns the magnitude information. You will need the phase information for the harmonics to get everything shifted correctly. Currently there's no way to get the phase information.

Fourth, if you have an AudioBuffer with the data you need, consider using the playbackRate to change the pitch. Not sure if this will produce the shift you want.

于 2020-08-03T23:01:49.710 回答