Midipal - midi clock groove induction

Hey there,

i´m trying to understand how the groove induction of midi pal works.

i guess the core of the groove induction happens here

void Clock::Update( uint16_t bpm, uint8_t bpm_tenth, uint8_t groove_template, uint8_t groove_amount) // bpmtenth = zentel der bpm?
{
  int32_t base_tick_duration = 7812500 / \ (static_cast<uint32_t>(bpm) * 10 + bpm_tenth) - 1;

  for (uint8_t i = 0; i < kNumStepsInGroovePattern; ++i)  // kNumStepsInGroovePattern = 16;
  {  
    int32_t swing_direction = ResourcesManager::Lookup<int16_t, uint8_t>( LUT_RES_GROOVE_SWING + groove_template, i );
    swing_direction *= base_tick_duration;
    swing_direction *= groove_amount;
    intervals_[i] = base_tick_duration + (swing_direction >> 16);
  }
}

i assume the 7812500 is nanoseconds (7,812 ms) and this tick duration is the smallest possible tick duration right?
int32_t base_tick_duration = 7812500 / \ (static_cast<uint32_t>(bpm) * 10 + bpm_tenth) - 1;

( and what means / \ ? )

how can I interpret the following array? lets assume the midiclock has 24ppq. this array has 16 steps.
which of the 24 ticks per beat are shifted to affect the 16th grid? or the other way around… I dont find the piece of code where the 16th grid is translated to the tick level of ppq. where is that happening?

const prog_uint16_t lut_res_groove_swing[] PROGMEM = {
     127,    127,   -127,   -127,    127,    127,   -127,   -127,
     127,    127,   -127,   -127,    127,    127,   -127,   -127,
};

would be more than delighted for any help!
also any hint for code or literature concerning how groove induction in midi clocks might work is very welcome!

I have the feeling that most of the midi clock receivers are focusing on steadiness of the bpm, and fast adoption to bpm changes. I wonder to what extend groove induction is possible and when it causes jittering in the midi clock receiver.

looking forward to chat!

What do you mean by “groove induction”?

This code applies swing to the MIDIpal’s internal clock, it has nothing to do with MIDI clock receiving.

/ is Division, \ indicates that the operand is on the following line.

What do you mean by “groove induction”?

with “groove induction” i mean to alter the tick intervals of a midiclock to induce groove.

i am experimenting with sending modulated midi clocks to midi clock receivers. I thought that MIDIpal works this way but then i misunderstood.
so if MIDIpals internal clock is altered with the groove templates then it sends probably just midi notes out to other MIDI devices right?

I see… Your choice of words wasn’t very clear! “Induction” suggested some kind of analysis of generalization process from particular examples (Inductive reasoning - Wikipedia) – for example recovering swing or groove settings from an observed external MIDI clock.

I confirm that the code above alters the internal clock of the MIDIpal, which is used to schedule all messages sent by the MIDIpal (notes, clock, etc.)

recovering swing or groove settings from an observed external MIDI clock.

this is exactly what I mean with “to alter the tick intervals of a midiclock to induce groove.” as I wrote before.

I´m trying to apply groove to any groove boxes or midi interfaces with an external midi clock.
i´m wondering how most of the midi clock receivers are working internally? because that matters in the end what groove could be transmitted.
the ACME-4 from snd also has a swing parameter. but i would like to have more intense groove changes…

how does the midi receiving work in YARNS for example?
are you working with an averaging buffer and rounding of incoming tick intervals?

The MIDIpal doesn’t do what you suspect it does. Either you use the internal clock, which has swing (the code above adjusts the increment of the MIDIpal’s own timer), or you use an external clock, in which case things happen at the exact same time the MIDI clock message is received (no possibility of swing).

Yarns does what you describe, by measuring the interval elapsed between MIDI clock messages, and applying a delay before actually handling them.

Measurement of the interval elapsed between MIDI clock messages:

Handling MIDI clock messages with a delay: