我从这样的音频中记录FFT(“ 快速傅立叶变换”)样本:
const no_samples = 100;
const samples = [];
for (let i = 0, l = no_samples; i < l; ++i) {
samples.push({ sample: new Uint8Array(this.sampleSize), time:-1 });
}
var lambdaToRemove = null;
let samplesDone = 0;
let start = -1;
let second = 0;
this.scriptProcessor.addEventListener("audioprocess", lambdaToRemove =
/**
* @param {AudioProcessingEvent} event
* */
(event) => {
// firefox provides data even before user allows acces to microphone
if (!this.mediaAllocated) {
console.log("Sample before media was allocated!");
return;
}
// AudioAnalyser - https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode
this.analyser.getByteFrequencyData(samples[samplesDone].sample);
++samplesDone;
if (samplesDone >= no_samples) {
this.scriptProcessor.removeEventListener("audioprocess", lambdaToRemove);
resolve(samples);
}
});
相关行是:
this.analyser.getByteFrequencyData(samples[samplesDone].sample);
此调用使用FFT数据填充Uint8Array
。长度是预先设置并固定的。
所以现在我有了一个包含Uint8Array
的数组,它们代表录制的音频。如何将数据反馈回一些音频流,以便在浏览器中播放?
我想将声音录制为FFT,然后进行修改然后再播放。
我尝试过:
/** @type {{time:number, sample:Uint8Array}[]} **/
const samples = this.getSamples();
this.oscilator = this.audioContext.createOscillator();
this.oscilator.connect(this.audioContext.destination);
let ctime = 0;
const ssize = samples[0].sample.length;
const imaginary = new Float32Array(ssize);
const half255 = 255 / 2;
this.oscilator.start();
for (let i = 0, l = samples.length; i < l; ++i) {
const sample = samples[i];
await sleep(sample.time - ctime);
ctime = sample.time;
const real = new Float32Array(ssize);
// convert 0->255 to -1.0->1.0
for (let is = 0, ls = real.length; is < ls; ++is) {
real[is] = (sample.sample[is] / half255) / half255;
}
const wave = this.audioContext.createPeriodicWave(real, imaginary);
this.oscilator.setPeriodicWave(wave);
}
this.isPlaying = false;
this.oscilator.stop();
但这听起来像是蜂鸣器。必须有一种方法可以从一个波浪过渡到另一个波浪。
答案 0 :(得分:0)
您必须使用正弦波重新合成音频,因为这基本上就是FFT分解的结果。
特别是,您将实现一种vocoder。
您可以将在特定时间点的FFT值数组描绘为该时间点的正弦波振荡器的幅度,其中fft[0]
为0 hz振荡器,fft[n - 1]
为振荡器调到原始采样率的一半(奈奎斯特定理)。
不过,重新合成的质量可能不会很好。 FFT阵列越大,您拥有的频率分辨率就越好(可能以时间分辨率为代价)。