xxxxxxxxxx
function audioViz(p) {
let audioFileSelector;
let audioFile;
let leftChannelData;
let rightChannelData;
let trimSlider;
let trimButton;
p.setup = function() {
p.createCanvas(400, 400);
audioFileSelector = p.createFileInput(loadAudioFile);
audioFileSelector.position(0, 0);
p.textAlign(p.CENTER, p.CENTER);
p.noLoop();
}
p.draw = function() {
p.background('lightgray');
p.noFill();
p.stroke('red');
p.strokeWeight(1);
let loading = true;
if (leftChannelData) {
renderChannel(leftChannelData, 0);
loading = false;
}
if (rightChannelData) {
renderChannel(rightChannelData, p.height);
loading = false;
}
if (loading) {
p.noStroke();
p.fill('red');
p.text('Waiting/Loading..', p.width / 2, p.height / 2);
}
}
p.doubleClicked = function() {
if (audioFile) {
if (audioFile.isPlaying()) {
audioFile.stop();
} else {
audioFile.play();
}
}
}
function renderChannel(data, peakHeight) {
let limit = trimSlider ? p.min(trimSlider.value() * audioFile.sampleRate(), data.length) : data.length
// values per pixel
let resolution = p.int(p.max(1, p.round(limit / p.width)));
// Normalize our graph based on the peak amplitude of this channel
let maxAmp;
for (let i = 0; i < limit; i++) {
if (maxAmp === undefined || p.abs(data[i]) > maxAmp) {
maxAmp = data[i];
}
}
let x = 0;
let sum = 0;
p.beginShape();
for (let i = 0; i < limit; i++) {
// Compute an average for each set of values
sum += p.abs(data[i]);
if (i % resolution == 0) {
p.vertex(
x++,
// map the average amplitude to range from the center of the canvas to
// either the top or bottom depending on the channel
p.map(sum / resolution, 0, maxAmp, p.height / 2, peakHeight));
sum = 0;
}
}
p.endShape();
}
function loadAudioFile(file) {
audioFile =
p.loadSound(
file.data,
() => onAudioFileLoaded(),
e => console.error(e)
);
}
function onAudioFileLoaded() {
if (trimSlider) {
trimSlider.remove();
}
trimSlider = p.createSlider(0, audioFile.duration(), audioFile.duration());
trimSlider.position(10, 30);
trimSlider.input(() => {
p.redraw();
});
if (!trimButton) {
trimButton = p.createButton('Trim');
trimButton.position(10, 60);
trimButton.mousePressed(trimAudioFile);
}
leftChannelData = audioFile.buffer.getChannelData(0);
rightChannelData =
audioFile.buffer.numberOfChannels > 1 ?
audioFile.buffer.getChannelData(1) :
undefined;
p.redraw();
}
function trimAudioFile() {
// Get the end time we want to trim to in seconds
let endTime = trimSlider.value();
// Convert the time to a number of samples
let endOffset = endTime * audioFile.sampleRate();
let channelBuffers = []
// Copy data for each channel in our source file
for (let channel = 0; channel < audioFile.channels(); channel++) {
// Create a new array for each channel
let channelDataArray = new Float32Array(endOffset);
// Copy data to the array (this will only copy upt to the size of the array)
audioFile.buffer.copyFromChannel(channelDataArray, channel, 0);
channelBuffers.push(channelDataArray);
}
// setBuffer expects an array of channels which are expected to be Float32 arrays
audioFile.setBuffer(channelBuffers);
onAudioFileLoaded();
}
}
new p5(audioViz);