You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:为何buffer数组的采样数比实际信号少1个?

问题分析与修复

你的代码存在两处核心逻辑错误,导致环形缓冲区与信号序列的长度和内容出现差异:

1. 信号更新函数(updateSignal)逻辑缺陷

当前代码中,当信号数组达到设定长度后,仅删除最旧元素但未添加新采样,导致数组长度在signalLength和signalLength-1之间波动,无法稳定保持设定长度。正确逻辑应该是每次先添加新采样,再判断是否需要删除最旧元素,确保数组长度始终不超过设定值。

2. 环形缓冲区更新函数(updateRingbuffer)逻辑缺陷

当缓冲区填满时,仅执行删除前50%元素的操作,但未将当前采样加入缓冲区,导致该次采样丢失,缓冲区长度直接从sampleLength变为sampleLength/2,后续才会继续添加新采样,因此出现长度少1的差异。正确逻辑是先添加新采样,再判断是否需要截断缓冲区。


修正后的完整代码

let ring_buffer = [] 
let signal = []
let sampleLength = 20
let signalLength  = 0
let spacing = 16

function setup() {
  createCanvas(400, 400);
  signalLength = width / spacing
  frameRate(1)
}

function draw() {
  background(220);
  translate(0, height >> 2)
  
  // 生成模拟采样(修正写法,逻辑更清晰)
  let sample = random(-30, 30) > 0 ? 20 : -20 
  
  // 更新并绘制信号
  stroke(255, 0, 0)
  updateSignal(sample)
  drawSignal(signal, 100)
  
  // 更新并绘制环形缓冲区
  stroke(0, 0, 255)
  updateRingbuffer(sample)
  drawSignal(ring_buffer, 150)
  
  // 绘制坐标轴
  drawAxis()
}

// 修正后的信号更新函数
function updateSignal(sample){
  signal.push(sample)
  // 超过设定长度时删除最旧元素
  if(signal.length > signalLength){
    signal.shift()
  }
}

// 修正后的环形缓冲区更新函数
function updateRingbuffer(sample){
  ring_buffer.push(sample)
  // 填满时删除前50%元素(用floor确保整数索引)
  if(ring_buffer.length === sampleLength){
    ring_buffer.splice(0, Math.floor(sampleLength / 2))
  }
}

function drawSignal(arr, offset){
  noFill()
  beginShape()
  for(let i=0; i<arr.length; i++){
    vertex(i * spacing, arr[i] + offset)
  }
  endShape()
}

function drawAxis(){
  fill(0)
  noStroke()
  textSize(8)
  textAlign(CENTER)
  for(let i=0; i<width; i+=spacing){ 
    text(i/spacing, i, 200)
    push()
    translate(i, 200)
    rotate(PI/2)
    stroke(0, 10)
    line(-width/2, 0, width/2, 0)
    pop()
  }
}

关键修改说明

  • updateSignal:调整为先push新采样,再判断是否需要shift,确保信号数组长度稳定在signalLength(因signalLength由width/spacing计算可能为浮点数,最终长度会接近该值)。
  • updateRingbuffer:先将新采样加入缓冲区,再检查是否填满,填满时删除前50%元素,保证每次采样都被正确记录,缓冲区在填满后会截断为原长度的50%,并继续接收新采样。
  • 模拟采样生成:调整条件判断写法,使其更易读(random(-30,30) > 0替代0<random(-30,30))。

内容的提问来源于stack exchange,提问作者Greyfrog

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 04:27:45