TheCreator

Creates 1024 waveforms of 1024 samples each into a single wavetable in a single process. just follow the controls from top to bottom, setting them to whatever setting, though reminding of some specialities: -harmonics: sets the maximum amount of harmonics that can ever be created for any one of the waveforms -range: sets the maximum harmonic that can be reaches above root-note. -decline and damp: control the volume drop. Decline is relative to harmonic order. Damp attenuates each newly added harmonic. -changerate: is set as a digital logic AND. 0 would be every single step, 1 would be each 2 steps, 2 each 4 steps etc.. -to create a new waveform (after having set all the above parameters) press "create" don't forget to shut down the volume by adding a "*c" or mixer module! -to stop the creation process before it's finished, press interupt. (eg. if you forgot to lower the volume ;) ) -after creating a table, set the maximum allowed volume with "max" and press the "maximise" button. -you can saturate your waveform "fatbasterd" style, pressing the "sat" button (gain adds distortion) -after all of this, press "SAVE2FILE" (need to connect a string-module to enter a file name, I recommend string/indexed) -you can compare saved tables by selecting a table using the string/indexed and pressing "LOADFILE".
Author: Remco van der Most
License: BSD
Github: sss/osc/TheCreator.axo

Inlets

charptr32 filename

Outlets

frac32buffer out

int32 countCreate

int32 countSaturate

int32 countMaximise

Parameters

bool32.mom press to create a new wavetable (see output to check how many waveforms are produced at the moment)

bool32.mom press to interupt the creation process

bool32.mom press to perform maximising process (normalises waveforms to max value)

bool32.mom press to perform saturation process (fatbasterd algorythm)

bool32.mom saves table to the file, named with the filename inlet

bool32.mom loads table from the file, named with the filename inlet

bin12 nothing to do here but read what the upfollowing controls do..

bin12 nothing to do here but read what the upfollowing controls do..

bin12 MAPCHANGE-settings-for-generating-different-waves-throughtout-the-table

bin12 nothing to do here but read what the upfollowing controls do..

bin12 nothing to do here but read what the upfollowing controls do..

bin12 nothing to do here but read what the upfollowing controls do..

int32 select one of the 1024 waves after you've created a table

int32 sets the volume decline rate for each higher harmonic

int32 sets the volume decline rate for each next generated harmonic

int32 sets the maximum amount of harmonics being created per waveform

int32 sets the change-size of the amount of harmonics being created during the creation process. Rate is controlled by changerate

int32 sets the number of the first harmonic being created

int32 offsets all the other harmonics from the first harmonic with a fixed amount

int32 sets the first harmonic interval of 4 intervals

int32 sets the second harmonic interval of 4 intervals

int32 sets the third harmonic interval of 4 intervals

int32 sets the fourth harmonic interval of 4 intervals

int32 sets the maximum harmonic number contained in the generated spectrum

int32 sets the changerate. After .. amount of steps, the skip/start positions, amount of harmonics, etc, will be changed to different settings. Allowing lots of different wavetable combinations

int32 sets the start-offset change, controlled by the changerate

int32 uses the 1-bit of the counter to offset the first skip with the amount set by this control

int32 uses the 2-bit of the counter to offset the second skip with the amount set by this control

int32 uses the 3-bit of the counter to offset the third skip with the amount set by this control

int32 uses the 4-bit of the counter to offset the fourth skip with the amount set by this control

int32 uses the 5-bit of the counter to offset the offset of all harmonics after the first harmonic with the amount set by this control

int32 uses changerate to offset all skip values

frac32.s.map.pitch sets the rootnote to play the waveform

frac32.u.map phaseshifts the generated harmonics according to harmonic number

frac32.u.map sets the gain for the saturation process

frac32.u.map sets the maximum value for the wave after saturation or maximise process

Attributes

combo size

Declaration
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 = 32;
static const uint32_t GAIN = 0;
int32_t *array;

uint32_t phase;
int32_t freq;
int32_t sine;
int ctrig;
int32_t i;
int32_t j;
int32_t k;
int32_t count;
int create;
int SAT;
int strig;
int32_t caunt;
int32_t G;
int32_t temp;
int Maximise;
int32_t max;
float32_t ratio;
float32_t MAX;
float32_t Max;
int mtrig;
int32_t ciunt;
int32_t ceunt;
int changerate;
int ntrig;
int ltrig;
Init
static int32_t _array[attr_poly][LENGTH] __attribute__((section(".sdram")));
array = &_array[parent->polyIndex][0];
{
  int i;
  for (i = 0; i < LENGTH; i++)
    array[i] = 0;
}
create = 0;
SAT = 0;
Maximise = 0;
ntrig = 0;
ltrig = 0;
Control Rate
if (param_create > 0) {
  create = 1;
}
if (param_interupt) {
  create = 0;
}
if (param_sat > 0) {
  SAT = 1;
}
if (param_Maximise > 0) {
  Maximise = 1;
}
changerate = ((1 << param_changerate) - 1);
int32_t harmonics = param_harmonics;
if ((create > 0) && !ctrig) {
  count += 1;
  int32_t A = (count & 1) * param_Astep;
  int32_t B = (count & 3) * param_Bstep;
  int32_t C = (count & 7) * param_Cstep;
  int32_t D = (count & 15) * param_Dstep;
  int32_t E = (count & 31) * param_Estep;
  int32_t F = (count >> (10 - param_changerate)) * param_Fstep;
  harmonics =
      param_harmonics + (count >> (10 - param_changerate)) * param_harmChange;
  harmonics = harmonics - (harmonics / (param_harmonics)) * param_harmonics;
  harmonics = harmonics > 0 ? harmonics : 1;
  MAX = param_max;

  int32_t start =
      param_start + (count >> (10 - param_changerate)) * param_startstep;
  start = start - (start / param_harmonics) * param_harmonics;
  start = start >= param_harmonics ? param_harmonics : start;

  int32_t skip1 = param_skip1 + A + F;
  int32_t skip2 = skip1 + A + param_skip2 + B + F;
  int32_t skip3 = (skip2 + B) * 2 + param_skip3 + F;
  int32_t skip4 = (skip3 + C) * 2 + param_skip4 + D + F;
  int32_t skip5 = (skip4 + D) * 2;

  for (i = 0; i < 1024; i++) {
    array[i + count * 1024] = 0;
  }
  for (i = 0; i < 1024; i++) {
    for (j = start; j < (start + param_harmonics); j++) {
      k = (j & 1) * skip1 + ((j >> 1) & 1) * skip2 + ((j >> 2) & 1) * skip3 +
          ((j >> 3) & 1) * skip4 + (j >> 4) * skip5;
      if (j > start) {
        k += param_offstart + E;
      }
      k = k - (k / param_range) * param_range + 1;
      SINE2TINTERP((i << 22) * k +
                       ((param_phaseshift + (E << 30)) * (k - 1) << 4),
                   sine);
      array[(i + (count << 10)) & LENGTHMASK] +=
          (sine >> 5) / (param_decline * k * (j / (param_damp + 1)));
    }
  }
  if (count > (1 << 10)) {
    ctrig = 1;
    create = 0;
  }
} else if (create == 0) {
  ctrig = 0;
  count = -1;
}

if ((SAT > 0) && !strig) {
  caunt += 1;
  for (G = 0; G < 1024; G++) {
    temp = array[(G + (caunt << 10)) & LENGTHMASK];
    int dir = temp > 0 ? 1 : -1;
    int32_t in = temp > 0 ? temp : -temp;
    int32_t gian = ___SMMUL(param_gain << 3, param_gain << 2);
    float32_t gain = ___SMMUL((gian + (1 << 17)) << 2, in << 3);
    gain = 1 + gain / (1 << 19);
    array[(G + (caunt << 10)) & LENGTHMASK] =
        ((param_max) - ((param_max)-in) / gain) * dir;
  }
  if (caunt > (1 << 10)) {
    strig = 1;
    SAT = 0;
  }
} else if (SAT == 0) {
  strig = 0;
  caunt = -1;
}

if ((Maximise > 0) && !mtrig) {
  ciunt += 1;
  max = 0;
  for (G = 0; G < 1024; G++) {
    temp = array[(G + (ciunt << 10)) & LENGTHMASK];
    temp = temp > 0 ? temp : -temp;
    max = temp > max ? temp : max;
    Max = G >= 1023 ? max : Max;
  }
  ratio = (float32_t)((float32_t)(MAX)) / ((float32_t)(Max));
  for (G = 0; G < 1024; G++) {
    array[(G + (ciunt << 10)) & LENGTHMASK] =
        ((float32_t)(array[(G + (ciunt << 10)) & LENGTHMASK])) * ratio;
  }
  if (ciunt > (1 << 10)) {
    mtrig = 1;
    Maximise = 0;
  }
} else if (Maximise == 0) {
  mtrig = 0;
  ciunt = -1;
}

MTOFEXTENDED(param_freq, freq)
int32_t wave = param_wave * 1024;
outlet_countCreate = count;
outlet_countSaturate = caunt;
outlet_countMaximise = ciunt;

if ((param_SAVE2FILE > 0) && !ntrig) {
  ntrig = 1;
  FIL FileObject;
  FRESULT err;
  UINT bytes_written;
  err = f_open(&FileObject, inlet_filename, FA_WRITE | FA_CREATE_ALWAYS);
  if (err != FR_OK) {
    report_fatfs_error(err, inlet_filename);
    return;
  }
  int rem_sz = sizeof(*array) * LENGTH;
  int offset = 0;
  while (rem_sz > 0) {
    if (rem_sz > sizeof(fbuff)) {
      memcpy((char *)fbuff, (char *)(&array[0]) + offset, sizeof(fbuff));
      err = f_write(&FileObject, fbuff, sizeof(fbuff), &bytes_written);
      rem_sz -= sizeof(fbuff);
      offset += sizeof(fbuff);
    } else {
      memcpy((char *)fbuff, (char *)(&array[0]) + offset, rem_sz);
      err = f_write(&FileObject, fbuff, rem_sz, &bytes_written);
      rem_sz = 0;
    }
  }
  if (err != FR_OK)
    report_fatfs_error(err, inlet_filename);
  err = f_close(&FileObject);
  if (err != FR_OK)
    report_fatfs_error(err, inlet_filename);
} else if (!(param_SAVE2FILE > 0))
  ntrig = 0;

if ((param_LOADFILE > 0) && !ltrig) {
  ltrig = 1;
  FIL FileObject;
  FRESULT err;
  UINT bytes_read;
  err = f_open(&FileObject, inlet_filename, FA_READ | FA_OPEN_EXISTING);
  if (err != FR_OK) {
    report_fatfs_error(err, inlet_filename);
    return;
  }
  int rem_sz = sizeof(*array) * LENGTH;
  int offset = 0;
  while (rem_sz > 0) {
    if (rem_sz > sizeof(fbuff)) {
      err = f_read(&FileObject, fbuff, sizeof(fbuff), &bytes_read);
      if (bytes_read == 0)
        break;
      memcpy((char *)(&array[0]) + offset, (char *)fbuff, bytes_read);
      rem_sz -= bytes_read;
      offset += bytes_read;
    } else {
      err = f_read(&FileObject, fbuff, rem_sz, &bytes_read);
      memcpy((char *)(&array[0]) + offset, (char *)fbuff, bytes_read);
      rem_sz = 0;
    }
  }
  if (err != FR_OK) {
    report_fatfs_error(err, inlet_filename);
    return;
  };
  err = f_close(&FileObject);
  if (err != FR_OK) {
    report_fatfs_error(err, inlet_filename);
    return;
  };
} else if (!(param_LOADFILE > 0))
  ltrig = 0;
Audio Rate
if (create == 0) {
  phase += freq;
  int32_t mix;
  mix = 0;
  mix = array[(phase >> 22) + wave] >> 2;
  mix += array[(((phase - freq) & ((1 << 32) - 1)) >> 22) + wave] >> 2;
  mix += array[(((phase - (freq << 1)) & ((1 << 32) - 1)) >> 22) + wave] >> 2;
  mix += array[(((phase - freq * 3) & ((1 << 32) - 1)) >> 22) + wave] >> 2;
  outlet_out = mix;
} else {
  outlet_out = 0;
}

Privacy

© 2024 Zrna Research