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

Processing中实现全屏竖线按行数动态等分拆分的技术求助

解决方案:实现动态等分的对讲机式音频可视化

针对你的需求,我重构了代码,实现了全屏竖线覆盖+每行填满后动态等分屏幕的效果,同时保留对讲机式的说话方切换逻辑。以下是核心修改点和完整代码:

核心修改说明

  • 用keyPressed事件替代draw中的按键检测,避免重复触发导致的绘制异常
  • 新增行计数与动态行高计算,实现每行填满后自动将屏幕等分为总行数+1份
  • 通过画面缩放保留历史对话的可视化内容,新行自动占据等分后的新区域
  • 统一管理两个说话方的配色方案,简化代码逻辑
  • 增加交互提示(初始引导、行填满提示)

完整修改代码

import processing.sound.*;

AudioIn input;
Amplitude amp;

// 说话方标识:0=A(蓝色系),1=L(橙色系),-1=未开始
int currentSpeaker = -1;
int currentX = 0;          // 当前绘制的横向像素位置
int rowCount = 1;          // 当前总行数
float rowHeight;           // 每行的高度(动态计算)

// 两个说话方的配色方案
color[] highColors = {color(72, 16, 255), color(255, 128, 16)};
color[] lowColors = {color(179, 155, 255), color(255, 203, 156)};
color midColor;            // 中间音量的过渡色

void setup() {
  size(1440, 846);
  background(255);
  pixelDensity(displayDensity());
  
  // 初始化音频输入
  input = new AudioIn(this, 0);
  input.start();
  amp = new Amplitude(this);
  amp.input(input);
  
  // 初始行高为全屏高度
  rowHeight = height / (float)rowCount;
}

void keyPressed() {
  // 切换到A说话方
  if (key == 'a' || key == 'A') {
    currentSpeaker = 0;
    handleRowCompletion();
    midColor = lerpColor(lowColors[currentSpeaker], highColors[currentSpeaker], 0.5);
  }
  // 切换到L说话方
  else if (key == 'l' || key == 'L') {
    currentSpeaker = 1;
    handleRowCompletion();
    midColor = lerpColor(lowColors[currentSpeaker], highColors[currentSpeaker], 0.5);
  }
}

// 处理当前行填满后的逻辑:新增行+缩放历史画面
void handleRowCompletion() {
  if (currentX >= width) {
    rowCount++;
    currentX = 0;
    rowHeight = height / (float)rowCount;
    
    // 将历史画面缩放到上方(rowCount-1)/rowCount区域,为新行腾出空间
    if (rowCount > 1) {
      PImage history = get(0, 0, width, height);
      background(255);
      image(history, 0, 0, width, height * (rowCount-1)/rowCount);
    }
  }
}

void draw() {
  // 初始引导提示
  if (currentSpeaker == -1) {
    background(255);
    textSize(40);
    fill(0);
    textAlign(CENTER, CENTER);
    text("按A或L切换说话方开始录制", width/2, height/2);
    return;
  }
  
  // 获取当前音量并映射到颜色等级
  float volume = amp.analyze();
  int colorLevel = int(map(volume, 0, 0.05, 0, 3));
  
  noFill();
  strokeCap(SQUARE);
  
  // 根据音量设置线条颜色
  switch(colorLevel) {
    case 0: stroke(255); break;       // 静音:背景色,不显示线条
    case 1: stroke(lowColors[currentSpeaker]); break;
    case 2: stroke(midColor); break;
    case 3: stroke(highColors[currentSpeaker]); break;
  }
  
  // 绘制当前行的竖线(从当前行顶部到底部)
  float currentRowTop = height - rowHeight;
  line(currentX, currentRowTop, currentX, height);
  currentX++;
  
  // 当前行填满后的提示
  if (currentX >= width) {
    textSize(40);
    fill(0);
    textAlign(CENTER, CENTER);
    text("当前行已填满,按A/L切换说话方继续", width/2, currentRowTop + rowHeight/2);
  }
}

功能说明

  1. 初始状态:屏幕显示引导文字,按A或L切换到对应说话方
  2. 实时绘制:根据麦克风输入的音量,绘制对应颜色的竖线,从左到右填充当前行
  3. 行填满逻辑:当一行横向填满全屏后,按任意说话方按键,会将历史画面缩放到屏幕上方的(总行数-1)/总行数区域,新行占据下方的1/总行数区域
  4. 对讲机切换:全程可通过A/L键随时切换说话方,切换后继续在当前行绘制对应色系的可视化线条

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 11:15:39