polyCCs

Receives Midi Continuous Controller messages from the Quneo midicontroller Only the two bottom rows of pads will be read Each pad-layer will be send to it's own control-output The hold-function makes sure the output won't be reset to zero when releasing, but holding the last CC value, even if the pads are set to reset to zero (needed for turning the LEDS off in "normal mode" after releasing the pad). Note though, that this doesn't really work for the pressure-control, as it will go down to zero if you release the pad anyways..
Author: Remco van der most
License: BSD
Github: sss/quneo/polyCCs.axo

Inlets

bool32 active

bool32 save

bool32 load

charptr32 filename

Outlets

int32 layer

frac32 a1

frac32 a2

frac32 a3

frac32 a4

frac32 a5

frac32 a6

frac32 a7

frac32 a8

frac32 b1

frac32 b2

frac32 b3

frac32 b4

frac32 b5

frac32 b6

frac32 b7

frac32 b8

frac32 c1

frac32 c2

frac32 c3

frac32 c4

frac32 c5

frac32 c6

frac32 c7

frac32 c8

frac32 d1

frac32 d2

frac32 d3

frac32 d4

frac32 d5

frac32 d6

frac32 d7

frac32 d8

Parameters

bool32.tgl hold

Attributes

spinner cc

Declaration
static const uint32_t LENGTHPOW = (5);
static const uint32_t LENGTH = 32;
static const uint32_t LENGTHMASK = 31;

int8_t *ccv;

bool strig;
bool ltrig;

int i;
uint8_t _note;
bool _gate[32];
bool hold;
int NT;
uint8_t nt;
bool act;
Init
static int8_t _array[LENGTH] __attribute__((section(".sdram")));
ccv = &_array[0];
Control Rate
if ((inlet_load > 0) && !ltrig) {
  ltrig = 1;
  FIL FileObject;
  FRESULT err;
  UINT bytes_read;
  codec_clearbuffer();
  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(*ccv) * 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 *)(&ccv[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 *)(&ccv[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 (!(inlet_load > 0))
  ltrig = 0;

if ((inlet_save > 0) && !strig) {
  strig = 1;
  FIL FileObject;
  FRESULT err;
  UINT bytes_written;
  codec_clearbuffer();
  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(*ccv) * LENGTH;
  int offset = 0;
  while (rem_sz > 0) {
    if (rem_sz > sizeof(fbuff)) {
      memcpy((char *)fbuff, (char *)(&ccv[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 *)(&ccv[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 (!(inlet_save > 0))
  strig = 0;

outlet_a1 = ccv[0] << 20;
outlet_a2 = ccv[1] << 20;
outlet_a3 = ccv[2] << 20;
outlet_a4 = ccv[3] << 20;
outlet_a5 = ccv[4] << 20;
outlet_a6 = ccv[5] << 20;
outlet_a7 = ccv[6] << 20;
outlet_a8 = ccv[7] << 20;
outlet_b1 = ccv[8] << 20;
outlet_b2 = ccv[9] << 20;
outlet_b3 = ccv[10] << 20;
outlet_b4 = ccv[11] << 20;
outlet_b5 = ccv[12] << 20;
outlet_b6 = ccv[13] << 20;
outlet_b7 = ccv[14] << 20;
outlet_b8 = ccv[15] << 20;
outlet_c1 = ccv[16] << 20;
outlet_c2 = ccv[17] << 20;
outlet_c3 = ccv[18] << 20;
outlet_c4 = ccv[19] << 20;
outlet_c5 = ccv[20] << 20;
outlet_c6 = ccv[21] << 20;
outlet_c7 = ccv[22] << 20;
outlet_c8 = ccv[23] << 20;
outlet_d1 = ccv[24] << 20;
outlet_d2 = ccv[25] << 20;
outlet_d3 = ccv[26] << 20;
outlet_d4 = ccv[27] << 20;
outlet_d5 = ccv[28] << 20;
outlet_d6 = ccv[29] << 20;
outlet_d7 = ccv[30] << 20;
outlet_d8 = ccv[31] << 20;
outlet_layer = _note;
hold = param_hold;
act = inlet_active;
Midi Handler
if (act > 0) {
  if ((status == MIDI_NOTE_ON + attr_midichannel) && (data2)) {
    nt = data1;
    NT = data1 - 36;
    _note = (NT) / 12;
    NT = NT - _note * 12;
    _gate[NT] = 1;

  } else if (((status == MIDI_NOTE_ON + attr_midichannel) && (!data2)) ||
             (status == MIDI_NOTE_OFF + attr_midichannel)) {
    if (nt == data1) {
      NT = data1 - 36;
      NT = NT - NT / 12 * 12;
      _gate[NT] = 0;
    }
  } else if ((status == attr_midichannel + MIDI_CONTROL_CHANGE) &&
             (data1 == MIDI_C_ALL_NOTES_OFF)) {
    for (i = 0; i < 32; i++) {
      _gate[i] = 0;
    }
  }

  for (i = 0; i < 8; i++) {
    if (_gate[i] > 0) {
      if ((status == attr_midichannel + MIDI_CONTROL_CHANGE) &&
          (data1 == attr_cc + i * 3) && ((!(data2 == 0)) || (!hold))) {
        ccv[i + (_note << 3)] = data2;
      }
    }
  }
}

Privacy

© 2024 Zrna Research