'Web Audio API - Cloning an audioBuffer
I have a deepClone function that I use throughout my program that clones all the properties and values of one object and returns the cloned object (see code below). I am now wanting to include an audioBuffer in the object and successfully copy it to the returning object. Is there a way to modify function to include this functionality?
TO NOTE: Not all objects passed to the deepClone function will include an audioBuffer, therefore it should be able to cope and successfully clone objects with and without them.
Edit: Can someone think of a way to combine JSON.parse(JSON.stringify(object)) with the solution provided as one of the answers? I.e. check properties of the object as the cloning is happening, if (property == 'trackBuffer') clone it differently to the rest?
deepClone function:
function deepClone (object) {
return JSON.parse(JSON.stringify(object));
};
/**
* Utility function for deep object cloning
*
* @param {object} obj Object to be cloned
* @returns {object} The deep-cloned object
*/
function deepClone (object) {
return JSON.parse(JSON.stringify(object));
};
// Create audio context
var context = new AudioContext();
// Create empty audio buffer
var audioBuffer = context.createBuffer(2, 22050, 44100);
// Create object to be cloned
var track = {
prop1: "val1",
prop2: "val2",
trackBuffer: audioBuffer
};
// Log before clone
console.log("before clone, track: \n", track);
// Clone track
var clonedTrack = deepClone(track);
// Log after clone
console.log("after clone, clonedTrack: \n", clonedTrack);
As you can see from the code snippet, the clonedTrack's trackBuffer is converted to an empty object which is to be expected from JSON.parse(JSON.stringify(object));.
What is the best way to modify deepClone to successfully clone the audioBuffer but keep existing functionality?
Any help would be greatly appreciated, thanks!
Solution 1:[1]
My suggestion is that handling AudioBuffer (de)serialization as a special case is safer. When your code must work across multiple browsers and be future-proof, you're better off to use the supported APIs of the object.
function cloneAudioBuffer(fromAudioBuffer) {
const audioBuffer = new AudioBuffer({
length:fromAudioBuffer.length,
numberOfChannels:fromAudioBuffer.numberOfChannels,
sampleRate:fromAudioBuffer.sampleRate
});
for(let channelI = 0; channelI < audioBuffer.numberOfChannels; ++channelI) {
const samples = fromAudioBuffer.getChannelData(channelI);
audioBuffer.copyToChannel(samples, channelI);
}
return audioBuffer;
}
Solution 2:[2]
I think below code is useful for you for cloning object.
function clone(obj) {
if (null == obj || "object" != typeof obj) return obj;
var copy = obj.constructor();
for (var attr in obj) {
if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
}
return copy;
}
Please note that Answer with description is given on below link. How do I correctly clone a JavaScript object?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Kaiido |
| Solution 2 | Community |
