Guys, any idea on how to introduce Swing/Shuffle to my MIDI Clock Timer? I'm using the 16-bit timer to pulse at every 96 PPQ. Them I just check if its on a beat or not to produce notes. But how do I handle Swing/Shuffle now?
Any help would be much appreciated. I will post the Timer code in a few minutes...
Wk
void timerStart()
{
TCCR1A = TCCR1B = 0;
bitWrite(TCCR1B, CS11, 1);
bitWrite(TCCR1B, WGM12, 1);
timerSetFrequency();
bitWrite(TIMSK1, OCIE1A, 1);
}
void timerSetFrequency()
{
// Calculates the Frequency for the Timer, used by the PPQ clock (Pulses Per Quarter Note) //
// This uses the 16-bit Timer1, unused by the Arduino, unless you use the analogWrite or Tone functions //
#define frequency (((midiClockBPM)*(PPQ))/60)
OCR1A = (F_CPU/ 8) / frequency - 1;
}
void timerStop(void)
{
bitWrite(TIMSK1, OCIE1A, 0);
TCCR1A = TCCR1B = OCR1A = 0;
}
ISR(TIMER1_COMPA_vect) { midiTimer(); }
And here's the complete MIDI Clock Tick, which generates all notes. Its long, I know, but so far it works even at 255 BPM and 1/64 mode.
Hint: midiClockProcessDoubleSteps is used for the 1/32 steps, as we have not just 16 x 1/16 steps, but a total of 32 x 1/32 steps. (now with V1.2.0 actually a total of 64 x 1/32 steps) Instead of 1/32 you can also chose 1/64, so you end up with 64 x 1/64 steps.
I removed the code for the 2 extra Synth Parts, so its easier to read...
void midiTimer()
{
if (midiClockProcess || midiClockProcessDoubleSteps)
{
uint8_t dBB = (((DRUMTRACKS+2)*midiClockProcessDoubleSteps)+(((DRUMTRACKS+2)*2)*stepsPos));
uint8_t dBBs = ((16*midiClockProcessDoubleSteps)+(32*stepsPos));
uint8_t velocity = 87+(bitRead(dmSteps[patternBufferN][DRUMTRACKS+dBB],midiClockCounter)*20)+(bitRead(dmSteps[patternBufferN][DRUMTRACKS+1+dBB],midiClockCounter)*20);
for (char xdtm=0; xdtm<DRUMTRACKS; xdtm++)
{
if (bitRead(dmSteps[patternBufferN][xdtm+dBB],midiClockCounter) && !bitRead(dmMutes,xdtm))
{
sendMidiNoteOff(dmNotes[xdtm], dmChannel[xdtm]);
sendMidiNoteOn(dmNotes[xdtm],velocity, dmChannel[xdtm]);
}
}
midiClockProcess = 0;
midiClockProcessDoubleSteps = 0;
}
// Midi Clock //
if (midiClockType == 1) midiClockCounterDivider += 2; else midiClockCounterDivider++;
if (midiClockCounterDivider >= (12*timeScale))
{
midiClockProcess = 1;
midiClockCounterDivider = 0;
midiClockCounter++;
if (midiClockCounter >= 16)
{
stepsPos++;
if (autoSteps) { editStepsPos = !editStepsPos; if (!holdingShift) doPatternLCDupdate = 1; }
midiClockCounter = 0;
if (stepsPos >= 2)
{
stepsPos = 0;
if (curMode == 1)
{
patternSongRepeatCounter++;
if (patternSongNext == 0 && patternSongRepeatCounter > patternSongRepeat)
{
MidiClockStop();
songNextPosition = 1;
}
}
checkPatternLoader();
}
}
}
else if (midiClockCounterDivider == (6*timeScale)) midiClockProcessDoubleSteps = 1;
}
That's the complete code, hopefully someone will get a hint on how to do it. I'm only asking as I have no clue on how, and I'm very tired already from other projects.
Wk
Well, I managed to get a nice Shuffle feel by doing a small hack on how I count the PPQs. So far its working nicely...
Here's some parts of the code.
midiClockShuffleData[0][0] = 12;
midiClockShuffleData[1][0] = 6;
void MidiShuffleUpdate()
{
midiClockShuffleData[0][1] = 12+midiClockShuffle;
midiClockShuffleData[1][1] = 6+midiClockShuffle;
midiClockShuffleData[0][2] = 12-midiClockShuffle;
midiClockShuffleData[1][2] = 6-midiClockShuffle;
}
// Midi Clock //
if (midiClockType == 1) midiClockCounterDivider += 2; else midiClockCounterDivider++;
if (midiClockCounterDivider >= (midiClockShuffleData[0][midiClockShuffleCounter]*timeScale))
{
...........
}[code]
midiClockShuffle goes from 0 to 6. At 1 and 2 you can already get a nice shuffle feeling.
Wk
[/code]