Timing and speed issues with pin change interrupt based routines - Arduino slow?

Again, can you give figures please? What speeds? What is "too delayed"?

I don't have a logic analyser and since the delays are random it is hard to measure on my scope but it is about 80-100 uS of delay.
Anything more than about 10uS is really noticeable.

Maybe sketch the sort of input pulses you are expecting. Are you saying you have 4 x 500 Hz pulses, where they may fire in close proximity? How close? What is an acceptable detection rate?

there are actually 12 input pulses that may fire at rates of up to 500Hz asychronously. It is possible at any time to have up to 8 fire at exactly the same time (or very close). The delay in reading these would be one of the main contributors to timing issues on the generated gates and processing them with less than 10uS error would be ideal.
Also using interrupts meant that these delays introduced were always random quantities. At least with the polling the jitter was more consistent in behavior.

The analogRead takes around 104 uS, so whether or not you do it infrequently, whenever you do that there is a window of 104 uS when you won't detect anything, especially in a polling loop. It's possible to do analog reads asynchronously.

I didn't see how I could get around this unless it was being polled and everything else was interrupt driven. How do you read it asynchronously?

You haven't posted your attempt to use interrupts, so we can't comment on the method you used.

Here is my code with ISRs.

#include "pins_arduino.h"

volatile uint8_t *port_to_pcmask[] = {
  &PCMSK0,
  &PCMSK1,
  &PCMSK2
};

static int PCintMode[24];

typedef void (*voidFuncPtr)(void);

volatile static voidFuncPtr PCintFunc[24] = {
  NULL };

volatile static uint8_t PCintLast[3];

/*
 * attach an interrupt to a specific pin using pin change interrupts.
 */
 void PCattachInterrupt(uint8_t pin, void (*userFunc)(void), int mode) {
  uint8_t bit = digitalPinToBitMask(pin);
  uint8_t port = digitalPinToPort(pin);
  uint8_t slot;
  volatile uint8_t *pcmask;

  // map pin to PCIR register
  if (port == NOT_A_PORT) {
    return;
  }
  else {
    port -= 2;
    pcmask = port_to_pcmask[port];
  }

// -- Fix by Baziki. In the original sources it was a little bug, which cause analog ports to work incorrectly.
  if (port == 1) {
     slot = port * 8 + (pin - 14);
  }
  else {
     slot = port * 8 + (pin % 8);
  }
// --Fix end
  PCintMode[slot] = mode;
  PCintFunc[slot] = userFunc;
  // set the mask
  *pcmask |= bit;
  // enable the interrupt
  PCICR |= 0x01 << port;
}

void PCdetachInterrupt(uint8_t pin) {
  uint8_t bit = digitalPinToBitMask(pin);
  uint8_t port = digitalPinToPort(pin);
  volatile uint8_t *pcmask;

  // map pin to PCIR register
  if (port == NOT_A_PORT) {
    return;
  }
  else {
    port -= 2;
    pcmask = port_to_pcmask[port];
  }

  // disable the mask.
  *pcmask &= ~bit;
  // if that's the last one, disable the interrupt.
  if (*pcmask == 0) {
    PCICR &= ~(0x01 << port);
  }
}

// common code for isr handler. "port" is the PCINT number.
// there isn't really a good way to back-map ports and masks to pins.
static void PCint(uint8_t port) {
  uint8_t bit;
  uint8_t curr;
  uint8_t mask;
  uint8_t pin;

  // get the pin states for the indicated port.
  curr = *portInputRegister(port+2);
  mask = curr ^ PCintLast[port];
  PCintLast[port] = curr;
  // mask is pins that have changed. screen out non pcint pins.
  if ((mask &= *port_to_pcmask[port]) == 0) {
    return;
  }
  // mask is pcint pins that have changed.
  for (uint8_t i=0; i < 8; i++) {
    bit = 0x01 << i;
    if (bit & mask) {
      pin = port * 8 + i;
      // Trigger interrupt if mode is CHANGE, or if mode is RISING and
      // the bit is currently high, or if mode is FALLING and bit is low.
      if ((PCintMode[pin] == CHANGE
          || ((PCintMode[pin] == RISING) && (curr & bit))
          || ((PCintMode[pin] == FALLING) && !(curr & bit)))
          && (PCintFunc[pin] != NULL)) {
        PCintFunc[pin]();
      }
    }
  }
}


SIGNAL(PCINT0_vect) {
  PCint(0);
}
SIGNAL(PCINT1_vect) {
  PCint(1);
}
SIGNAL(PCINT2_vect) {
  PCint(2);
}

//**************************************************************************************************************************************************************************************************************************************


