p5.js中peakDetect.isDetected未按预期触发问题咨询
问题根因
peakDetect.isDetected始终不触发是三个问题叠加导致的:
- 你混淆了两个振幅概念:给
osc.amp()设置的01.2是振荡器输出的*时域振幅*,而`p5.PeakDetect`默认检测的是FFT输出的*归一化频谱能量*(取值范围01),二者不是同一个计量维度,不存在“时域振幅到1.0就触发”的默认逻辑。 - 你初始化
PeakDetect时没有传自定义参数,默认配置为检测20Hz~20kHz全频段、触发阈值0.35、两次峰值最小间隔20帧,这个阈值和你预期的触发条件不匹配,且因为信号链问题根本拿不到正确的检测信号。 - 音频信号链断裂:你在setup中执行了
osc.disconnect()、lfo.disconnect(),仅将osc连接到了filter,但filter既没有连接到主输出,也没有连接到FFT输入节点,FFT默认采集主输出通道的信号,实际拿到的根本不是你经过LFO调制、滤波后的目标信号,自然不可能检测到峰值。
修复步骤
- 补全音频信号链路
在setup的信号连接部分最后补上filter到主输出的连接,保证信号能正常被FFT采集:
// chain lfo.disconnect(); osc.disconnect(); osc.connect(filter); // 新增:将filter连接到主输出 filter.connect();
- 配置PeakDetect的自定义参数
根据你的触发需求调整检测阈值,比如需要接近最大振幅时触发,可以将阈值设为0.9(对应频域能量接近满值),同时缩短峰值检测的最小间隔提升响应灵敏度:
// 替换原代码的peakDetect = new p5.PeakDetect(); // 参数依次为:检测起始频率、检测结束频率、触发阈值、两次峰值最小间隔帧 peakDetect = new p5.PeakDetect(20, 20000, 0.9, 10);
- (可选)严格时域振幅触发方案
如果你需要严格按照“时域波形振幅绝对值≥1.0”的规则触发,不需要依赖PeakDetect,直接遍历FFT返回的waveform数组判断即可:
// 替换原有peakDetect.update(fft)及后续判断逻辑 peakDetect.update(fft); let isOverAmpThreshold = false; let waveform = fft.waveform(); for (let val of waveform) { if (Math.abs(val) >= 1.0) { isOverAmpThreshold = true; break; } } let ellipseWidth = 10; if (isOverAmpThreshold || peakDetect.isDetected) { ellipseWidth = 50; } else { ellipseWidth *= 0.95; }
调整后当鼠标移到画布最上方把amp拉到1.2时,就能正常触发检测逻辑,中间的椭圆会放大到50像素。
内容的提问来源于stack exchange,提问作者Chewie The Chorkie
相关产品推荐
相关产品推荐

