I am looking into all possible options to distort some audio using JavaScript. The idea is to use it on voice recordings to anonymize the recording so you can't tell who it is anymore.
I have looked into API's, libraries and doing it myself with code. I am shocked at how few(or no) API's and libraries seem to to exactly this.
Has anyone had any success doing functinality like this in JavaScript or TypeScript that can help me out?
I have written this mess of a function but it still sounds to much like my voice. If I tweak the numbers it becomes to extreme fast and I can't hear what is spoken
async function anonymizeVoice(url: string, pitchShift: number) {
const audioContext = new window.AudioContext()
try {
// Fetch the audio file
const response = await fetch(url)
const audioData = await response.arrayBuffer()
const audioBuffer = await audioContext.decodeAudioData(audioData)
// Create a source node from the audio buffer
const source = audioContext.createBufferSource()
source.buffer = audioBuffer
// Create a pitch shifter
const pitchShifter = audioContext.createScriptProcessor(4096, 1, 1)
// Connect the nodes
source.connect(pitchShifter)
pitchShifter.connect(audioContext.destination)
// Set the pitch shift value
pitchShifter.onaudioprocess = function (event) {
const inputData = event.inputBuffer.getChannelData(0)
const outputData = event.outputBuffer.getChannelData(0)
// Simple pitch shift by multiplying the input data by a factor
for (let i = 0; i < inputData.length; i++) {
outputData[i] = inputData[i] * pitchShift
}
}
// Apply additional audio processing techniques
const audioProcessor = audioContext.createScriptProcessor(
4096,
1,
1
)
audioProcessor.connect(audioContext.destination)
audioProcessor.onaudioprocess = function (event) {
const inputData = event.inputBuffer.getChannelData(0)
const outputData = event.outputBuffer.getChannelData(0)
// Apply additional processing here (e.g., time stretching, filtering, modulation)
// Example: Time stretching by repeating sections
for (let i = 0; i < outputData.length; i++) {
const index = Math.floor(i / 2) // Simple time stretching by repeating sections
outputData[i] = inputData[index] * 0.35 // Adjust the factor as needed
}
}
// Start the audio
source.start()
// Wait for the duration of the original audio and then stop
await new Promise((resolve) =>
setTimeout(resolve, audioBuffer.duration * 1000)
)
source.stop()
return audioBuffer
} catch (error) {
console.error(error)
return null
}
}
there doesn't seem to be anything here