Arduino 16 步音序器 - 音符不同步
Posted
技术标签:
【中文标题】Arduino 16 步音序器 - 音符不同步【英文标题】:Arduino 16-step sequencer - Notes not in sync 【发布时间】: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;
【问题讨论】:
尝试在尝试运行实时代码的同时不要发送全部串行调试负载... 【参考方案1】:节拍间隔不均匀。 24 - 1 是 23,48 - 24 是 24 等等。
一个简单的解决方法是将您的第一个节拍设置为 0 而不是 1。不要增加 tickCount,而是将变量 nextTickCount 设置为 tickCount +1,并将其分配给 if (milliseconds > nextClockTime)
条件括号末尾的 tickCount。
另外,当 tickCount 达到 95 时,将 nextTickCount 设置为 0,但不要弹奏任何音符(它将在 0 拍上播放)
【讨论】:
16 步音序器 = 4 拍 => 24ppqn *4 = 96。我错过了什么吗? 不,你是对的,出于某种原因,我很困惑并在思考 2 的幂。不过,您确实需要更改最后一个节拍的处理方式(请参阅编辑) 我实施了您的更改,结果相同..这让我发疯。请查看顶部已编辑的代码。 让 24 和 48 和 72 保持原样。音符应在 0、24、48 和 72 上播放。回零应在 95 我试过了,还是有audibe不同步。我开始认为这个敏感操作的 arduino 计时器可能存在问题。以上是关于Arduino 16 步音序器 - 音符不同步的主要内容,如果未能解决你的问题,请参考以下文章