//DIGITAL INPUT PINS
#define EOA1pin 14
#define EOA2pin 15
#define EOA3pin 16
#define EOA4pin 17

byte EOApin[] = {EOA1pin, EOA2pin, EOA3pin, EOA4pin};

#define EOC1pin 10
#define EOC2pin 11
#define EOC3pin 12
#define EOC4pin 13

byte EOCpin[] = {EOC1pin, EOC2pin, EOC3pin, EOC4pin};

#define TRIG1pin 0
#define TRIG2pin 1
#define TRIG3pin 2
#define TRIG4pin 3

byte TRIGpin[] = {TRIG1pin, TRIG2pin, TRIG3pin, TRIG4pin};


#define QUADSWApin 8
#define QUADSWBpin 9



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ swapped pins 2 and 4 to correct mistake!
//ANALOG INPUT PINS
#define MODESW1pin 4
#define MODESW2pin 5
#define MODESW3pin 6
#define MODESW4pin 7

byte MODESWpin[] = {MODESW1pin, MODESW2pin, MODESW3pin, MODESW4pin};

//DIGITAL OUTPUT PINS
#define GATE1pin 4
#define GATE2pin 5
#define GATE3pin 6
#define GATE4pin 7

byte GATEpin[] = {GATE1pin, GATE2pin, GATE3pin, GATE4pin};


#define AR    0
#define AD    1
#define LOOP  2


#define OFF 0
#define ON  1

volatile byte state = 0;

byte mode[4] = {AR,AR,AR,AR};
byte prevMode[4] = {AR,AR,AR,AR};

byte quadMode[2] = {OFF, OFF};

volatile byte EOA_flag[4] = {OFF, OFF, OFF, OFF};
volatile byte EOC_flag[4] = {OFF, OFF, OFF, OFF};
volatile byte TRIG_flag[4] = {OFF, OFF, OFF, OFF};


//**************************************************************************************************************************************************************************************************************************************
void setup() {
  
  
  for (int i = 0; i<4; i++) {
    pinMode(EOApin[i], INPUT);
    digitalWrite(EOApin[i], LOW);
    pinMode(EOCpin[i], INPUT);
    digitalWrite(EOCpin[i], LOW);
    pinMode(TRIGpin[i], INPUT);
    digitalWrite(TRIGpin[i], LOW);
    pinMode(GATEpin[i], OUTPUT);
  }
  
  
  pinMode(QUADSWApin, INPUT);
  pinMode(QUADSWBpin, INPUT);
  digitalWrite(QUADSWApin, HIGH);
  digitalWrite(QUADSWBpin, HIGH);
 
 
 
  PCattachInterrupt(EOApin[0],EOA0,RISING);
  PCattachInterrupt(EOApin[1],EOA1,RISING);
  PCattachInterrupt(EOApin[2],EOA2,RISING);
  PCattachInterrupt(EOApin[3],EOA3,RISING);
  
 
  PCattachInterrupt(EOCpin[0],EOC0,RISING);
  PCattachInterrupt(EOCpin[1],EOC1,RISING);
  PCattachInterrupt(EOCpin[2],EOC2,RISING);
  PCattachInterrupt(EOCpin[3],EOC3,RISING);
  
  
  PCattachInterrupt(TRIGpin[0],TRIG0,CHANGE);
  PCattachInterrupt(TRIGpin[1],TRIG1,CHANGE);
  PCattachInterrupt(TRIGpin[2],TRIG2,CHANGE);
  PCattachInterrupt(TRIGpin[3],TRIG3,CHANGE); 
  
  
}


void loop() {
  
  
 modeSW_update();
 quadSW_update();
 
 
 checkEOC();
 checkTRIG();
 checkEOA();

  
}


void modeSW_update() {
int val = 0;
int newmode = 0;

   for (int i = 0; i<4; i++) {
     val = analogRead(MODESWpin[i]);
     
     if (val < 10) newmode = AD;
     if ( (val >= 10) && (val < 400) ) { newmode = AR; }
     if (val >= 400) newmode = LOOP;
     
     if (newmode != mode[i]) {
       prevMode[i] = mode[i];
       mode[i] = newmode;
       digitalWrite(GATEpin[i], LOW);  //reset envelope.
       eoc(i); //call EOC to get loop happening.
     }
     
  }
  
  
  //check if mode changed and perform action like zero envelope??
}


void quadSW_update() {
  if (!digitalRead(QUADSWApin)) quadMode[0] = ON;
    else quadMode[0] = OFF;
  if (!digitalRead(QUADSWBpin)) quadMode[1] = ON;
    else quadMode[1] = OFF;
}