Browse Source

BLOCKS example apps: some cleanup, enabled DUMP_TOPOLOGY flag

tags/2021-05-28
jules 8 years ago
parent
commit
de84462f2d
9 changed files with 173 additions and 170 deletions
  1. +1
    -1
      examples/BLOCKS/BlocksDrawing/JuceLibraryCode/AppConfig.h
  2. +39
    -35
      examples/BLOCKS/BlocksDrawing/Source/MainComponent.h
  3. +1
    -1
      examples/BLOCKS/BlocksMonitor/JuceLibraryCode/AppConfig.h
  4. +73
    -69
      examples/BLOCKS/BlocksMonitor/Source/BlockComponents.h
  5. +8
    -8
      examples/BLOCKS/BlocksMonitor/Source/MainComponent.h
  6. +1
    -1
      examples/BLOCKS/BlocksSynth/JuceLibraryCode/AppConfig.h
  7. +1
    -4
      examples/BLOCKS/BlocksSynth/Source/Main.cpp
  8. +41
    -37
      examples/BLOCKS/BlocksSynth/Source/MainComponent.h
  9. +8
    -14
      examples/BLOCKS/BlocksSynth/Source/Oscillators.h

+ 1
- 1
examples/BLOCKS/BlocksDrawing/JuceLibraryCode/AppConfig.h View File

@@ -17,7 +17,7 @@
//==============================================================================
// [BEGIN_USER_CODE_SECTION]
// (You can add your own code in this section, and the Projucer will not overwrite it)
#define DUMP_TOPOLOGY 1
// [END_USER_CODE_SECTION]


+ 39
- 35
examples/BLOCKS/BlocksDrawing/Source/MainComponent.h View File

@@ -4,6 +4,7 @@
#include "../JuceLibraryCode/JuceHeader.h"
//==============================================================================
/**
A struct that handles the setup and layout of the DrumPadGridProgram
*/
@@ -70,28 +71,31 @@ struct ColourGrid
//==============================================================================
int numColumns, numRows;
float width, height;
Array<DrumPadGridProgram::GridFill> gridFillArray;
Array<Colour> colourArray = { Colours::white, Colours::red, Colours::green, Colours::blue, Colours::hotpink,
Colours::orange, Colours::magenta, Colours::cyan, Colours::black };
Array<Colour> colourArray = { Colours::white, Colours::red, Colours::green,
Colours::blue, Colours::hotpink, Colours::orange,
Colours::magenta, Colours::cyan, Colours::black };
Colour currentColour = Colours::hotpink;
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ColourGrid)
};
//==============================================================================
/**
The main component
*/
class MainComponent : public Component,
public TopologySource::Listener,
private TouchSurface::Listener,
private ControlButton::Listener,
private Timer
public TopologySource::Listener,
private TouchSurface::Listener,
private ControlButton::Listener,
private Timer
{
public:
MainComponent() : layout (3, 3)
MainComponent()
{
setSize (600, 400);
@@ -110,7 +114,8 @@ public:
void paint (Graphics& g) override
{
g.fillAll (Colours::lightgrey);
g.drawText ("Connect a Lightpad Block to draw.", getLocalBounds(), Justification::centred, false);
g.drawText ("Connect a Lightpad Block to draw.",
getLocalBounds(), Justification::centred, false);
}
void resized() override {}
@@ -176,7 +181,7 @@ private:
}
/** Overridden from ControlButton::Listener. Called when a button on the Lightpad is pressed */
void buttonPressed (ControlButton&, Block::Timestamp) override {};
void buttonPressed (ControlButton&, Block::Timestamp) override {}
/** Overridden from ControlButton::Listener. Called when a button on the Lightpad is released */
void buttonReleased (ControlButton&, Block::Timestamp) override
@@ -257,7 +262,9 @@ private:
grid->setProgram (colourPaletteProgram);
// Setup the grid layout
colourPaletteProgram->setGridFills (layout.numColumns, layout.numRows, layout.gridFillArray);
colourPaletteProgram->setGridFills (layout.numColumns,
layout.numRows,
layout.gridFillArray);
}
}
@@ -265,20 +272,12 @@ private:
void drawLEDs (uint32 x0, uint32 y0, float z, Colour drawColour)
{
// Check if the activeLeds array already contains an ActiveLED object for this LED
int index = -1;
for (int i = 0; i < activeLeds.size(); ++i)
{
if (activeLeds.getReference(i).occupies (x0, y0))
{
index = i;
break;
}
}
auto index = getLEDAt (x0, y0);
// If the colour is black then just set the LED to black and return
if (drawColour == Colours::black)
{
if (index != -1)
if (index >= 0)
{
canvasProgram->setLED (x0, y0, Colours::black);
activeLeds.remove (index);
@@ -289,7 +288,7 @@ private:
// If there is no ActiveLED obejct for this LED then create one,
// add it to the array, set the LED on the Block and return
if (index == -1)
if (index < 0)
{
ActiveLED led;
led.x = x0;
@@ -333,37 +332,42 @@ private:
*/
struct ActiveLED
{
uint32 x;
uint32 y;
uint32 x, y;
Colour colour;
float brightness;
/** Returns true if this LED occupies the given co-ordiantes */
/** Returns true if this LED occupies the given co-ordinates */
bool occupies (uint32 xPos, uint32 yPos) const
{
if (xPos == x && yPos == y)
return true;
return false;
return xPos == x && yPos == y;
}
};
Array<ActiveLED> activeLeds;
/**
enum for the two modes
*/
int getLEDAt (uint32 x, uint32 y) const
{
for (int i = 0; i < activeLeds.size(); ++i)
if (activeLeds.getReference(i).occupies (x, y))
return i;
return -1;
}
//==============================================================================
enum DisplayMode
{
colourPalette = 0,
canvas
};
DisplayMode currentMode = colourPalette;
//==============================================================================
BitmapLEDProgram* canvasProgram;
DrumPadGridProgram* colourPaletteProgram;
BitmapLEDProgram* canvasProgram = nullptr;
DrumPadGridProgram* colourPaletteProgram = nullptr;
ColourGrid layout;
ColourGrid layout { 3, 3 };
PhysicalTopologySource topologySource;
Block::Ptr activeBlock;


+ 1
- 1
examples/BLOCKS/BlocksMonitor/JuceLibraryCode/AppConfig.h View File

@@ -17,7 +17,7 @@
//==============================================================================
// [BEGIN_USER_CODE_SECTION]
// (You can add your own code in this section, and the Projucer will not overwrite it)
#define DUMP_TOPOLOGY 1
// [END_USER_CODE_SECTION]


+ 73
- 69
examples/BLOCKS/BlocksMonitor/Source/BlockComponents.h View File

@@ -15,7 +15,6 @@ class BlockComponent : public Component,
private Timer
{
public:
/** Constructor */
BlockComponent (Block::Ptr blockToUse)
: block (blockToUse)
{
@@ -38,7 +37,6 @@ public:
startTimerHz (25);
}
/** Destructor */
~BlockComponent()
{
// Remove any listeners
@@ -53,19 +51,16 @@ public:
void updateStatsAndTooltip()
{
// Get the battery level of this Block and inform any subclasses
const float batteryLevel = block->getBatteryLevel();
auto batteryLevel = block->getBatteryLevel();
handleBatteryLevelUpdate (batteryLevel);
// Format the tooltip string
const String ttString = "Name = " + block->getDeviceDescription() + "\n"
+ "UID = " + String (block->uid) + "\n"
+ "Serial number = " + block->serialNumber + "\n"
+ "Battery level = " + String ((int) (batteryLevel * 100)) + "%"
+ (block->isBatteryCharging() ? "++" : "--");
// Update the tooltip string if it has changed
if (ttString != getTooltip())
setTooltip (ttString);
// Update the tooltip
setTooltip ("Name = " + block->getDeviceDescription() + "\n"
+ "UID = " + String (block->uid) + "\n"
+ "Serial number = " + block->serialNumber + "\n"
+ "Battery level = " + String ((int) (batteryLevel * 100)) + "%"
+ (block->isBatteryCharging() ? "++"
: "--"));
}
/** Subclasses should override this to paint the Block object on the screen */
@@ -88,31 +83,35 @@ public:
//==============================================================================
/** Returns an integer index corresponding to a physical position on the hardware
for each type of Control Block. */
for each type of Control Block. */
static int controlButtonFunctionToIndex (ControlButton::ButtonFunction f)
{
static std::initializer_list<ControlButton::ButtonFunction> map[] =
{{ControlButton::mode, ControlButton::button0},
{ControlButton::volume, ControlButton::button1},
{ControlButton::scale, ControlButton::button2, ControlButton::click},
{ControlButton::chord, ControlButton::button3, ControlButton::snap},
{ControlButton::arp,ControlButton:: button4, ControlButton::back},
{ControlButton::sustain, ControlButton::button5, ControlButton::playOrPause},
{ControlButton::octave, ControlButton::button6, ControlButton::record},
{ControlButton::love, ControlButton::button7, ControlButton::learn},
{ControlButton::up},
{ControlButton::down}};
for (size_t i = 0; i < (sizeof (map) / sizeof (map[0])); ++i)
if (std::find (map[i].begin(), map[i].end(), f) != map[i].end())
return static_cast<int> (i);
using CB = ControlButton;
static Array<ControlButton::ButtonFunction> map[] =
{
{ CB::mode, CB::button0 },
{ CB::volume, CB::button1 },
{ CB::scale, CB::button2, CB::click },
{ CB::chord, CB::button3, CB::snap },
{ CB::arp, CB::button4, CB::back },
{ CB::sustain, CB::button5, CB::playOrPause },
{ CB::octave, CB::button6, CB::record },
{ CB::love, CB::button7, CB::learn },
{ CB::up },
{ CB::down }
};
for (int i = 0; i < numElementsInArray (map); ++i)
if (map[i].contains (f))
return i;
return -1;
}
private:
/** Used to call repaint() periodically */
void timerCallback() override { repaint(); }
void timerCallback() override { repaint(); }
/** Overridden from TouchSurface::Listener */
void touchChanged (TouchSurface&, const TouchSurface::Touch& t) override { handleTouchChange (t); }
@@ -123,14 +122,14 @@ private:
/** Overridden from ControlButton::Listener */
void buttonReleased (ControlButton& b, Block::Timestamp t) override { handleButtonReleased (b.getType(), t); }
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BlockComponent)
};
//==============================================================================
/**
Class that renders a Lightpad on the screen
*/
class LightpadComponent : public BlockComponent
class LightpadComponent : public BlockComponent
{
public:
LightpadComponent (Block::Ptr blockToUse)
@@ -154,23 +153,25 @@ public:
g.fillAll (Colours::black);
// size ration between physical and on-screen blocks
const Point<float> ratio (r.getWidth() / block->getWidth(),
r.getHeight() / block->getHeight());
const float maxCircleSize = block->getWidth() / 3.0f;
Point<float> ratio (r.getWidth() / block->getWidth(),
r.getHeight() / block->getHeight());
float maxCircleSize = block->getWidth() / 3.0f;
// iterate over the list of current touches and draw them on the onscreen Block
for (auto touch : touches)
{
const float circleSize = touch.touch.z * maxCircleSize;
const Point<float> touchPosition = Point<float> (touch.touch.x, touch.touch.y);
float circleSize = touch.touch.z * maxCircleSize;
Point<float> touchPosition (touch.touch.x,
touch.touch.y);
const Colour c = colourArray[touch.touch.index];
const Rectangle<float> blob =
(Rectangle<float> (circleSize, circleSize).withCentre (touchPosition)) * ratio;
auto blob = Rectangle<float> (circleSize, circleSize)
.withCentre (touchPosition) * ratio;
const ColourGradient cg = ColourGradient (colourArray[touch.touch.index], blob.getCentreX(), blob.getCentreY(),
Colours::transparentBlack, blob.getRight(), blob.getBottom(),
true);
ColourGradient cg (colourArray[touch.touch.index], blob.getCentreX(), blob.getCentreY(),
Colours::transparentBlack, blob.getRight(), blob.getBottom(),
true);
g.setGradientFill (cg);
g.fillEllipse (blob);
@@ -181,21 +182,26 @@ public:
private:
/** An Array of colours to use for touches */
Array<Colour> colourArray = { Colours::red, Colours::blue, Colours::green,
Colours::yellow, Colours::white, Colours::hotpink,
Array<Colour> colourArray = { Colours::red,
Colours::blue,
Colours::green,
Colours::yellow,
Colours::white,
Colours::hotpink,
Colours::mediumpurple };
/** A list of current Touch events */
TouchList<TouchSurface::Touch> touches;
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LightpadComponent)
};
//==============================================================================
/**
Class that renders a Control Block on the screen
*/
class ControlBlockComponent : public BlockComponent
class ControlBlockComponent : public BlockComponent
{
public:
ControlBlockComponent (Block::Ptr blockToUse)
@@ -205,13 +211,12 @@ public:
addAndMakeVisible (roundedRectangleButton);
// Display the battery level on the LEDRow
int numLedsToTurnOn = static_cast<int> (static_cast<float> (numLeds) * block->getBatteryLevel());
auto numLedsToTurnOn = static_cast<int> (numLeds * block->getBatteryLevel());
// add LEDs
LEDComponent* ledComponent;
for (int i = 0; i < numLeds; ++i)
{
ledComponent = new LEDComponent();
auto ledComponent = new LEDComponent();
ledComponent->setOnState (i < numLedsToTurnOn);
addAndMakeVisible (leds.add (ledComponent));
@@ -238,9 +243,9 @@ public:
auto buttonRow1 = row.removeFromTop (rowHeight * 2).withSizeKeepingCentre (r.getWidth(), buttonWidth);
auto buttonRow2 = row.removeFromTop (rowHeight * 2).withSizeKeepingCentre (r.getWidth(), buttonWidth);
for (int i = 0; i < numLeds; ++i)
for (auto* led : leds)
{
leds.getUnchecked (i)->setBounds (ledRow.removeFromLeft (ledWidth).reduced (2));
led->setBounds (ledRow.removeFromLeft (ledWidth).reduced (2));
ledRow.removeFromLeft (5);
}
@@ -261,7 +266,7 @@ public:
void paint (Graphics& g) override
{
const auto r = getLocalBounds().toFloat();
auto r = getLocalBounds().toFloat();
// Fill a black rectangle for the Control Block
g.setColour (Colours::black);
@@ -281,7 +286,7 @@ public:
void handleBatteryLevelUpdate (float batteryLevel) override
{
// Update the number of LEDs that are on to represent the battery level
int numLedsOn = static_cast<int> (static_cast<float> (numLeds) * batteryLevel);
int numLedsOn = static_cast<int> (numLeds * batteryLevel);
if (numLedsOn != previousNumLedsOn)
for (int i = 0; i < numLeds; ++i)
@@ -292,22 +297,22 @@ public:
}
private:
//==============================================================================
/**
Base class that renders a Control Block button
*/
struct ControlBlockSubComponent : public Component,
public TooltipClient
struct ControlBlockSubComponent : public Component,
public TooltipClient
{
ControlBlockSubComponent (Colour componentColourToUse)
: componentColour (componentColourToUse),
onState (false)
: componentColour (componentColourToUse)
{}
/** Subclasses should override this to paint the button on the screen */
virtual void paint (Graphics&) override = 0;
/** Sets the colour of the button */
void setColour (Colour c) { componentColour = c; }
void setColour (Colour c) { componentColour = c; }
/** Sets the on state of the button */
void setOnState (bool isOn)
@@ -320,15 +325,15 @@ private:
String getTooltip() override
{
for (Component* comp = this; comp != nullptr; comp = comp->getParentComponent())
if (SettableTooltipClient* sttc = dynamic_cast<SettableTooltipClient*> (comp))
if (auto* sttc = dynamic_cast<SettableTooltipClient*> (comp))
return sttc->getTooltip();
return String();
return {};
}
//==============================================================================
Colour componentColour;
bool onState;
bool onState = false;
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ControlBlockSubComponent)
@@ -372,8 +377,7 @@ private:
void paint (Graphics& g) override
{
const auto r = getLocalBounds().toFloat();
auto r = getLocalBounds().toFloat();
g.setColour (componentColour.withAlpha (0.2f));
g.fillRoundedRectangle (r.toFloat(), 20.0f);
@@ -382,11 +386,11 @@ private:
// is a button pressed?
if (doubleButtonOnState[0] || doubleButtonOnState[1])
{
const float semiButtonWidth = r.getWidth() / 2.0f;
const auto semiButtonBounds = r.withWidth (semiButtonWidth)
.withX (doubleButtonOnState[1] ? semiButtonWidth : 0)
.reduced (5.0f, 2.0f);
auto semiButtonWidth = r.getWidth() / 2.0f;
auto semiButtonBounds = r.withWidth (semiButtonWidth)
.withX (doubleButtonOnState[1] ? semiButtonWidth : 0)
.reduced (5.0f, 2.0f);
g.fillEllipse (semiButtonBounds);
}
@@ -399,7 +403,7 @@ private:
}
private:
bool doubleButtonOnState[2] = {false, false};
bool doubleButtonOnState[2] = { false, false };
};
/** Displays a button press or release interaction for a button at a given index */


+ 8
- 8
examples/BLOCKS/BlocksMonitor/Source/MainComponent.h View File

@@ -46,10 +46,10 @@ public:
}
// Work out the maximum diplay area for each Block
const Rectangle<int> bounds = getLocalBounds().reduced (20);
auto bounds = getLocalBounds().reduced (20);
auto squareRoot = sqrt (numBlockComponents);
int gridSize = (int)squareRoot;
auto squareRoot = std::sqrt (numBlockComponents);
int gridSize = (int) squareRoot;
if (squareRoot - gridSize > 0)
gridSize++;
@@ -64,7 +64,7 @@ public:
for (auto block : blockComponents)
{
Rectangle<int> blockBounds;
const Block::Type type = block->block->getType();
auto type = block->block->getType();
// Can fit 2 ControlBlockComponents in the space of one LightpadBlockComponent
if (type == Block::liveBlock || type == Block::loopBlock)
@@ -105,11 +105,11 @@ public:
blockComponents.clear();
// Get the array of currently connected Block objects from the PhysicalTopologySource
Block::Array blocksArray = topologySource.getCurrentTopology().blocks;
auto blocksArray = topologySource.getCurrentTopology().blocks;
// Create a BlockComponent object for each Block object
for (auto& block : blocksArray)
if (BlockComponent* blockComponent = createBlockComponent (block))
if (auto* blockComponent = createBlockComponent (block))
addAndMakeVisible (blockComponents.add (blockComponent));
// Update the display
@@ -120,16 +120,16 @@ private:
/** Creates a BlockComponent object for a new Block and adds it to the content component */
BlockComponent* createBlockComponent (Block::Ptr newBlock)
{
const Block::Type type = newBlock->getType();
auto type = newBlock->getType();
if (type == Block::lightPadBlock)
return new LightpadComponent (newBlock);
if (type == Block::loopBlock || type == Block::liveBlock)
return new ControlBlockComponent (newBlock);
// should only be connecting a Lightpad or Control Block!
jassertfalse;
return nullptr;
}


+ 1
- 1
examples/BLOCKS/BlocksSynth/JuceLibraryCode/AppConfig.h View File

@@ -17,7 +17,7 @@
//==============================================================================
// [BEGIN_USER_CODE_SECTION]
// (You can add your own code in this section, and the Projucer will not overwrite it)
#define DUMP_TOPOLOGY 1
// [END_USER_CODE_SECTION]


+ 1
- 4
examples/BLOCKS/BlocksSynth/Source/Main.cpp View File

@@ -27,9 +27,8 @@ public:
void shutdown() override { mainWindow = nullptr; }
//==============================================================================
class MainWindow : public DocumentWindow
struct MainWindow : public DocumentWindow
{
public:
MainWindow (String name) : DocumentWindow (name,
Colours::lightgrey,
DocumentWindow::allButtons)
@@ -47,10 +46,8 @@ public:
JUCEApplication::getInstance()->systemRequestedQuit();
}
private:
TooltipWindow tooltipWindow;
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainWindow)
};


+ 41
- 37
examples/BLOCKS/BlocksSynth/Source/MainComponent.h View File

@@ -5,6 +5,7 @@
#include "../JuceLibraryCode/JuceHeader.h"
#include "Audio.h"
//==============================================================================
/**
A struct that handles the setup and layout of the DrumPadGridProgram
*/
@@ -41,7 +42,7 @@ struct SynthGrid
}
}
int getNoteNumberForPad (int x, int y)
int getNoteNumberForPad (int x, int y) const
{
int xIndex = x / 3;
int yIndex = y / 3;
@@ -64,6 +65,7 @@ struct SynthGrid
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SynthGrid)
};
//==============================================================================
/**
The main component
*/
@@ -74,7 +76,7 @@ class MainComponent : public Component,
private Timer
{
public:
MainComponent() : layout (5, 5)
MainComponent()
{
setSize (600, 400);
@@ -93,7 +95,8 @@ public:
void paint (Graphics& g) override
{
g.fillAll (Colours::lightgrey);
g.drawText ("Connect a Lightpad Block to play.", getLocalBounds(), Justification::centred, false);
g.drawText ("Connect a Lightpad Block to play.",
getLocalBounds(), Justification::centred, false);
}
void resized() override {}
@@ -106,7 +109,7 @@ public:
detachActiveBlock();
// Get the array of currently connected Block objects from the PhysicalTopologySource
Block::Array blocks = topologySource.getCurrentTopology().blocks;
auto blocks = topologySource.getCurrentTopology().blocks;
// Iterate over the array of Block objects
for (auto b : blocks)
@@ -180,10 +183,11 @@ private:
if (touchMessageTimesInLastSecond.size() > maxNumTouchMessagesPerSecond / 3)
return;
gridProgram->sendTouch (touch.x, touch.y, touch.z, layout.touchColour);
gridProgram->sendTouch (touch.x, touch.y, touch.z,
layout.touchColour);
// Send pitch change and pressure values to the Audio class
audio.pitchChange (midiChannel, (touch.x - touch.startX) / static_cast<float> (activeBlock->getWidth()));
audio.pitchChange (midiChannel, (touch.x - touch.startX) / activeBlock->getWidth());
audio.pressureChange (midiChannel, touch.z);
}
@@ -215,26 +219,18 @@ private:
// Clear all LEDs
for (uint32 x = 0; x < 15; ++x)
for (uint32 y = 0; y < 15; ++y)
bitmapProgram->setLED (x, y, Colours::black);
setLED (x, y, Colours::black);
// Determine which array to use based on waveshapeMode
int* waveshapeY = nullptr;
switch (waveshapeMode)
{
case 0:
waveshapeY = sineWaveY;
break;
case 1:
waveshapeY = squareWaveY;
break;
case 2:
waveshapeY = sawWaveY;
break;
case 3:
waveshapeY = triangleWaveY;
break;
default:
break;
case 0: waveshapeY = sineWaveY; break;
case 1: waveshapeY = squareWaveY; break;
case 2: waveshapeY = sawWaveY; break;
case 3: waveshapeY = triangleWaveY; break;
default: break;
}
// For each X co-ordinate
@@ -306,7 +302,9 @@ private:
grid->setProgram (gridProgram);
// Setup the grid layout
gridProgram->setGridFills (layout.numColumns, layout.numRows, layout.gridFillArray);
gridProgram->setGridFills (layout.numColumns,
layout.numRows,
layout.gridFillArray);
}
}
@@ -341,6 +339,7 @@ private:
// 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] != -1)
sawWaveY[x] = -1;
@@ -361,42 +360,47 @@ private:
}
}
/** Simple wrapper function to set a LED colour */
void setLED (uint32 x, uint32 y, Colour colour)
{
if (bitmapProgram != nullptr)
bitmapProgram->setLED (x, y, colour);
}
/** Draws a 'circle' on the Lightpad around an origin co-ordinate */
void drawLEDCircle (uint32 x0, uint32 y0)
{
bitmapProgram->setLED (x0, y0, waveshapeColour);
setLED (x0, y0, waveshapeColour);
const uint32 minLedIndex = 0;
const uint32 maxLedIndex = 14;
bitmapProgram->setLED (jmin (x0 + 1, maxLedIndex), y0, waveshapeColour.withBrightness (0.4f));
bitmapProgram->setLED (jmax (x0 - 1, minLedIndex), y0, waveshapeColour.withBrightness (0.4f));
bitmapProgram->setLED (x0, jmin (y0 + 1, maxLedIndex), waveshapeColour.withBrightness (0.4f));
bitmapProgram->setLED (x0, jmax (y0 - 1, minLedIndex), waveshapeColour.withBrightness (0.4f));
setLED (jmin (x0 + 1, maxLedIndex), y0, waveshapeColour.withBrightness (0.4f));
setLED (jmax (x0 - 1, minLedIndex), y0, waveshapeColour.withBrightness (0.4f));
setLED (x0, jmin (y0 + 1, maxLedIndex), waveshapeColour.withBrightness (0.4f));
setLED (x0, jmax (y0 - 1, minLedIndex), waveshapeColour.withBrightness (0.4f));
bitmapProgram->setLED (jmin (x0 + 1, maxLedIndex), jmin (y0 + 1, maxLedIndex), waveshapeColour.withBrightness (0.1f));
bitmapProgram->setLED (jmin (x0 + 1, maxLedIndex), jmax (y0 - 1, minLedIndex), waveshapeColour.withBrightness (0.1f));
bitmapProgram->setLED (jmax (x0 - 1, minLedIndex), jmin (y0 + 1, maxLedIndex), waveshapeColour.withBrightness (0.1f));
bitmapProgram->setLED (jmax (x0 - 1, minLedIndex), jmax (y0 - 1, minLedIndex), waveshapeColour.withBrightness (0.1f));
setLED (jmin (x0 + 1, maxLedIndex), jmin (y0 + 1, maxLedIndex), waveshapeColour.withBrightness (0.1f));
setLED (jmin (x0 + 1, maxLedIndex), jmax (y0 - 1, minLedIndex), waveshapeColour.withBrightness (0.1f));
setLED (jmax (x0 - 1, minLedIndex), jmin (y0 + 1, maxLedIndex), waveshapeColour.withBrightness (0.1f));
setLED (jmax (x0 - 1, minLedIndex), jmax (y0 - 1, minLedIndex), waveshapeColour.withBrightness (0.1f));
}
/**
enum for the two modes
*/
enum BlocksSynthMode
{
waveformSelectionMode = 0,
playMode
};
BlocksSynthMode currentMode = playMode;
//==============================================================================
Audio audio;
DrumPadGridProgram* gridProgram;
BitmapLEDProgram* bitmapProgram;
DrumPadGridProgram* gridProgram = nullptr;
BitmapLEDProgram* bitmapProgram = nullptr;
SynthGrid layout;
SynthGrid layout { 5, 5 };
PhysicalTopologySource topologySource;
Block::Ptr activeBlock;


+ 8
- 14
examples/BLOCKS/BlocksSynth/Source/Oscillators.h View File

@@ -7,7 +7,7 @@
/**
Base class for oscillators
*/
class Oscillator : public SynthesiserVoice
class Oscillator : public SynthesiserVoice
{
public:
Oscillator()
@@ -16,10 +16,6 @@ public:
phaseIncrement.reset (getSampleRate(), 0.1);
}
virtual ~Oscillator()
{
}
void startNote (int midiNoteNumber, float velocity, SynthesiserSound*, int) override
{
frequency = MidiMessage::getMidiNoteInHertz (midiNoteNumber);
@@ -57,7 +53,7 @@ public:
void renderNextBlock (AudioSampleBuffer& outputBuffer, int startSample, int numSamples) override
{
while(--numSamples >= 0)
while (--numSamples >= 0)
{
double output = getSample() * amplitude.getNextValue();
@@ -82,22 +78,20 @@ public:
}
/** Subclasses should override this to say whether they can play the given sound */
virtual bool canPlaySound (SynthesiserSound* sound) override = 0;
virtual bool canPlaySound (SynthesiserSound*) override = 0;
/** Subclasses should override this to render a waveshape */
virtual double renderWaveShape (const double currentPhase) = 0;
virtual double renderWaveShape (double currentPhase) = 0;
private:
LinearSmoothedValue<double> amplitude;
LinearSmoothedValue<double> phaseIncrement;
LinearSmoothedValue<double> amplitude, phaseIncrement;
double frequency;
double frequency = 0;
double phasePos = 0.0f;
double sampleRate = 44100.0;
int initialNote;
double maxFreq;
double minFreq;
int initialNote = 0;
double maxFreq = 0, minFreq = 0;
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Oscillator)


Loading…
Cancel
Save