处理中同时发生if / else事件

问题描述 投票:1回答:1

该程序将采用指定的MIDI INPUT设备,并根据同时发送的信号数量,在指定的MIDI OUTPUT设备的通道1-4之间分割其信号(无论通道如何)。

这意味着如果您使用MIDI键盘作为INPUT设备,并按键盘上的任意一个键,该数据将被发送到OUTPUT设备上的通道1。但是,如果您同时按下(或永远按下)键盘上的任意2个键,您按下的第一个键将被发送到通道1,而您按下的第二个键将被发送到通道2.程序将使用相同的过程最多4个同时音符(因此4个输出通道)。

这样做不需要MIDI键盘,只需下载像VMPK(http://vmpk.sourceforge.net)这样的虚拟键盘,并创建一个类似loopMIDI(https://www.tobias-erichsen.de/software/loopmidi.html)的虚拟端口,将虚拟键盘连接到脚本。如果使用这两个程序,请使用loopMIDI创建虚拟端口,然后打开VMPK并将其输出设置为刚刚创建的虚拟端口。

唯一的问题是,如果您一次玩多个键,只释放其中一个键(并继续保持其余键),然后尝试再次按下您释放的键。它不会将消息发送到空闲频道,而是尝试将消息发送到已经忙碌的频道。

EX:如果按一个键并按住它,如果notesPlayed = 0程序将音符ON信号发送到通道1并设置notesPlayed = notesPlayed + 1,然后等待你放开键,然后将音符OFF信号发送到同一通道通过设置notesPlayed = notesPlayed - 1

所以,如果你没有碰到键盘(notesPlayed = 0),然后你开始拿着一把钥匙(notesPlayed = 1)并开始拿着另一把钥匙(现在是notesPlayed = 2),然后放开第一把钥匙(现在又来了notesPlayed = 1),然后试试按一个键,它会尝试将它发送到通道2,因为notesPlayed = 1,但因为通道2仍在播放音符而失败。我正在绞尽脑汁解决这个问题!

我认为需要有类似的东西

if (notesPlayed == 1) {                  // if 1 note is currently being played
     if (stat2 = 1) {                     // if channel 2 is already busy
"send note to the last available channel"
         }
 }

这是程序。

import controlP5.*;
import themidibus.*;
import at.mukprojects.console.*;


Console console;
ControlP5 cp5;
MidiBus myBus;
PFont sans;
final int MODE_1 = 1;
final int MODE_2 = 2;
int notesPlayed,ch1,ch2,ch3,ch4,stat1,stat2,stat3,stat4,mode,r,g,b;
String input = "NOT CONNECTED";
String output = "NOT CONNECTED";
String reset,devicesConnected;
boolean showConsole;

void setup()  {
  size(300, 550);
  smooth();
  notesPlayed = 0;
  cp5 = new ControlP5(this);
  cp5.addTextfield("input").setPosition(10, 365).setSize(80, 20).setAutoClear(false);
  cp5.addTextfield("output").setPosition(100, 365).setSize(80, 20).setAutoClear(false);
  cp5.addBang("submit").setPosition(190, 365).setSize(20, 20);
  cp5.addBang("reset").setPosition(270, 365).setSize(20, 20);
  console = new Console(this);
  console.start();
  showConsole = true;
  mode = MODE_1;
  sans = loadFont("SansSerif.plain-18.vlw");
  reset = "yes";
  devicesConnected = "no";
  r = 255;
  g = 0;
  b = 0;
}

void draw(){

  background(0);

  switch(mode) {
  case MODE_1:
// (x, y, width, height, preferredTextSize, minTextSize, linespace, padding, strokeColor, backgroundColor, textColor)
    console.draw(2, 0, 295, 360, 13, 13, 1, 1);
    break;

  case MODE_2:
// (x, y, width, height, preferredTextSize, minTextSize, linespace, padding, strokeColor, backgroundColor, textColor)
    console.draw(2, 0, 295, 360, 13, 13, 1, 1, color(220), color(0), color(0, 255, 0));
    break;
  }

  textSize(12);
  fill(200, 200, 200);
  text("INPUT:", 10, 420);
  text("OUTPUT:", 10, 435);
  fill(r, g, b);
  text(input, 70, 420);
  text(output, 70, 435);

  fill(255, 255, 0);
  textSize(28);
  text("Channel Activity", 15, 450);

  textSize(60);

  if (stat1 == 0)  {
    fill(90, 90, 90);
    text("1", 20, 485);
  }

  if (stat2 == 0)  {
    fill(90, 90, 90);
    text("2", 95, 485);
  }

  if (stat3 == 0)  {
    fill(90, 90, 90);
    text("3", 170, 485);
  }

  if (stat4 == 0)  {
    fill(90, 90, 90);
    text("4", 245, 485);
  }

  if (stat1 == 1)  {
    fill(0, 255, 0);
    text("1", 20, 485);
  }

  if (stat2 == 1)  {
    fill(0, 255, 0);
    text("2", 95, 485);
  }

  if (stat3 == 1)  {
    fill(0, 255, 0);
    text("3", 170, 485);
  }

  if (stat4 == 1)  {
    fill(0, 255, 0);
    text("4", 245, 485);
  }

  textFont(sans);
  fill(r, g, b);
  textSize(14);
  text("- Active Devices -", 10, 405);

  if (reset == "yes")  {
    println(" ");
    println(" ");
    println(" ");
    println(" ");
    println(" ");
    println(" ");
    println(" ");
    println(" ");
    println(" ");
    println(" ");
    MidiBus.findMidiDevices();
    MidiBus.list();
    println("------------------------------------");
    println("      Input device names below");
    println("          (case sensitive)");
    input = "NOT CONNECTED";
    output = "NOT CONNECTED";
    r = 255;
    g = 0;
    b = 0;
    reset = "no";
  }  else  {}
}

void noteOn(int channel, int pitch, int velocity) {

  if (notesPlayed == 0)  {
    myBus.sendNoteOn(0, pitch, velocity);
    ch1 = pitch;
    stat1 = 1;
    println("CH1 - ON  - ", pitch, " ", velocity);
  }

  if (notesPlayed == 1) {
    myBus.sendNoteOn(1, pitch, velocity);
    ch2 = pitch;
    stat2 = 1;
    println("CH2 - ON  - ", pitch, " ", velocity);
  }

  if (notesPlayed == 2)  {
    myBus.sendNoteOn(2, pitch, velocity);
    ch3 = pitch;
    stat3 = 1;
    println("CH3 - ON  - ", pitch, " ", velocity);
  }

  if (notesPlayed == 3)  {
    myBus.sendNoteOn(3, pitch, velocity);
    ch4 = pitch;
    stat4 = 1;
    println("CH4 - ON  - ", pitch, " ", velocity);
  }

  notesPlayed = notesPlayed + 1;

}

void noteOff(int channel, int pitch, int velocity) {

  if (ch1 == pitch)  {
    myBus.sendNoteOff(0, pitch, velocity);
    stat1 = 0;
    println("CH1 - OFF - ", pitch, " ", velocity);
  }

    if (ch2 == pitch)  {
    myBus.sendNoteOff(1, pitch, velocity);
    stat2 = 0;
    println("CH2 - OFF - ", pitch, " ", velocity);
  }

    if (ch3 == pitch)  {
    myBus.sendNoteOff(2, pitch, velocity);
    stat3 = 0;
    println("CH3 - OFF - ", pitch, " ", velocity);
  }

    if (ch4 == pitch)  {
    myBus.sendNoteOff(3, pitch, velocity);
    stat4 = 0;
    println("CH3 - OFF - ", pitch, " ", velocity);
  }

  notesPlayed = notesPlayed - 1;

}

void submit()  {

  if (devicesConnected == "yes")  {
    println("There are already devices connected! Please reset first and try again.");
  }  else  {
    r = 0;
    g = 255;
    b = 0;
    input = cp5.get(Textfield.class,"input").getText();
    output = cp5.get(Textfield.class,"output").getText();
    myBus = new MidiBus(this, input, output);
    devicesConnected = "yes";
    mode = MODE_2;
  }
}

void reset()  {
  if (devicesConnected == "yes")  {
    myBus.close();
    devicesConnected = "no";
    mode = MODE_1;
  }  else  {}
  println(" ");
  println(" ");
  println(" ");
  println(" ");
  println(" ");
  println(" ");
  println(" ");
  println(" ");
  println(" ");
  println(" ");
  MidiBus.findMidiDevices();
  MidiBus.list();
  println("------------------------------------");
  println("      Input device names below");
  println("          (case sensitive)");
  input = "NOT CONNECTED";
  output = "NOT CONNECTED";
  r = 255;
  g = 0;
  b = 0;
  mode = MODE_1;
}
if-statement processing midi state-machine
1个回答
0
投票

你的问题是系统的当前状态是由一个计数器(notesPlayed)决定的;这不允许您确定当前活动的四个输出中的哪一个。

您需要为四个输出提供四个独立状态。换句话说,创建一个包含四个条目的数组;收到音符开消息时,搜索数组中的第一个空闲条目;收到音符关闭消息时,搜索数组中具有相同音符的匹配条目。

© www.soinside.com 2019 - 2024. All rights reserved.