melGen1x

stackable melody generator Each stacked generator can add it's own note change to the entire sequence Together they create an entire sequence with multiple layers to connect your oscillators to. Each bar a "fill" is generated which starts from the "start" minus the shift parameter for the length of "barlenght-start"(what's left). The fill goes around the semitone scale toward the next note in the bars-sequence in steps based on chord scaling (2 steps within the scale each time) and holds this new note until the bar restarts (and then it is the actual current note). Stacking several of them with first a couple short, quick sequences with not many octaves and semitones in it, followed by a couple of slower ones, provides a really nice start to experiment.
Author: Remco van der Most
License: BSD
Github: sss/patt/melGen1x.axo

Inlets

int32 connect to former stacked semi output (inlet acts as INDEX!! selector for notes within a chord!)

int32 connect to former stacked oct output (octave index as in +1,+2,+3,etc)

bool32.rising trigger to advance sequence

bool32.rising reset sequencer

Outlets

bool32.pulse carry pulse of bar restart

bool32.pulse carry pulse of bar repeat restart

int32 connect to semi-input of next stacked module (outputs semitone INDEX!! for 7 semitones in a scale, thus not actual semitone pitch!)

int32 connect to octi-input of next stacked module (outputs the octave value as +1/+2 etc)

int32 outputs it's own internal sequence (in actual pitch info)

int32 outputs the sum of external and internal sequences (in actual pitch info)

Parameters

int32 bar count length

int32 amount of bar repeats

int32 maximum amount of octaves

int32 amount of semi tones present (above 1 is multiplied by two and only selecting within scale to select notes in standard chords)

frac32.u.map startpoint of fill in relation to bar length (length=barlength-start)

frac32.u.map shifts the start of the fill forward

bool32.tgl integrates the external semi and octave inputs into it's own limitators

Attributes

combo size

Declaration
int ntrig;
int rtrig;
int count;

static const uint32_t LENGTHPOW = (attr_size);
static const uint32_t LENGTH = (1 << attr_size);
static const uint32_t LENGTHMASK = ((1 << attr_size) - 1);
static const uint32_t BITS = 8;
static const uint32_t GAIN = 20;
int8_t *array;
int32_t cnt;
int note[7] = {0, 2, 4, 5, 7, 9, 11};
int stp, ofs;
Init
count = 0;
ntrig = 0;
rtrig = 0;
static int8_t _array[attr_poly][LENGTH] __attribute__((section(".sdram")));
array = &_array[parent->polyIndex][0];
{
  int i;
  array[0] = 0;
  for (i = 1; i < LENGTH; i++) {
    int chg = (int32_t)(GenerateRandomNumber() % 21);
    chg += (chg % 7) == 0 ? 1 : 0;
    array[i] = array[i - 1] + chg;
  }
}
stp = (int32_t)GenerateRandomNumber() % 14;
stp += (stp % 7) == 0 ? 1 : 0;
Control Rate
outlet_restartbar = 0;
outlet_restartbars = 0;
int s1, s2, o1, o2;

if (param_integrate) {
  s1 = o1 = 0;
  s2 = inlet_semi;
  o2 = inlet_oct * 7;
} else {
  s2 = o2 = 0;
  s1 = inlet_semi;
  o1 = inlet_oct;
}
if ((inlet_trig > 0) && !ntrig) {
  count += 1;
  if (count >= param_bar) {
    ofs = 0;
    count = 0;
    outlet_restartbar = 1;
    cnt += 1;
    stp = (int32_t)GenerateRandomNumber() % 8;
    stp += (stp % 7) == 0 ? 1 : 0;
    if (cnt >= param_bars) {
      cnt = 0;
      outlet_restartbars = 1;
    }
  }
  ntrig = 1;
} else if (!(inlet_trig > 0))
  ntrig = 0;
if ((inlet_r > 0) && !rtrig) {
  count = 0;
  cnt = 0;
  rtrig = 1;
  outlet_restartbar = 1;
} else if (!(inlet_r > 0))
  rtrig = 0;
int shft = ___SMMUL(param_shift, param_bar << 5);
int ct = (count + shft) % param_bar;
int start = ___SMMUL(param_bar << 5, param_start);
int left = __USAT(count - start, 28);
ct = cnt;
if (left > 0) {
  left = (param_bar - start - left) * stp;
  ofs = 1;
}
int mem = (array[ct + ofs & LENGTHMASK] + left);
left = mem + s2 + o2;

int oct = left / param_semis;
if ((left < 0) && (left > -param_semis)) {
  oct -= 1;
}
left = left % param_semis;
left += left < 0 ? param_semis : 0;
left *= 2;
left += s1;
left = left % 7;
left += left < 0 ? 7 : 0;

oct = oct % param_octaves;
oct += (oct < 0 ? param_octaves : 0) + o1;
outlet_sum = note[left] + oct * 12;
outlet_semi = left;
outlet_oct = oct;

left = mem;
oct = left / param_semis;
if ((left < 0) && (left > -param_semis)) {
  oct -= 1;
}
left = left % param_semis;
left += left < 0 ? param_semis : 0;
left *= 2;
left = left % 7;
left += left < 0 ? 7 : 0;
outlet_self = note[left] + oct * 12;

Privacy

© 2024 Zrna Research