Browse Source

BLOCKS: Updated the BlocksSynth example

tags/2021-05-28
ed 8 years ago
parent
commit
543711d92f
4 changed files with 94 additions and 93 deletions
  1. +1
    -1
      examples/BLOCKS/BlocksSynth/Source/Audio.h
  2. +76
    -59
      examples/BLOCKS/BlocksSynth/Source/MainComponent.h
  3. +4
    -4
      examples/BLOCKS/BlocksSynth/Source/Oscillators.h
  4. +13
    -29
      examples/BLOCKS/BlocksSynth/Source/WaveshapeProgram.h

+ 1
- 1
examples/BLOCKS/BlocksSynth/Source/Audio.h View File

@@ -92,7 +92,7 @@ public:
/** Called to turn all synthesiser notes off */
void allNotesOff()
{
for (int i = 1; i < 5; ++i)
for (auto i = 1; i < 5; ++i)
synthesiser.allNotesOff (i, false);
}


+ 76
- 59
examples/BLOCKS/BlocksSynth/Source/MainComponent.h View File

@@ -50,13 +50,13 @@ struct SynthGrid
{
gridFillArray.clear();
for (int i = 0; i < numRows; ++i)
for (auto i = 0; i < numRows; ++i)
{
for (int j = 0; j < numColumns; ++j)
for (auto j = 0; j < numColumns; ++j)
{
DrumPadGridProgram::GridFill fill;
int padNum = (i * 5) + j;
auto padNum = (i * 5) + j;
fill.colour = notes.contains (padNum) ? baseGridColour
: tonics.contains (padNum) ? Colours::white
@@ -69,8 +69,8 @@ struct SynthGrid
int getNoteNumberForPad (int x, int y) const
{
int xIndex = x / 3;
int yIndex = y / 3;
auto xIndex = x / 3;
auto yIndex = y / 3;
return 60 + ((4 - yIndex) * 5) + xIndex;
}
@@ -185,55 +185,61 @@ private:
{
if (currentMode == waveformSelectionMode && touch.isTouchStart && allowTouch)
{
// Change the displayed waveshape to the next one
++waveshapeMode;
if (auto* waveshapeProgram = getWaveshapeProgram())
{
// Change the displayed waveshape to the next one
++waveshapeMode;
if (waveshapeMode > 3)
waveshapeMode = 0;
if (waveshapeMode > 3)
waveshapeMode = 0;
waveshapeProgram->setWaveshapeType (static_cast<uint8> (waveshapeMode));
waveshapeProgram->setWaveshapeType (static_cast<uint8> (waveshapeMode));
allowTouch = false;
startTimer (250);
allowTouch = false;
startTimer (250);
}
}
else if (currentMode == playMode)
{
// Translate X and Y touch events to LED indexes
int xLed = roundToInt (touch.startX * scaleX);
int yLed = roundToInt (touch.startY * scaleY);
if (auto* gridProgram = getGridProgram())
{
// Translate X and Y touch events to LED indexes
auto xLed = roundToInt (touch.startX * scaleX);
auto yLed = roundToInt (touch.startY * scaleY);
// Limit the number of touches per second
constexpr int maxNumTouchMessagesPerSecond = 100;
auto now = Time::getCurrentTime();
clearOldTouchTimes (now);
// Limit the number of touches per second
constexpr auto maxNumTouchMessagesPerSecond = 100;
auto now = Time::getCurrentTime();
clearOldTouchTimes (now);
int midiChannel = waveshapeMode + 1;
auto midiChannel = waveshapeMode + 1;
// Send the touch event to the DrumPadGridProgram and Audio class
if (touch.isTouchStart)
{
gridProgram->startTouch (touch.startX, touch.startY);
audio.noteOn (midiChannel, layout.getNoteNumberForPad (xLed, yLed), touch.z);
}
else if (touch.isTouchEnd)
{
gridProgram->endTouch (touch.startX, touch.startY);
audio.noteOff (midiChannel, layout.getNoteNumberForPad (xLed, yLed), 1.0);
}
else
{
if (touchMessageTimesInLastSecond.size() > maxNumTouchMessagesPerSecond / 3)
return;
// Send the touch event to the DrumPadGridProgram and Audio class
if (touch.isTouchStart)
{
gridProgram->startTouch (touch.startX, touch.startY);
audio.noteOn (midiChannel, layout.getNoteNumberForPad (xLed, yLed), touch.z);
}
else if (touch.isTouchEnd)
{
gridProgram->endTouch (touch.startX, touch.startY);
audio.noteOff (midiChannel, layout.getNoteNumberForPad (xLed, yLed), 1.0);
}
else
{
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) / activeBlock->getWidth());
audio.pressureChange (midiChannel, touch.z);
}
// Send pitch change and pressure values to the Audio class
audio.pitchChange (midiChannel, (touch.x - touch.startX) / activeBlock->getWidth());
audio.pressureChange (midiChannel, touch.z);
}
touchMessageTimesInLastSecond.add (now);
touchMessageTimesInLastSecond.add (now);
}
}
}
@@ -267,7 +273,7 @@ private:
/** Clears the old touch times */
void clearOldTouchTimes (const Time now)
{
for (int i = touchMessageTimesInLastSecond.size(); --i >= 0;)
for (auto i = touchMessageTimesInLastSecond.size(); --i >= 0;)
if (touchMessageTimesInLastSecond.getReference(i) < now - juce::RelativeTime::seconds (0.33))
touchMessageTimesInLastSecond.remove (i);
}
@@ -289,23 +295,20 @@ private:
{
if (currentMode == waveformSelectionMode)
{
// Create a new WaveshapeProgram for the LEDGrid
waveshapeProgram = new WaveshapeProgram (block);
// Set the LEDGrid program
block.setProgram (waveshapeProgram);
block.setProgram (new WaveshapeProgram (block));
// Initialise the program
waveshapeProgram->setWaveshapeType (static_cast<uint8> (waveshapeMode));
waveshapeProgram->generateWaveshapes();
if (auto* waveshapeProgram = getWaveshapeProgram())
{
waveshapeProgram->setWaveshapeType (static_cast<uint8> (waveshapeMode));
waveshapeProgram->generateWaveshapes();
}
}
else if (currentMode == playMode)
{
// Create a new DrumPadGridProgram for the LEDGrid
gridProgram = new DrumPadGridProgram (block);
// Set the LEDGrid program
auto error = block.setProgram (gridProgram);
auto error = block.setProgram (new DrumPadGridProgram (block));
if (error.failed())
{
@@ -314,15 +317,32 @@ private:
}
// Setup the grid layout
gridProgram->setGridFills (layout.numColumns,
layout.numRows,
layout.gridFillArray);
if (auto* gridProgram = getGridProgram())
gridProgram->setGridFills (layout.numColumns, layout.numRows, layout.gridFillArray);
}
}
/** Stops touch events from triggering multiple waveshape mode changes */
void timerCallback() override { allowTouch = true; }
//==============================================================================
DrumPadGridProgram* getGridProgram()
{
if (activeBlock != nullptr)
return dynamic_cast<DrumPadGridProgram*> (activeBlock->getProgram());
return nullptr;
}
WaveshapeProgram* getWaveshapeProgram()
{
if (activeBlock != nullptr)
return dynamic_cast<WaveshapeProgram*> (activeBlock->getProgram());
return nullptr;
}
//==============================================================================
enum BlocksSynthMode
{
waveformSelectionMode = 0,
@@ -334,9 +354,6 @@ private:
//==============================================================================
Audio audio;
DrumPadGridProgram* gridProgram = nullptr;
WaveshapeProgram* waveshapeProgram = nullptr;
SynthGrid layout { 5, 5 };
PhysicalTopologySource topologySource;
Block::Ptr activeBlock;


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

@@ -61,7 +61,7 @@ public:
void pitchWheelMoved (int newValue) override
{
// Change the phase increment based on pitch bend amount
double frequencyOffset = ((newValue > 0 ? maxFreq : minFreq) * (newValue / 127.0));
auto frequencyOffset = ((newValue > 0 ? maxFreq : minFreq) * (newValue / 127.0));
phaseIncrement.setValue (((2.0 * double_Pi) * (frequency + frequencyOffset)) / sampleRate);
}
@@ -79,9 +79,9 @@ public:
{
while (--numSamples >= 0)
{
double output = getSample() * amplitude.getNextValue();
auto output = getSample() * amplitude.getNextValue();
for (int i = outputBuffer.getNumChannels(); --i >= 0;)
for (auto i = outputBuffer.getNumChannels(); --i >= 0;)
outputBuffer.addSample (i, startSample, static_cast<float> (output));
++startSample;
@@ -91,7 +91,7 @@ public:
/** Returns the next sample */
double getSample()
{
double output = renderWaveShape (phasePos);
auto output = renderWaveShape (phasePos);
phasePos += phaseIncrement.getNextValue();


+ 13
- 29
examples/BLOCKS/BlocksSynth/Source/WaveshapeProgram.h View File

@@ -50,13 +50,13 @@ public:
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);
auto currentPhase = 0.0;
auto phaseInc = (1.0 / 30.0) * (2.0 * double_Pi);
for (int x = 0; x < 30; ++x)
for (auto x = 0; x < 30; ++x)
{
// Scale and offset the sin output to the Lightpad display
double sineOutput = sin (currentPhase);
auto sineOutput = sin (currentPhase);
sineWaveY[x] = static_cast<uint8> (roundToInt ((sineOutput * 6.5) + 7.0));
// Square wave output, set flags for when vertical line should be drawn
@@ -115,38 +115,22 @@ public:
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, 0xffff0000);
blendPixel (0xffff0000, x0, y0);
int minLedIndex = 0;
int maxLedIndex = 14;
setLED (min (x0 + 1, maxLedIndex), y0, 0xff660000);
setLED (max (x0 - 1, minLedIndex), y0, 0xff660000);
setLED (x0, min (y0 + 1, maxLedIndex), 0xff660000);
setLED (x0, max (y0 - 1, minLedIndex), 0xff660000);
blendPixel (0xff660000, min (x0 + 1, maxLedIndex), y0);
blendPixel (0xff660000, max (x0 - 1, minLedIndex), y0);
blendPixel (0xff660000, x0, min (y0 + 1, maxLedIndex));
blendPixel (0xff660000, x0, max (y0 - 1, minLedIndex));
setLED (min (x0 + 1, maxLedIndex), min (y0 + 1, maxLedIndex), 0xff1a0000);
setLED (min (x0 + 1, maxLedIndex), max (y0 - 1, minLedIndex), 0xff1a0000);
setLED (max (x0 - 1, minLedIndex), min (y0 + 1, maxLedIndex), 0xff1a0000);
setLED (max (x0 - 1, minLedIndex), max (y0 - 1, minLedIndex), 0xff1a0000);
blendPixel (0xff1a0000, min (x0 + 1, maxLedIndex), min (y0 + 1, maxLedIndex));
blendPixel (0xff1a0000, min (x0 + 1, maxLedIndex), max (y0 - 1, minLedIndex));
blendPixel (0xff1a0000, max (x0 - 1, minLedIndex), min (y0 + 1, maxLedIndex));
blendPixel (0xff1a0000, max (x0 - 1, minLedIndex), max (y0 - 1, minLedIndex));
}
void repaint()


Loading…
Cancel
Save