Existe un array con todas las divisiones binarias y ternarias:
const int subdivisionesArray [12] = {2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96};
Cada modo se cambia mediante valores en la variable llamada subDivMode:
El número de subdivisión indica cuantos mensajes MIDIClock debe pasar para tocar la nota.
Para binarias y ternarias, solo es necesario ir sumando el indice de subdivisionesArray cada vez que se le da al botón:
if(subDivMode == 0){ //Modo binario-ternario
if (!repeated && tiempoActualMillis - ultimoTiempoBoton >= 250){
if (indiceSubdivisiones < 11){
indiceSubdivisiones++;
updateLCD = true;
repeated = true;
ultimoTiempoBoton = tiempoActualMillis;
}
}
}
Para las subdivisiones unicamente binarias saltamos entre los valores impares:
else if(subDivMode == 1){ //modo solo binarios
if (!repeated && tiempoActualMillis - ultimoTiempoBoton >= 250){
if (indiceSubdivisiones < 11){
indiceSubdivisiones += 2;
updateLCD = true;
repeated = true;
ultimoTiempoBoton = tiempoActualMillis;
}
}
}
Para las subdivisiones compuestas es más complicado, pues no son divisibles entre mensajes MIDI. Para ello, dividimos el tiempo que pasa cada 96 mensajes clock (una redonda) y dividimos entre la subdivisión compleja:
else if(subDivMode == 2){
nClockMsg++;
if(pulsoClock == 0){
subdivision = subdivisionesComplejasArray[indComplexSubdivY][indComplexSubdivX];
tiempoClock1 = micros();
if (tiempoClock2 != 0 && nClockMsg > 1) {
sumaTiempos = tiempoClock1 - tiempoClock2;
if(primeraMedicion){microsSubdivision = sumaTiempos*4 / subdivision;}
else{microsSubdivision = sumaTiempos / subdivision;}
tiempoUltimaNota = tiempoClock1;
primerPulso = true;
primeraMedicion = false;
}
updateLCD = true;
tiempoClock2 = tiempoClock1;
}
pulsoClock++;
if(pulsoClock >= lecturaPulsoClock){
pulsoClock = 0;
lecturaPulsoClock = 96;
}
Para evitar que se lancen notas antes de tener un valor que restar, ponemos un valor mínimo en microsSubdivision para ejecutar la nota. Además, para evitar que se lancen dos notas justo al final, tambien se pone un limite para que la distancia entre una nota y otra tiene que ser de más de 15ms:
else if (microsSubdivision >= 10000 && (tiempoActualMicros - tiempoUltimaNota > microsSubdivision)){
unsigned long tiempoDesdeInicioRedonda = tiempoActualMicros - tiempoClock1;
unsigned long duracionRedondaTeorica = microsSubdivision * subdivision;
if (tiempoDesdeInicioRedonda < (duracionRedondaTeorica - 15000)) { //limite 15ms
tiempoUltimaNota += microsSubdivision; //para evitar el desfase
dispararNotaMode2();
}
Las subdivisiones complejas se organizan de la siguiente manera. Tenemos un numerador, el numero de notas del grupeto y un denominador, la figura donde cabrán esas cinco notas. Ese denominador será de figura de redonda, blanca y negra: