transport

midi loopertransport module. not much use for much else. has a few 96ppq clocks set to different/changing offsets and handles the controls
Author: Mattilyn Matroe
License: 5 jars of peanut buttter per use in a grammy winning performance
Github: matroe/midi looper/transport.axo

Inlets

int32 offset

int32 clipslot

bool32.rising record

bool32 input

bool32 96ppq

bool32 bartrig

bool32 recbartrig

bool32 initrig

bool32 trigger

bool32 overdub

bool32 stop

bool32 clear

bool32 erase

Outlets

int32 stepunQP

int32 stepunQR

int32 stepunQCC

int32 copy

int32 copyR

int32 barcount

int32 length

int32 tablesize

int32 erasenote

bool32 recshift

bool32 output

bool32 record

bool32 overdub

bool32 wait

bool32 full

bool32 reset

bool32 cleartrigger

Attributes

objref table

spinner bar

spinner voices

spinner clipslots

spinner channel

combo output

Declaration
int wait;
int voice;
int R;
int Rwait;
int prevclipslot;
int stepunQ;
int copyclock;
int qtrig;
int ocol;
int clipslot;

int prevfull;
int playslot;

int prevbrcount;
int RC;
int RCWait;
int clipoffs;
int ktrig;

int modetrig;

int RR;
int bendvoice;
int pct;
int currentdub;
int dubtrig;
int length;
int xtrighold;
int xtrigQ;
int lengthout;
int full;
int count;
int barcount;
int ptrig;
int recshift;
int otrig;
int retrig;
int rectrig;
int brtrig;
int strig;
int atrig;
int play;
int record;
int overdub;
int xtrig;
int total;
int ltrig;
int ertrig;
int ntrig;
int rtrig;
int budd;
int speed;
int clear;
int cleartrig;
int erasenote;
int erase;
int erasegate;
uint32_t i;
uint32_t ii;
uint32_t src;
uint32_t dst;
uint32_t range;
uint32_t block;
Init
voice = ((attr_bar << 9) - ((attr_bar << 9) >> 2));
bendvoice = (voice * 5);
budd = ((voice + voice + voice) * attr_voices);
clear = 1;
prevclipslot = 0;

R = budd;
RC = budd;
clipslot = 0;
clipoffs = (attr_clipslots * (budd + bendvoice)) + budd + budd;
Control Rate
// stepunQ
if ((inlet_96ppq > 0) && !qtrig) {
  stepunQ += 1;
  copyclock += 1;

  if (stepunQ == 13) {
    copyclock = 0;
    if (RCWait) {
      RC = R;
      RCWait = 0;
    }
  }
  qtrig = 1;
} else if (!(inlet_96ppq > 0))
  qtrig = 0;
if (inlet_clipslot != pct) {
  if (inlet_bartrig) {
    pct = inlet_clipslot;
    ltrig = 1;
  }
}

if (xtrigQ) {
  stepunQ = 0;
  barcount = 0;
  length = 0;
}

if (inlet_initrig && !otrig) {
  stepunQ = 48;
  otrig = 1;
} else if (!inlet_initrig) {
  otrig = 0;
}

if (inlet_active && !atrig) {
  stepunQ = 0;
  atrig = 1;
}
if (!inlet_active && atrig) {
  atrig = 0;
  ltrig = 1;
  play = 0;
  record = 0;
  wait = 0;
}

if ((inlet_clipslot != prevclipslot) && (inlet_clipslot < (attr_clipslots))) {
  prevfull = full;
  Rwait = 1;
}

retrig = 0;
ltrig = 0;
xtrig = 0;
xtrigQ = 0;
full = attr_table.array[clipslot + clipoffs];

lengthout = full;
outlet_full = attr_table.array[inlet_clipslot + clipoffs];

if (inlet_overdub && !dubtrig) {
  overdub = !overdub;
  if (overdub) {
    ocol = 9;
  } else if (!overdub) {
    ocol = 11;
  }

  currentdub = overdub;
  dubtrig = 1;
}
if (!inlet_overdub) {
  dubtrig = 0;
}
if (inlet_bartrig && !brtrig) {
  brtrig = 1;
  barcount += 1;
  if (barcount > attr_bar) {
    barcount = 0;
  }
  if (recshift) {
    recshift = 0;
  }
  if (modetrig) {
    modetrig = 0;
    xtrigQ = 1;
  }
  if (xtrighold) {
    xtrigQ = 1;
    xtrighold = 0;
  }
}
//	}
if (!inlet_bartrig) {
  brtrig = 0;
}

if (inlet_recbartrig && !rectrig) {
  length += 1;
  count += 1;
  rectrig = 1;
  if ((length >= lengthout) && (lengthout > 0)) {
    length = 0;
    xtrig = 1;
    xtrighold = 1;
    retrig = 1;
  }

  if (wait) {
    wait = 0;
    retrig = 1;
  }
}
if (!inlet_recbartrig) {
  rectrig = 0;
}

if (inlet_active) {
  // stop
  if (inlet_stop && !strig) {

    strig = 1;
    wait = 1;
  }

  // play/record

  if (inlet_trigger && !ptrig && !strig &&
      (inlet_clipslot < (attr_clipslots)) && (!inlet_clear) && !ktrig) {
    if (record) {
      attr_table.array[clipslot + clipoffs] = length + 1;
    }

    ptrig = 1;
    wait = 1;
  }

  // record

  if (inlet_record && !ptrig) {

    attr_table.array[inlet_clipslot + clipoffs] = 0;
    full = 0;

    ptrig = 1;
    wait = 1;
  }

  if (retrig && !strig) {
    if (ptrig) {
      R = (inlet_clipslot * (budd + bendvoice)) + budd;
      RCWait = 1;
      clipslot = inlet_clipslot;
      full = attr_table.array[clipslot + clipoffs];
      playslot = inlet_clipslot;
    }

    if ((full) && ptrig) {

      length = 0;
      play = 1;
      record = 0;
      ptrig = 0;
      xtrig = 1;
      xtrighold = 1;
      prevclipslot = inlet_clipslot;
    } else if (!full && ptrig) {
      if (play || record) {
        clear = 0;
        cleartrig = 1;
        ltrig = 1;
      }

      length = 0;
      record = 1;
      recshift = 1;
      count = 0;
      play = 0;
      ptrig = 0;
      xtrig = 1;
      xtrighold = 1;
      prevclipslot = inlet_clipslot;
    }
  }
}

if (strig && retrig) {

  strig = 0;
  play = 0;
  record = 0;
}

// maxbar
if (record && (length == attr_bar)) {
  attr_table.array[clipslot + clipoffs] = length;

  xtrig = 1;
  xtrighold = 1;
  length = 0;
  record = 0;
  play = 1;
}

if (lengthout == 0) {
  lengthout = attr_bar;
}

// save load clear
if (inlet_clipslot < (attr_clipslots)) {
  if (inlet_clear && !ktrig) {
    if (inlet_clipslot == playslot) {
      play = 0;
      record = 0;
    }
    ktrig = 1;
    attr_table.array[inlet_clipslot + clipoffs] = 0;
    clear = 0;
    cleartrig = 1;
    ltrig = 1;

    ntrig = 1;
    i = 0;
    rtrig = 0;
    // overdub=0;
  }
  if (!inlet_clear) {
    ktrig = 0;
  }

  speed = 16 << 4;

  range = budd;
  block = (range / speed) * speed;
  src = (inlet_clipslot * (budd + bendvoice)) + budd;
  dst = (inlet_clipslot * (budd + bendvoice)) + budd;

  if ((i == range) && (!inlet_trigger)) {
    ntrig = 0;
    i = 0;
    clear = 1;
  }

  // copy n chunks of size 'speed'
  if (ntrig && (i < block)) {
    {
      for (ii = 0; ii < speed; ii++)
        attr_table.array[(i + ii + dst)] =
            ((attr_table.array[(i + ii + src)]) * (clear));
    }
    i += speed;
  }

  // copy what's left
  if (i == block)
    rtrig = 1;

  if ((ntrig && rtrig) && (i < (range))) {
    attr_table.array[(i + dst)] = ((attr_table.array[(i + src)]) * (clear));
    i += 1;
  }
}
erase = inlet_erase;
if (!erase || !erasegate) {
  erasenote = 0;
}
if (inlet_erase) {
  overdub = 0;
  ertrig = 0;
}
if (!inlet_erase && !ertrig) {
  ertrig = 1;
  overdub = currentdub;
}

outlet_copy = copyclock;
outlet_copyR = copyclock + RC;
outlet_barcount = length + 1;
outlet_overdub = overdub;
outlet_play = play;
outlet_record = record;
outlet_wait = wait;
outlet_overdub = overdub;
outlet_length = lengthout;
outlet_stepunQR = stepunQ;
outlet_stepunQP = stepunQ + R;
outlet_stepunQCC = stepunQ + R + budd;
outlet_recshift = recshift;
outlet_cleartrigger = ltrig;
outlet_reset = xtrigQ;

outlet_erasenote = erasenote;

outlet_tablesize =
    (attr_clipslots * (budd + bendvoice)) + budd + budd + attr_clipslots;
Midi Handler
if (dev != MIDI_DEVICE_INTERNAL) {

  if ((status == MIDI_NOTE_ON + (attr_channel - 1)) && (data2) && erase) {
    erasenote = data1;
    erasegate = 1;
    MidiSend3((midi_device_t)attr_output, MIDI_NOTE_OFF + (attr_channel - 1),
              data1, data2);
  }

  if (((status == MIDI_NOTE_OFF + (attr_channel - 1)) ||
       ((status == MIDI_NOTE_ON + (attr_channel - 1)) && (!data2))) &&
      erase) {
    if (erasenote == data1) {
      erasegate = 0;
    }
  }
}

Privacy

© 2024 Zrna Research