/* */ // 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; } } /* */