【问题标题】:Arduino 16-step sequencer - Notes not in syncArduino 16 步音序器 - 音符不同步
【发布时间】:2017-03-06 10:06:24
【问题描述】:

我正在为我的 arduino mega 使用以下代码将 midi 时钟发送到我的鼓机和合成器。 当我也尝试在“节拍”上准确发送 MIDI 音符时,就会出现问题。 只有第一个音符完美同步,其余音符不同步,您可以听到。 代码有什么明显的缺陷吗?

// METRONOME
#include <MIDI.h>

#define LED1PIN 13
#define LED4PIN 7
#define SWITCHAPIN 5
#define SWITCHBPIN 2
MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI);

void setup() {
  pinMode(LED1PIN, OUTPUT);
  pinMode(LED4PIN, OUTPUT);

  pinMode(SWITCHAPIN, INPUT);
  pinMode(SWITCHBPIN, INPUT);

  digitalWrite(SWITCHAPIN, HIGH);
  digitalWrite(SWITCHBPIN, HIGH);

  MIDI.begin(MIDI_CHANNEL_OMNI);
  Serial.begin(9600);
  Serial.println("Setting up");
}

unsigned long nextClockTime = 0;
int clockDelay = 20;
int tickCount = 0;
byte running = 0;
int pula = 0;
int currentStep = 1;
int lastPulse = 0;
int currPulse = 0;
int nextTickCount = 0;

typedef struct {
  int noteNumber;
  int velocity;
  int noteLength;
  bool enabled;
}
Step;

Step stepData[100];

void loop() {

  stepData[0].enabled = true;
  stepData[0].velocity = 127;
  stepData[0].noteNumber = 40;
  stepData[23].enabled = true;
  stepData[23].velocity = 127;
  stepData[23].noteNumber = 40;
  stepData[47].enabled = true;
  stepData[47].velocity = 127;
  stepData[47].noteNumber = 40;
  stepData[71].enabled = true;
  stepData[71].velocity = 127;
  stepData[71].noteNumber = 40;
  stepData[95].enabled = true;
  stepData[95].velocity = 127;
  stepData[95].noteNumber = 40;

  MIDI.read();
  unsigned long milliseconds = millis();
  if (milliseconds > nextClockTime) {
    if (running)
      MIDI.sendRealTime(MIDI_NAMESPACE::Clock);

    nextClockTime = milliseconds + clockDelay;
    nextTickCount = tickCount + 1;
    if (tickCount == 0) {
      if (stepData[tickCount].enabled) {
        MIDI.sendNoteOn(stepData[tickCount].noteNumber, stepData[tickCount].velocity, 1);
        Serial.print("STEP ENABLED: ");
        Serial.println(tickCount);
      }
    }
    if (tickCount == 23) {
      if (stepData[tickCount].enabled) {
        MIDI.sendNoteOn(stepData[tickCount].noteNumber, stepData[tickCount].velocity, 1);
        Serial.print("STEP ENABLED: ");
        Serial.println(tickCount);
        currPulse = millis(); //1500
        Serial.println(currPulse - lastPulse); //1500-500
        lastPulse = currPulse;
      }
    }
    if (tickCount == 47) {
      if (stepData[tickCount].enabled) {
        MIDI.sendNoteOn(stepData[tickCount].noteNumber, stepData[tickCount].velocity, 1);
        Serial.print("STEP ENABLED: ");
        Serial.println(tickCount);
        currPulse = millis();
        Serial.println(currPulse - lastPulse);
        lastPulse = currPulse;
      }
    }
    if (tickCount == 71) {
      if (stepData[tickCount].enabled) {
        MIDI.sendNoteOn(stepData[tickCount].noteNumber, stepData[tickCount].velocity, 1);
        Serial.print("STEP ENABLED: ");
        Serial.println(tickCount);
        currPulse = millis();
        Serial.println(currPulse - lastPulse);
        lastPulse = currPulse;
      }
    }
    if (tickCount == 95) {
      if (stepData[tickCount].enabled) {
        //MIDI.sendNoteOn(stepData[tickCount].noteNumber, stepData[tickCount].velocity, 1);
        Serial.print("STEP ENABLED: ");
        Serial.println(tickCount);
        currPulse = millis();
        Serial.println(currPulse - lastPulse);
        lastPulse = currPulse;
      }
      nextTickCount = 0;
    }
    tickCount = nextTickCount;
  } else if (digitalRead(SWITCHBPIN) == LOW) {
    if (running) {
      MIDI.sendRealTime(MIDI_NAMESPACE::Stop);
      running = 0;
      digitalWrite(LED4PIN, LOW);
    }
  } else {
    clockDelay = analogRead(A0) / 10;
  }
  if (pula == 0) {
    if (!running) {
      MIDI.sendRealTime(MIDI_NAMESPACE::Start);
      tickCount = 0;
      running = 1;
      digitalWrite(LED4PIN, HIGH);
      pula = 1;
    }
  }
}

【问题讨论】:

  • 尝试在尝试运行实时代码的同时不要发送全部串行调试负载...

标签: arduino midi


【解决方案1】:

节拍间隔不均匀。 24 - 1 是 23,48 - 24 是 24 等等。

一个简单的解决方法是将您的第一个节拍设置为 0 而不是 1。不要增加 tickCount,而是将变量 nextTickCount 设置为 tickCount +1,并将其分配给 if (milliseconds &gt; nextClockTime) { 条件括号末尾的 tickCount。

另外,当 tickCount 达到 95 时,将 nextTickCount 设置为 0,但不要弹奏任何音符(它将在 0 拍上播放)

【讨论】:

  • 16 步音序器 = 4 拍 => 24ppqn *4 = 96。我错过了什么吗?
  • 不,你是对的,出于某种原因,我很困惑并在思考 2 的幂。不过,您确实需要更改最后一个节拍的处理方式(请参阅编辑)
  • 我实施了您的更改,结果相同..这让我发疯。请查看顶部已编辑的代码。
  • 让 24 和 48 和 72 保持原样。音符应在 0、24、48 和 72 上播放。回零应在 95
  • 我试过了,还是有audibe不同步。我开始认为这个敏感操作的 arduino 计时器可能存在问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-06
  • 2013-12-24
  • 1970-01-01
  • 2012-03-16
  • 2017-01-28
  • 1970-01-01
  • 2017-12-07
相关资源
最近更新 更多