I’m building a little sound visualiser, but I’m strictly unable to get the amplitude level, it always return 0, and I have no idea why. I have no problem accessing fft, so it seems that there is no issue accessing the mic, althought I have amplitude.setInput(mic), it always return 0, whatever the volume.
furthermore I have a log error, which is totally unclear:
TypeError: arraySequence[channel] is undefined
Here is my setup function
function setup() {
noLoop(); // Start with no loop
$('.sound-trigger').on('click', function() {
if (!soundIsCapted) {
// Create an audio input
mic = new p5.AudioIn();
mic.start(function() {
// Create a new amplitude analyzer
amplitude = new p5.Amplitude();
fft = new p5.FFT();
peakDetect = new p5.PeakDetect();
amplitude.setInput(mic);
fft.setInput(mic);
loop(); // Start looping when mic is started
soundIsCapted = true;
}, function(err) {
console.error('Failed to start microphone', err);
});
} else {
mic.stop();
noLoop();
soundIsCapted = false;
}
});
}
and my draw function
function draw() {
if (!soundIsCapted) {
return;
}
// Get the current amplitude level
let level = amplitude.getLevel();
let spectrum = fft.analyze();
// https://p5js.org/reference/#/p5.FFT/getEnergy
let bass = fft.getEnergy('bass');
let lowMid = fft.getEnergy('lowMid');
let mid = fft.getEnergy('mid');
let highMid = fft.getEnergy('highMid');
let treble = fft.getEnergy('treble');
let trebleEnergy = (treble + highMid) / 2;
let bassEnergy = bass;
console.log('Amplitude Level:', level);
// Update the peak detect
peakDetect.update(fft);
// If a peak is detected
if (peakDetect.isDetected) {
let currentTime = millis();
peakTimes.push(currentTime);
// Keep the last 10 peaks
if (peakTimes.length > 10) {
peakTimes.shift();
}
if (peakTimes.length > 1) {
// Calculate intervals between peaks
let intervals = [];
for (let i = 1; i < peakTimes.length; i++) {
intervals.push(peakTimes[i] - peakTimes[i - 1]);
}
// Calculate average interval
let averageInterval = intervals.reduce((a, b) => a + b) / intervals.length;
// Convert average interval to BPM
bpm = 60000 / averageInterval;
}
// Create visual effects or animations based on the peak
var mappedPeak = gsap.utils.pipe(
gsap.utils.clamp(.35, .5),
gsap.utils.mapRange(.35, .5, 100, 900)
);
var newPeak = mappedPeak(peakDetect.currentValue);
var tl = gsap.timeline({ paused: true });
tl.to('html', { '--font-weight': newPeak, duration: .1 })
.to('html', { '--font-weight': 100, duration: .1 });
tl.play();
}
let transformTreble = gsap.utils.pipe(
gsap.utils.clamp(100, 250),
gsap.utils.mapRange(100, 250, 1.5, 15)
);
let transformBass = gsap.utils.pipe(
gsap.utils.clamp(100, 250),
gsap.utils.mapRange(100, 250, 100, 900)
);
trebleEnergy = transformTreble(trebleEnergy);
bassEnergy = transformBass(trebleEnergy);
gsap.to('html', { '--word-multiplied-by': trebleEnergy, duration: .25 });
gsap.to('html', { '--font-weight': bassEnergy, duration: .5 });
// Remove old beats
if (beats.length > 20) {
beats.shift();
}
}
Here is the codepen: CodePen - A Pen by Romain
you just need to click on SOUND>Activate sound.
Side question : After a lot of research it seem that getting the BPM will never get very accurate, is there some tricks to have it accurate?
Thank you