Я записываю 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);
Этот вызовзаполняет Uint8Array
данными FFT.Длина предварительно установлена и фиксирована.
Итак, теперь у меня есть массив с Uint8Array
s, представляющий записанный звук.Как передать данные обратно в аудиопоток для воспроизведения в браузере?
Я хотел бы записать звук в формате 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();
Но это просто звучит как зуммер.Должен быть способ перехода от одной волны к другой.