i'm creating a program that from an input .mp3 file song generate fragments with 100 millisecond length, than randomly reassemble the fragments to create a new song output. for the moment everything works but i don't know how to make the program generate a .mp3/.wav file to be saved in the "/output" folder that i have create in my p5.js sketch. this is my code:
let audioBuffer;
let segmentLength = 100; // length of each segment in milliseconds
let patternLength = 15; // length of each pattern in segments
let numPatterns; // number of patterns in the final output
let numSegments; // total number of segments in the output
let segments = [];
let patterns = [];
let audioContext;
function preload() {
audioFile = loadSound('sounds/02ContortYourself.mp3', onAudioLoaded);
}
function onAudioLoaded() {
// Create a new AudioContext object
audioContext = new AudioContext();
// Get the decoded audio buffer from the loaded audio file
audioBuffer = audioFile.buffer;
// Calculate the maximum number of patterns and segments that fit within 1 minute
let maxDuration = 60; // maximum duration of the output song in seconds
numPatterns = Math.floor(maxDuration * 1000 / (segmentLength * patternLength));
numSegments = numPatterns * patternLength;
// Split the audio buffer into segments of the specified length, up to the maximum duration
for(let i = 0; i < numSegments; i++) {
let go = i * segmentLength / 1000;
let end = go + segmentLength / 1000;
let segment = audioBuffer.getChannelData(0).subarray(go * audioBuffer.sampleRate, end * audioBuffer.sampleRate);
segments.push(segment);
// Print the length of the segment in milliseconds
console.log(`Segment ${i}: ${segmentLength}ms`);
}
// Shuffle the segments array using the Fisher-Yates shuffle algorithm
for (let i = segments.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[segments[i], segments[j]] = [segments[j], segments[i]];
}
// Group segments into patterns
for (let i = 0; i < numPatterns; i++) {
let pattern = [];
for (let j = 0; j < patternLength; j++) {
pattern.push(segments[i * patternLength + j]);
}
patterns.push(pattern);
}
// Arrange patterns in a specific sequence
let patternSequence = [0, 0, 2, 2, 1, 1, 3, 3, 3, 3, 2, 0, 1]; // example pattern sequence
let outputSegments = [];
while (outputSegments.length < numSegments) {
outputSegments = outputSegments.concat(patternSequence.map(index => patterns[index]).flat());
}
outputSegments = outputSegments.slice(0, numSegments);
// Create a new audio buffer for the output song
let outputBuffer = new AudioBuffer({
numberOfChannels: 1,
length: outputSegments.length * segmentLength * audioBuffer.sampleRate / 1000,
sampleRate: audioBuffer.sampleRate
});
// Copy each segment into the output buffer in their arranged order
for (let i = 0; i < outputSegments.length; i++) {
let offset = i * segmentLength * audioBuffer.sampleRate / 1000;
outputBuffer.copyToChannel(outputSegments[i], 0, offset);
}
// Create a new audio source from the output buffer and play it
let outputSource = new AudioBufferSourceNode(audioContext, { buffer: outputBuffer });
outputSource.connect(audioContext.destination);
outputSource.start();
}
function setup() {
createCanvas(400, 400);
}
the function outputSource.start(); makes the new song playing but what i want is the song to saved in the /output folder not to be played. i'm stack here and i don't know how to go on.
thank you very much for helping!