/*
*/
// heapsize: ((1 + samples) * (gems * axyz * signif) TODO 1/5
#heapsize: ((1 + 4) * (5 * 3 * 2))
/*
* Heap layout is as follows:
* gems 0 - 4, per axyz (x,y,z) 2 bytes
* byte 0 MSB
* byte 1 LSB
*
*/
int maxSamples;
int maxGems;
int maxAxyz;
int maxSignif;
int heapOffset(int sample, int gem, int axyz, int signif)
{
int result = 0;
if (sample >= 0 && sample < maxSamples && gem >=0 && gem < maxGems && axyz >=0 && axyz < maxAxyz && signif >= 0 && signif < maxSignif) {
result = (sample * maxGems * maxAxyz * maxSignif) + (gem * maxAxyz * maxSignif) + (axyz * maxSignif) + signif;
}
return result;
}
bool gammaCorrected;
int repaintCounter;
int performStamp;
int buttonStamp;
int breathCounter;
int clockStamp;
int clockCounter;
int beatCounter;
int pulseCounter;
bool playing;
int touching;
int touchBits;
int sampleIndex;
bool playback;
int recordCount;
bool beat4;
bool beat8;
bool beat16;
int send;
bool beat;
bool setup;
void initialise()
{
maxSamples = 5; // 1 + (4 * beat)
maxGems = 5;
maxAxyz = 3;
maxSignif = 2;
repaintCounter = 0;
performStamp = 0;
clockStamp = 0;
beatCounter = -1;
sampleIndex = -1;
clockCounter = 0;
pulseCounter = -1;
playing = false;
beat4 = false;
beat8 = false;
beat16 = false;
touching = 0;
touchBits = 0;
playback = false;
recordCount = ((recorder == 1) ? 4 : ((recorder == 2) ? 8 : 0));
ensurePrimariIsActive();
send = 0;
beat = false;
setup = false;
for (int i = 0; i < 32; ++i) {
setLocalConfigActiveState (i, false, false);
}
setLocalConfig (33, 1);
gammaCorrected = getLocalConfig (33);
clearData();
}
/* gem is 1-based */
bool isActive(int gem) {
if (active == 0) { // All Gems
if (gem >= 1 && gem <= 5) return true;
} else if (active == 1) { // Gem 1
if (gem == 1) return true;
} else if (active == 2) { // Gem 2
if (gem == 2) return true;
} else if (active == 3) { // Gem 3
if (gem == 3) return true;
} else if (active == 4) { // Gem 4
if (gem == 4) return true;
} else if (active == 5) { // Gem 5
if (gem == 5) return true;
} else if (active == 6) { // Only Gems 2-5
if (gem >= 2 && gem <= 5) return true;
// } else if (active == 7) { // MultiPad Gems 2-5
// if (gem >= 2 && gem <= 5) return true;
}
return false;
}
/* index is 1-based */
int index2gem(int index) {
int result = 0;
if (active == 0) { // All Gems
if (index >= 1 && index <= 5) result = index;
} else if (active == 1) { // Gem 1
if (index == 1) result = 1;
} else if (active == 2) { // Gem 2
if (index == 1) result = 2;
} else if (active == 3) { // Gem 3
if (index == 1) result = 3;
} else if (active == 4) { // Gem 4
if (index == 1) result = 4;
} else if (active == 5) { // Gem 5
if (index == 1) result = 5;
} else if (active == 6) { // Only Gems 2-5
if (index >= 1 && index <= 4) result = index + 1;
// } else if (active == 7) { // MultiPad Gems 2-5
// if (index == 1) result = index + 1;
}
if (result) {
result = ((((active == 0?(primary - 1):(active == 6?(primary - 2):0)) + result) - 1) % 5) + 1;
int count=0;
while (!isActive(result) && count outMax ? outMax : mapped) );
}
void performCC (float v, int cc, float inMin, float inMax, bool invert, int axyz, bool output, int index)
{
int value = (mapTouchToRange (v, inMin, inMax, 16383.0));
// if (axyz == 0 && index==1) {
// log ((value >> 7) & 0x7F);
// log ((value >> 0) & 0x7F);
// log(99999999);
// output=true;
// } else {
// output=false;
// }
//
//
if (invert) value = value + 1;
int valueMSB = (value >> 7) & 0x7F;
if (invert) valueMSB = 127 - valueMSB;
if (sampleIndex>=0) setHeapByte( heapOffset(sampleIndex+1, index, axyz, 0), valueMSB);
int offsetMSB = heapOffset(0, index, axyz, 0); // (index * 3 * 2) + (axyz * 2) + 0;
int oldMSB = getHeapByte(offsetMSB);
if (oldMSB != valueMSB) {
setHeapByte( offsetMSB, valueMSB);
if (output) sendCC((channel - 1), cc, valueMSB);
}
int valueLSB = (value >> 0) & 0x7F;
if (invert) valueLSB = 127 - valueLSB;
if (sampleIndex>=0) setHeapByte( heapOffset(sampleIndex+1, index, axyz, 1), valueLSB);
int offsetLSB = heapOffset(0, index, axyz, 1); // (index * 3 * 2) + (axyz * 2) + 1;
int oldLSB = getHeapByte(offsetLSB);
if (oldLSB != valueLSB) {
setHeapByte( offsetLSB, valueLSB);
if (output && highres && cc < 32) sendCC((channel - 1), cc + 32, valueLSB);
}
performStamp = repaintCounter;
}
void handleGem(int g, float x, float y, float z, float vz)
{
if (g >= 0 && g < 5) {
if (z > 0.0 && zscale != 0.0 && z > zthreshold) {
if (( (1.0 - zthreshold) / (z - zthreshold) ) != 0.0 ) {
float scale = 1.0 + (zscale * ( 1.0 / ( (1.0 - zthreshold) / (z - zthreshold) ) ) );
x = min(max (((x - 1.0) * scale) + 1.0, 0.0), 2.0 - 0.07);
y = min(max (((y - 1.0) * scale) + 1.0, 0.0), 2.0 - 0.07);
}
}
performCC(x, getXCC(g), 0.0 + 7.0, 200.0 - 7.0, false, 0, true, g);
performCC(y, getYCC(g), 0.0 + 7.0, 200.0 - 7.0, true, 1, true, g);
performCC(z, getZCC(g), 0.0, 100.0, false, 2, true, g);
}
}
void handleSetup(float x, float y)
{
int px = int(map(x, 0.07, 1.93, 0.0, 14.0));
int py = int(map(y, 0.07, 1.93, 0.0, 14.0));
int pg = -1;
if (px == 0) {
if (py < 4) { // Beat toggle
beat = !beat;
setup = false;
} else if (py < 8) { // Reset Gems (center)
resetToCenter();
setup = false;
} else if (py < 12) { // Multitouch toggle
multitouch = !multitouch;
setup = false;
}
} else if (px == 14) {
if (py < 4) { // Record Off
recorder = 0;
recordCount = 0;
sampleIndex = 0;
playing = false;
setup = false;
} else if (py < 8) { // Record On (4)
recorder = 1;
recordCount = 4;
setup = false;
} else if (py < 12) {
// recorder = 2;
// recordCount = 8;
// setup = false;
}
} else {
if (py < 6 ) {
if ( px < 6) {
send = 1;
} else if (px < 10) {
send = 2;
} else if (px < 14) {
send = 3;
}
} else if (py < 11) {
if (px < 8) {
pg = 1;
} else {
pg = 3;
}
} else {
if (px < 5) {
pg = 0;
} else if (px < 10) {
pg = 2;
} else {
pg = 4;
}
}
}
if (pg>=0 && isActive(pg+1)) {
primary = pg + 1;
/* only send the MSB values */
if (send ==0 || send ==1) sendCC((channel - 1), getXCC(pg), 64);
if (send ==0 || send ==2) sendCC((channel - 1), getYCC(pg), 64);
if (send ==0 || send ==3) sendCC((channel - 1), getZCC(pg), 64);
}
}
void resetToCenter()
{
for (int gem = 1; gem <= maxGems; gem++) {
if (isActive(gem)) handleGem(gem-1, 1.0, 1.0, 0.0, 0.0);
}
clearData();
}
void clearData()
{
for (int s = 0; s <= maxSamples; s++) {
for (int g = 0; g < maxGems; g++) {
for (int a = 0; a < maxAxyz; a++) {
for (int b = 0; b < maxSignif; b++) {
setHeapByte( heapOffset(s,g,a,b), 0xFF);
}
}
}
}
}
void handleTouch(int index, float x, float y, float z, float vz, bool start)
{
if (index == 1 && x < 0.079 && y < 0.079) {
if (start && repaintCounter > (performStamp + 7)) {
primary = primary == 2 ? 0 : 2;
ensurePrimariIsActive();
performStamp = repaintCounter;
}
} else if (index == 1 && x < 0.079 && y > 1.923) {
if (start && repaintCounter > (performStamp + 7)) {
primary = primary == 4 ? 0 : 4;
ensurePrimariIsActive();
performStamp = repaintCounter;
}
} else if (index == 1 && x > 1.923 && y < 0.079) {
if (start && repaintCounter > (performStamp + 7)) {
primary = primary == 3 ? 0 : 3;
ensurePrimariIsActive();
performStamp = repaintCounter;
}
} else if (index == 1 && x > 1.923 && y > 1.923) {
if (start && repaintCounter > (performStamp + 7)) {
primary = primary == 5 ? 0 : 5;
ensurePrimariIsActive();
performStamp = repaintCounter;
}
} else {
int gem = index2gem(index);
if (gem) {
handleGem(gem-1, x, y, z, vz);
fadePressureMap();
}
}
}
void touchStart (int index, float x, float y, float z, float vz)
{
touching ++;
if (index >= 1 && index <= 5 && index2gem(index)) {
if (index==1 || multitouch) {
touchBits = touchBits | (1 << (index - 1));
// log(touchBits);
if (!setup) {
handleTouch(index, rotateX(x, y, 0.0, 2.0, 0), rotateY(x, y, 0.0, 2.0, 0), z, vz, true);
}
}
}
}
void touchMove (int index, float x, float y, float z, float vz)
{
if (index >= 1 && index <= 5 && index2gem(index)) {
if (index==1 || multitouch) {
touchBits = touchBits | (1 << (index - 1));
// log(touchBits);
if (!setup) {
handleTouch(index, rotateX(x, y, 0.0, 2.0, 0), rotateY(x, y, 0.0, 2.0, 0), z, vz, false);
}
}
}
}
void touchEnd(int index, float x, float y, float z, float vz)
{
touching --;
if (((multitouch && index >= 1 && index <= 5) || (!multitouch && index==1)) && index2gem(index)) {
touchBits = touchBits & ~(1 << (index - 1));
//// log(touchBits);
if (setup) {
handleSetup(rotateX(x, y, 0.0, 2.0, 0), rotateY(x, y, 0.0, 2.00, 0));
}
} else {
if (((multitouch && (index < 1 || index > (active == 6 ? 4 : 5) )) || (!multitouch && index>2))) resetToCenter();
}
}
void handleButtonDown(int index) {
if (setup) {
setup = false;
} else {
buttonStamp = repaintCounter;
}
}
void ensurePrimariIsActive() {
int count=0;
while (!isActive(primary) && count < maxGems) {
count++;
primary++;
}
}
void handleButtonUp(int index) {
if ((repaintCounter - buttonStamp) <=12) {
primary = primary >= 5 ? 1 : primary + 1;
ensurePrimariIsActive();
}
buttonStamp = 0;
}
void drawDot(int c,int a,int x,int y)
{
if (x < 0) x = 0;
if (x > 14) x = 14;
if (y < 0) y = 0;
if (y > 14) y = 14;
blendPixel(c | (a << 24), int(rotateX(float(x), float(y), 0.0, 14.0, 1)), int(rotateY(float(x), float(y), 0.0, 14.0, 1)));
}
int getColourVariation(int index)
{
int c = getColour(index);
int max = 0xFFFFFF;
int rnd = getRnd(index);
if (clockCounter>=0) {
if (beat4) {
rnd = getRandomInt(max);
setRnd(index,rnd);
}
} else {
if (!(repaintCounter % 25)) {
rnd = getRandomInt(max);
setRnd(index,rnd);
}
}
int b0 = (c >> 24) & 0xFF;
int b1 = (c >> 16) & 0xFF;
int b2 = (c >> 8) & 0xFF;
int b3 = (c >> 0) & 0xFF;
int delta = 4;
if ((rnd % 4) == 0) b0 = b0 + ((rnd % delta) - (delta / 2));
if ((rnd % 4) == 1) b1 = b1 + ((rnd % delta) - (delta / 2));
if ((rnd % 4) == 2) b2 = b2 + ((rnd % delta) - (delta / 2));
if ((rnd % 4) == 3) b3 = b3 + ((rnd % delta) - (delta / 2));
return c;
}
int getColour(int index)
{
if (index == 0) return dot1;
if (index == 1) return dot2;
if (index == 2) return dot3;
if (index == 3) return dot4;
if (index == 4) return dot5;
return 0xFFFFFF;
}
void drawSetup()
{
int xo = 2;
int yo = 1;
//drawNumber (99, 0x7FFFFFFF, 0, 0);
int c = 0xFFFFFF;
int a;
a = (send == 1) ? 0xFF : 0x7F;
// X shape
drawDot(c, a, xo + 0, yo + 0);
drawDot(c, a, xo + 2, yo + 0);
drawDot(c, a, xo + 0, yo + 1);
drawDot(c, a, xo + 2, yo + 1);
drawDot(c, a, xo + 1, yo + 2);
drawDot(c, a, xo + 0, yo + 3);
drawDot(c, a, xo + 2, yo + 3);
drawDot(c, a, xo + 0, yo + 4);
drawDot(c, a, xo + 2, yo + 4);
xo += 4;
a = (send == 2) ? 0xFF : 0x7F;
// Y shape
drawDot(c, a, xo + 0, yo + 0);
drawDot(c, a, xo + 2, yo + 0);
drawDot(c, a, xo + 0, yo + 1);
drawDot(c, a, xo + 2, yo + 1);
drawDot(c, a, xo + 1, yo + 2);
drawDot(c, a, xo + 1, yo + 3);
drawDot(c, a, xo + 1, yo + 4);
xo += 4;
a = (send == 3) ? 0xFF : 0x7F;
// Y shape
drawDot(c, a, xo + 0, yo + 0);
drawDot(c, a, xo + 1, yo + 0);
drawDot(c, a, xo + 2, yo + 0);
drawDot(c, a, xo + 2, yo + 1);
drawDot(c, a, xo + 1, yo + 2);
drawDot(c, a, xo + 0, yo + 3);
drawDot(c, a, xo + 0, yo + 4);
drawDot(c, a, xo + 1, yo + 4);
drawDot(c, a, xo + 2, yo + 4);
drawDot(0x00FF7F00, 0x4F, 0, 1);
drawDot(0x00FF7F00, 0x7F, 0, 2);
drawDot(0x00FF7F00, 0x4F, 0, 3);
drawDot(0x00FFFF00, 0x4F, 0, 5);
drawDot(0x00FFFF00, 0x7F, 0, 6);
drawDot(0x00FFFF00, 0x4F, 0, 7);
drawDot(0x0000FFFF, 0x4F, 0, 9);
drawDot(0x0000FFFF, 0x7F, 0, 10);
drawDot(0x0000FFFF, 0x4F, 0, 11);
drawDot(0x000000FF, 0x4F, 14, 1);
drawDot(0x000000FF, 0x7F, 14, 2);
drawDot(0x000000FF, 0x4F, 14, 3);
drawDot(0x0000FF00, 0x4F, 14, 5);
drawDot(0x0000FF00, 0x7F, 14, 6);
drawDot(0x0000FF00, 0x4F, 14, 7);
// drawDot(0x000000FF, 0x4F, 14, 9);
// drawDot(0x000000FF, 0x7F, 14, 10);
// drawDot(0x000000FF, 0x4F, 14, 11);
drawPressureMap();
for (int p = 0; p<5; p++) {
float flame = getFlame(p);
if (!(repaintCounter % 5)) {
flame = getRandomFloat();
setFlame(p,flame);
}
float xf = map(((2.0 / 5)*p)+0.1, 0.0, 2.0, 0.07, 1.93);
float yf = (p % 2) ? 1.1 : 1.65;
addPressurePoint(getColourVariation(p), rotateX(xf, yf, 0.07, 1.93, 1), rotateY(xf, yf, 0.07, 1.93, 1), (((4 ) * 5.0) + (flame * 5)) + (0.3 * 75.0) );
if (p == (primary - 1)) {
xf *= 7.5;
yf *= 7.5;
blendCircle(0xFFFFFFFF,rotateX(xf, yf, 0.0, 15.0, 1), rotateY(xf, yf, 0.0, 15.0, 1), 0.4, true);
}
}
fadePressureMap();
}
void drawGems()
{
if (primary == 2) {
drawDot(getColour(primary-1), 0x4F, 0, 0);
} else if (primary == 4) {
drawDot(getColour(primary-1), 0x4F, 0, 14);
} else if (primary == 3) {
drawDot(getColour(primary-1), 0x4F, 14, 0);
} else if (primary == 5) {
drawDot(getColour(primary-1), 0x4F, 14, 14);
}
// if (active == 7) {
// for (int x=0;x<15;x++) drawDot(0xFFFFFF, 0x4F, x, 8);
// }
for (int o=4; o>=0; o--) {
int p = ((primary - 1) + o) % 5;
float flame = getFlame(p);
if (clockCounter>=0) {
if (!(clockCounter % 3)) {
flame = getRandomFloat();
setFlame(p,flame);
}
} else {
if (!(repaintCounter % 3)) {
flame = getRandomFloat();
setFlame(p,flame);
}
}
int x = getHeapByte( heapOffset(0, p, 0, 0) );
int y = getHeapByte( heapOffset(0, p, 1, 0) );
int z = getHeapByte( heapOffset(0, p, 2, 0) );
if (x > 127 && y > 127) continue;
if (x > 127) x = 63;
if (y > 127) y = 63;
if (z > 127) z = 0;
float xf = map(float(x), 0.0, 127.0, 0.07, 1.93);
float yf = map(float(y), 0.0, 127.0, 1.93, 0.07);
float zf = map(float(z), 0.0, 127.0, 0.0, 1.0);
float scale = (((4 - o) * 8.0) + (flame * 24)) + (zf * 75.0);
if (beat4) {
addPressurePoint (getColourVariation(p), rotateX(xf, yf, 0.07, 1.93, 1), rotateY(xf, yf, 0.07, 1.93, 1), (((5 - o) * 16.0) + (flame * 24)) + (zf * 75.0));
} else {
addPressurePoint (getColourVariation(p), rotateX(xf, yf, 0.07, 1.93, 1), rotateY(xf, yf, 0.07, 1.93, 1), scale );
}
}
drawPressureMap();
fadePressureMap();
for (int o=4; o>=0; o--) {
int p = ((primary - 1) + o) % 5;
int x = getHeapByte( heapOffset(0, p, 0, 0) );
int y = getHeapByte( heapOffset(0, p, 1, 0) );
if (x > 127 && y > 127) continue;
if (x > 127) x = 63;
if (y > 127) y = 63;
float xf = map(float(x), 0.0, 127.0, 0.0, 14.0);
float yf = map(float(y), 0.0, 127.0, 14.0, 0.0);
blendCircle(0xFFFFFF | ( ((225 - ((o+1)*31)) + (getRnd(p) % 16)) << 24), rotateX(xf, yf, 0.0, 14.0, 1), rotateY(xf, yf, 0.0, 14.0, 1), 0.4, true);
}
}
void centerNumber(int value,int colour)
{
drawNumber(value,colour,(value<100?3:0) + (value < 10 ? 3 : 0) + (value == 1 ? -1 : 0),4);
}
void repaint()
{
int colour = getColour(primary-1);
int r = ((colour & 0xFF0000) >> 16);
int g = ((colour & 0x00FF00) >> 8);
int b = ((colour & 0x0000FF) >> 0);
float factor = 8;
int background = ((int(r / factor) & 0xFF) << 16) | ((int(g / factor) & 0xFF) << 8) | ((int(b / factor) & 0xFF) << 0);
fillRect((primary == 1) ? 0xFF000000 : background, 0, 0, 15, 15);
if (buttonStamp && (repaintCounter - buttonStamp) > 12) {
setup = !setup;
buttonStamp = 0;
}
if (setup) {
drawSetup();
} else {
drawGems();
}
if (!setup) {
if (recordCount && sampleIndex>=0 && playing) {
centerNumber(sampleIndex + 1,0x7FFFFFFF);
}
if (beat && beat4) {
drawDot(0xFFFFFF, 0xFF, 7, 0);
}
if (playback) {
drawDot(0x0000FF, 0xFF, 7, 14); // ?
}
}
if (beat4) beat4 = false;
if (beat8) beat8 = false;
if (beat16) beat16 = false;
repaintCounter++;
breathCounter++;
}
int getValue(int s, int g, int a)
{
int value = 0xFFFF;
int valueMSB = getHeapByte(heapOffset(s + 1,g,a,0));
if (valueMSB >=0 && valueMSB <= 127) {
value = valueMSB << 7;
int valueLSB = getHeapByte(heapOffset(s + 1,g,a,1));
if (valueLSB >=0 && valueLSB <= 127) {
value = value | valueLSB;
}
}
return value;
}
void handleMIDI(int byte0, int byte1, int byte2)
{
if ((byte0 & 240) == 176) { // MIDI Control Change
if ((repaintCounter - performStamp) < 12) return; // prevent feedback
int ch = byte0 & 15;
if ( (channel - 1) == ch) {
int cc = byte1;
int value = byte2;
int ofst=-1;
int ofstA=-1;
int xx;
int yy;
float x=-1;
float y=-1;
for (int p = 0; p < 5; p++) {
if (isActive(p+1)) {
if (getXCC(p) == cc) {
ofst =heapOffset(0, p, 0, 0);
ofstA = heapOffset(0, p, 1, 0);
xx = value;
yy = getHeapByte(ofstA);
x = map(float(xx), 0.0, 127.0, 0.0, 2.0);
y = map(float(yy), 0.0, 127.0, 2.0, 0.0);
if (clearOnCenter && (xx == 63 || xx == 64 || xx == 0xFF) && (yy == 63 || yy == 64 || yy == 0xFF)) {
setHeapByte(ofstA, 0xFF);
value=0xFF;
}
} else if (getYCC(p) == cc) {
ofst = heapOffset(0, p, 1, 0);
ofstA = heapOffset(0, p, 0, 0);
xx = getHeapByte(ofstA);
yy = value;
x = map(float(xx), 0.0, 127.0, 0.0, 2.0);
y = map(float(yy), 0.0, 127.0, 2.0, 0.0);
if (clearOnCenter && (xx == 63 || xx == 64 || xx == 0xFF) && (yy == 63 || yy == 64 || yy == 0xFF)) {
setHeapByte(ofstA, 0xFF);
value=0xFF;
}
} else if (getZCC(p) == cc) {
ofst = heapOffset(0, p, 2, 0);
} else if (getXCC(p) == (cc + 32) ) {
ofst = heapOffset(0, p, 0, 1);
} else if (getYCC(p) == (cc + 32)) {
ofst = heapOffset(0, p, 1, 1);
} else if (getZCC(p) == (cc + 32)) {
ofst = heapOffset(0, p, 2, 1);
}
}
}
if (ofst >= 0) {
if (getHeapByte(ofst) != value) {
setHeapByte(ofst, value);
}
}
}
} else if (byte0 == 248) { // MIDI clock
clockCounter++;
clockStamp = repaintCounter;
pulseCounter = (clockCounter % 24);
if (!pulseCounter && playing) {
beat4 = true;
beatCounter = (clockCounter / 24);
if (recordCount || playback) {
sampleIndex = beatCounter % recordCount;
int s = beatCounter % recordCount;
for (int g=0; g < maxGems; g++) {
if ((touchBits & (1 << g))== 0) {
for (int a=0; a < maxAxyz; a++) {
for (int b=0; b < maxSignif; b++) {
int value = getHeapByte(heapOffset(s + 1,g,a,b));
if (value > 0 && value <= 127) {
if (getHeapByte(heapOffset(0,g,a,b)) != value) {
if (isActive(g+1)) {
int cc = ((a == 0) ? getXCC(g) : ((a == 1) ? getYCC(g) : getZCC(g))) + (b * 32) ;
if (!b || (highres && cc >= 32 && cc < 64 ) ) sendCC((channel - 1), cc, value);
}
setHeapByte(heapOffset(0,g,a,b),value);
}
} else {
setHeapByte(heapOffset(s + 1,g,a,b),getHeapByte(heapOffset(0,g,a,b)));
}
}
}
}
}
}
}
if (playing && recordCount && clockCounter >= 0) {
int s = beatCounter % recordCount;
// s = (s > 0) ? (s - 1) : (recordCount - 1);
int n = s < (recordCount - 1) ? (s + 1) : 0;
for (int g=0; g < maxGems; g++) {
//log((touchBits & (1 << g)));
if ((touchBits & (1 << g)) == 0) {
for (int a=0; a < maxAxyz; a++) {
int thisBeatValue = getValue(s,g,a);
int nextBeatValue = getValue(n,g,a);
if (thisBeatValue <= 16383 && nextBeatValue <= 16383) {
int diff = (nextBeatValue - thisBeatValue);
float step = float(diff) / 24; // ppqn
int value = int(float(thisBeatValue) + (step * pulseCounter));
int valueMSB = (value >> 7) & 0x7F;
if (getHeapByte(heapOffset(0,g,a,0)) != valueMSB) {
int cc = ((a == 0) ? getXCC(g) : ((a == 1) ? getYCC(g) : getZCC(g)));
setHeapByte(heapOffset(0,g,a,0), valueMSB);
sendCC((channel - 1), cc, valueMSB);
int valueLSB = (value >> 0) & 0x7F;
if (getHeapByte(heapOffset(0,g,a,1)) != valueLSB) {
setHeapByte(heapOffset(0,g,a,1), valueLSB);
if (highres && cc < 32) sendCC((channel - 1), cc + 32, valueLSB);
}
}
}
}
}
}
}
if (!((clockCounter+12)%12)) beat8 = true;
if (!((clockCounter+12)%6)) beat16 = true;
} else if (byte0 == 242) { // MIDI Song Position
clockCounter = byte1 | (byte2 << 7);
beatCounter = (clockCounter / 24);
sampleIndex = beatCounter % recordCount;
} else if (byte0 == 250) { // MIDI start
playing = true;
} else if (byte0 == 251) { // MIDI continue
playing = true;
} else if (byte0 == 252) { // MIDI stop
playing = false;
}
}
/*
*/