diff --git a/examples/BLOCKS/BlocksSynth/Source/MainComponent.h b/examples/BLOCKS/BlocksSynth/Source/MainComponent.h index 370f1a41d0..482b47e1f3 100644 --- a/examples/BLOCKS/BlocksSynth/Source/MainComponent.h +++ b/examples/BLOCKS/BlocksSynth/Source/MainComponent.h @@ -73,7 +73,8 @@ struct SynthGrid class MainComponent : public Component, public TopologySource::Listener, private TouchSurface::Listener, - private ControlButton::Listener + private ControlButton::Listener, + private Timer { public: MainComponent() @@ -144,15 +145,18 @@ private: /** Overridden from TouchSurface::Listener. Called when a Touch is received on the Lightpad */ void touchChanged (TouchSurface&, const TouchSurface::Touch& touch) override { - if (currentMode == waveformSelectionMode && touch.isTouchStart) + if (currentMode == waveformSelectionMode && touch.isTouchStart && allowTouch) { // Change the displayed waveshape to the next one ++waveshapeMode; if (waveshapeMode > 3) waveshapeMode = 0; - + waveshapeProgram->setWaveshapeType (waveshapeMode); + + allowTouch = false; + startTimer (500); } else if (currentMode == playMode) { @@ -240,10 +244,13 @@ private: if (currentMode == waveformSelectionMode) { // Create a new BitmapLEDProgram for the LEDGrid - waveshapeProgram = new WaveshapeProgram (*grid, waveshapeMode); + waveshapeProgram = new WaveshapeProgram (*grid); // Set the LEDGrid program grid->setProgram (waveshapeProgram); + + waveshapeProgram->setWaveshapeType (waveshapeMode); + waveshapeProgram->generateWaveshapes(); } else if (currentMode == playMode) { @@ -260,6 +267,11 @@ private: } } + void timerCallback() override + { + allowTouch = true; + } + enum BlocksSynthMode { waveformSelectionMode = 0, @@ -283,10 +295,12 @@ private: Colour waveshapeColour = Colours::red; int waveshapeMode = 0; - + float scaleX = 0.0; float scaleY = 0.0; + bool allowTouch = true; + //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent) }; diff --git a/examples/BLOCKS/BlocksSynth/Source/WaveshapeProgram.h b/examples/BLOCKS/BlocksSynth/Source/WaveshapeProgram.h index 7c243b2569..457def258e 100644 --- a/examples/BLOCKS/BlocksSynth/Source/WaveshapeProgram.h +++ b/examples/BLOCKS/BlocksSynth/Source/WaveshapeProgram.h @@ -14,29 +14,27 @@ class WaveshapeProgram : public LEDGrid::Program { public: - WaveshapeProgram (LEDGrid& lg, int waveshape) : Program (lg) + WaveshapeProgram (LEDGrid& lg) : Program (lg) { - setWaveshapeType (waveshape); - generateWaveshapes(); } void generateWaveshapes() { - int sineWaveY[45]; - int squareWaveY[45]; - int sawWaveY[45]; - int triangleWaveY[45]; - + uint8 sineWaveY[45]; + uint8 squareWaveY[45]; + uint8 sawWaveY[45]; + uint8 triangleWaveY[45]; + // Set current phase position to 0 and work out the required phase increment for one cycle double currentPhase = 0.0; double phaseInc = (1.0 / 30.0) * (2.0 * double_Pi); - + for (int x = 0; x < 30; ++x) { // Scale and offset the sin output to the Lightpad display double sineOutput = sin (currentPhase); sineWaveY[x] = roundToInt ((sineOutput * 6.5) + 7.0); - + // Square wave output, set flags for when vertical line should be drawn if (currentPhase < double_Pi) { @@ -49,19 +47,19 @@ public: { if (squareWaveY[x - 1] == 1) squareWaveY[x - 1] = 20; - + squareWaveY[x] = 13; } - + // Saw wave output, set flags for when vertical line should be drawn sawWaveY[x] = 14 - ((x / 2) % 15); - + if (sawWaveY[x] == 0 && sawWaveY[x - 1] != 20) sawWaveY[x] = 20; - + // Triangle wave output triangleWaveY[x] = x < 15 ? x : 14 - (x % 15); - + // Add half cycle to end of array so it loops correctly if (x < 15) { @@ -70,30 +68,39 @@ public: sawWaveY[x + 30] = sawWaveY[x]; triangleWaveY[x + 30] = triangleWaveY[x]; } - + // Increment the current phase currentPhase += phaseInc; } - + for (int i = 0; i < 45; ++i) { - ledGrid.setDataBits ((sineWaveOffset * 8) + (32 * i), 32, sineWaveY[i]); - jassert (ledGrid.getDataByte (sineWaveOffset + (i * 4)) == sineWaveY[i]); - - ledGrid.setDataBits ((squareWaveOffset * 8) + (32 * i), 32, squareWaveY[i]); - jassert (ledGrid.getDataByte (squareWaveOffset + (i * 4)) == squareWaveY[i]); - - ledGrid.setDataBits ((sawWaveOffset * 8) + (32 * i), 32, sawWaveY[i]); - jassert (ledGrid.getDataByte (sawWaveOffset + (i * 4)) == sawWaveY[i]); - - ledGrid.setDataBits ((triangleWaveOffset * 8) + (32 * i), 32, triangleWaveY[i]); - jassert (ledGrid.getDataByte (triangleWaveOffset + (i * 4)) == triangleWaveY[i]); + ledGrid.setDataByte (sineWaveOffset + i, sineWaveY[i]); + int sineByte = ledGrid.getDataByte (sineWaveOffset + i); + jassert (sineByte == sineWaveY[i]); + + ledGrid.setDataByte (squareWaveOffset + i, squareWaveY[i]); + int squareByte = ledGrid.getDataByte (squareWaveOffset + i); + jassert (squareByte == squareWaveY[i]); + + ledGrid.setDataByte (sawWaveOffset + i, sawWaveY[i]); + int sawByte = ledGrid.getDataByte (sawWaveOffset + i); + jassert (sawByte == sawWaveY[i]); + + ledGrid.setDataByte (triangleWaveOffset + i, triangleWaveY[i]); + int triangleByte = ledGrid.getDataByte (triangleWaveOffset + i); + jassert (triangleByte == triangleWaveY[i]); } } - - void setWaveshapeType (int type) + + void setWaveshapeType (uint8 type) { - ledGrid.setDataBits (0, 4, type); + ledGrid.setDataByte (0, type); + } + + uint32 getHeapSize() override + { + return totalDataSize; } String getLittleFootProgram() override @@ -101,27 +108,27 @@ public: return R"littlefoot( int yOffset; - + int min (int a, int b) { if (a > b) return b; - + return a; } - + int max (int a, int b) { if (a > b) return a; - + return b; } - + void drawLEDCircle (int x0, int y0) { - setLED (x0, y0, 0xffffffff); - + setLED (x0, y0, 0xffff0000); + int minLedIndex = 0; int maxLedIndex = 14; @@ -135,20 +142,19 @@ public: setLED (max (x0 - 1, minLedIndex), min (y0 + 1, maxLedIndex), 0xff1a0000); setLED (max (x0 - 1, minLedIndex), max (y0 - 1, minLedIndex), 0xff1a0000); } - + void repaint() { // Clear LEDs to black fillRect (0xff000000, 0, 0, 15, 15); // Get the waveshape type - int type = getHeapInt (0); - int offset = 4 + (type * 180) + yOffset; - + int type = getHeapByte (0); + int offset = 1 + (type * 45) + yOffset; + for (int x = 0; x < 15; ++x) { - // Find the corresponding Y co-ordinate for the current waveshape - int y = getHeapInt (offset + (x * 4)); + int y = getHeapByte (offset + x); // Draw a vertical line if flag is set or draw an LED circle if (y == 20) @@ -162,28 +168,22 @@ public: } } - // Increment the offset to draw a 'moving' waveshape - yOffset += 4; - if (yOffset == (4 * 30)) - yOffset -= (4 * 30); + if (++yOffset == 30) + yOffset = 0; + } )littlefoot"; } - uint32 getHeapSize() override - { - return totalDataSize; - } - private: - static constexpr uint32 waveshapeType = 0; // 4 bytes - static constexpr uint32 sineWaveOffset = 4; // 4 byte * 45 - static constexpr uint32 squareWaveOffset = 184; // 4 byte * 45 - static constexpr uint32 sawWaveOffset = 364; // 4 byte * 45 - static constexpr uint32 triangleWaveOffset = 544; // 4 byte * 45 + static constexpr uint32 waveshapeType = 0; // 1 byte + static constexpr uint32 sineWaveOffset = 1; // 1 byte * 45 + static constexpr uint32 squareWaveOffset = 46; // 1 byte * 45 + static constexpr uint32 sawWaveOffset = 91; // 1 byte * 45 + static constexpr uint32 triangleWaveOffset = 136; // 1 byte * 45 - static constexpr uint32 totalDataSize = triangleWaveOffset + (4 * 45); + static constexpr uint32 totalDataSize = triangleWaveOffset + 45; //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WaveshapeProgram)