From 5d2ffe1ffc45a03c42214e304ab62cb42bb788e5 Mon Sep 17 00:00:00 2001 From: Tom Poole Date: Mon, 19 Feb 2018 16:23:30 +0000 Subject: [PATCH] Fixed whitespace in Doxygen files --- .../doxygen/pages/juce_connecting_blocks.dox | 65 ++++----- .../juce_controlling_control_buttons.dox | 35 +++-- .../pages/juce_controlling_led_grids.dox | 73 +++++----- .../pages/juce_controlling_led_strips.dox | 35 +++-- .../doxygen/pages/juce_discovering_blocks.dox | 111 +++++++------- .../pages/juce_downloading_the_sdk.dox | 24 +-- .../pages/juce_example_applications.dox | 59 ++++---- .../pages/juce_example_blocks_drawing.dox | 70 ++++----- .../pages/juce_example_blocks_monitor.dox | 81 +++++------ .../pages/juce_example_blocks_synth.dox | 74 +++++----- .../juce_getting_control_button_events.dox | 79 +++++----- .../pages/juce_getting_touch_events.dox | 71 +++++---- extras/BLOCKS/doxygen/pages/juce_main.dox | 130 ++++++++--------- .../pages/juce_the_littlefoot_language.dox | 47 +++--- .../pages/juce_the_standalone_blocks_sdk.dox | 137 +++++++++--------- .../Source/Application/jucer_CommandLine.cpp | 2 +- 16 files changed, 541 insertions(+), 552 deletions(-) diff --git a/extras/BLOCKS/doxygen/pages/juce_connecting_blocks.dox b/extras/BLOCKS/doxygen/pages/juce_connecting_blocks.dox index 5299ec55f3..7d720fa582 100644 --- a/extras/BLOCKS/doxygen/pages/juce_connecting_blocks.dox +++ b/extras/BLOCKS/doxygen/pages/juce_connecting_blocks.dox @@ -1,33 +1,32 @@ -/** -@page connecting_blocks Connecting BLOCKS - -Lightpads can be conected to a computer either via USB or Bluetooth, and Control Blocks can be connected via Bluetooth or by snapping to an already connected Lightpad. -Both devices communicate with your computer using System Exclusive (SysEx) MIDI messages. - -@section usb USB - -To connect a Lightpad to your computer over USB, you need to insert a USB-C cable into the top of the device and connect it to a USB port on your computer. -When powered on by pressing the power button on the bottom edge, you will be able to send and receive data from the block over the USB connection. - -@section bluetooth Bluetooth - -The power button also functions as a toggle for the Bluetooth connection - when the blue light on the button is illuminated, the device is able to connect via Bluetooth and send and receive MIDI data. -Pressing this button will turn the light off and disable the Bluetooth functionality. -Currently MIDI over Bluetooth is only supported on Mac OS. - -@subsection mac_bluetooth MacOS - -To connect a BLOCKS device via Bluetooth on MacOS, follow these steps: - -- Open the "Audio Midi Setup" application (found in Applications/Utilities) -- Click on the menu item: Window -> Show MIDI Studio -- Double-click on the "Bluetooth" icon in the MIDI Studio window -- Click the "Connect" button next to the block you want to connect to -- Your device should show up in the MIDI Studio window with a Bluetooth icon and can now send and receive MIDI data over Bluetooth - -@section connecting_blocks_to_each_other Connecting BLOCKS together - -Lightpad and Control Blocks can be connected together in any number of combinations via their DNA edge connectors, sharing a common connection to your computer. -To do this, simply snap your devices together and the magnetic connectors will handle the rest. -*/ - +/** +@page connecting_blocks Connecting BLOCKS + +Lightpads can be conected to a computer either via USB or Bluetooth, and Control Blocks can be connected via Bluetooth or by snapping to an already connected Lightpad. +Both devices communicate with your computer using System Exclusive (SysEx) MIDI messages. + +@section usb USB + +To connect a Lightpad to your computer over USB, you need to insert a USB-C cable into the top of the device and connect it to a USB port on your computer. +When powered on by pressing the power button on the bottom edge, you will be able to send and receive data from the block over the USB connection. + +@section bluetooth Bluetooth + +The power button also functions as a toggle for the Bluetooth connection - when the blue light on the button is illuminated, the device is able to connect via Bluetooth and send and receive MIDI data. +Pressing this button will turn the light off and disable the Bluetooth functionality. +Currently MIDI over Bluetooth is only supported on Mac OS. + +@subsection mac_bluetooth MacOS + +To connect a BLOCKS device via Bluetooth on MacOS, follow these steps: + +- Open the "Audio Midi Setup" application (found in Applications/Utilities) +- Click on the menu item: Window -> Show MIDI Studio +- Double-click on the "Bluetooth" icon in the MIDI Studio window +- Click the "Connect" button next to the block you want to connect to +- Your device should show up in the MIDI Studio window with a Bluetooth icon and can now send and receive MIDI data over Bluetooth + +@section connecting_blocks_to_each_other Connecting BLOCKS together + +Lightpad and Control Blocks can be connected together in any number of combinations via their DNA edge connectors, sharing a common connection to your computer. +To do this, simply snap your devices together and the magnetic connectors will handle the rest. +*/ diff --git a/extras/BLOCKS/doxygen/pages/juce_controlling_control_buttons.dox b/extras/BLOCKS/doxygen/pages/juce_controlling_control_buttons.dox index 6315143470..2712e543c3 100644 --- a/extras/BLOCKS/doxygen/pages/juce_controlling_control_buttons.dox +++ b/extras/BLOCKS/doxygen/pages/juce_controlling_control_buttons.dox @@ -1,18 +1,17 @@ -/** -@page controlling_control_buttons Controlling control buttons - -In addition to sending button pressed and button released events, ControlButton objects can allow your application code to change the colour of the LED behind the corresponding physical button on a BLOCKS device. - -An array of pointers to the available %ControlButton objects can be obtained from the Block::getButtons method of a Block---see the @ref discovering_blocks section for details of how to obtain a %Block object. -Once you have a %ControlButton, the functions involving the LED are ControlButton::hasLight and ControlButton::setLightColour, which are descriptively named. -A code snippet showing how to turn all the available buttons of a %Block red is shown below. -@code{.cpp} -void setAllButtonsRed (Block& block) -{ - for (auto button : block->getButtons()) - if (button->hasLight()) - button->setLightColour (Colours::red); -} -@endcode -*/ - +/** +@page controlling_control_buttons Controlling control buttons + +In addition to sending button pressed and button released events, ControlButton objects can allow your application code to change the colour of the LED behind the corresponding physical button on a BLOCKS device. + +An array of pointers to the available %ControlButton objects can be obtained from the Block::getButtons method of a Block---see the @ref discovering_blocks section for details of how to obtain a %Block object. +Once you have a %ControlButton, the functions involving the LED are ControlButton::hasLight and ControlButton::setLightColour, which are descriptively named. +A code snippet showing how to turn all the available buttons of a %Block red is shown below. +@code{.cpp} +void setAllButtonsRed (Block& block) +{ + for (auto button : block->getButtons()) + if (button->hasLight()) + button->setLightColour (Colours::red); +} +@endcode +*/ diff --git a/extras/BLOCKS/doxygen/pages/juce_controlling_led_grids.dox b/extras/BLOCKS/doxygen/pages/juce_controlling_led_grids.dox index 16eaa0182e..b9e1a04ee3 100644 --- a/extras/BLOCKS/doxygen/pages/juce_controlling_led_grids.dox +++ b/extras/BLOCKS/doxygen/pages/juce_controlling_led_grids.dox @@ -1,37 +1,36 @@ -/** -@page controlling_led_grids Controlling LED grids - -@section basic_usage Basic usage - -An LED grid on a BLOCKS device can be controlled via an LEDGrid object, which can be obtained from the Block::getLEDGrid function of a Block---see the @ref discovering_blocks section for details of how to obtain a %Block object. - -Using an LED grid requires an LEDGrid::Program to operate the LEDs. -This program specifies some code to run on the device, and can also provide methods to be called from your application which can comminucate with the code running on the device via a block of shared memory. -The code which runs on the device must be specified using @ref the_littlefoot_language, which is described in the corresponding section. -However, for a very wide range of applications, the BitmapLEDProgram provided with the BLOCKS SDK is sufficient and you will not need to create your own. -Using a %BitmapLEDProgram to change the colour of LEDs is demonstated below. - -@code{.cpp} -// This should be called when doing the initial configuration of your application. -void setBitmapLEDProgram (Block& block) -{ - if (auto grid = block->getLEDGrid()) - grid->setProgram (new BitmapLEDProgram (*grid)); -} - -// Once a BitmapLEDProgram is loaded we can use its setLED method to change the -// colour of LEDs on the corresponding device. -void setLED (Block& block, int x, int y, Colour c) -{ - if (auto grid = block->getLEDGrid()) - if (auto program = dynamic_cast (grid->getProgram())) - program->setLED (x, y, c); -} -@endcode - -@section advanced_usage Advanced Usage - -Using a custom %LEDGrid::Program allows more precise control over the operation of the LEDs. -The code which will actually execute on the device, returned by your overriden LEDGrid::Program::getLittleFootProgram() function, must be specified in the LittleFoot language. -*/ - +/** +@page controlling_led_grids Controlling LED grids + +@section basic_usage Basic usage + +An LED grid on a BLOCKS device can be controlled via an LEDGrid object, which can be obtained from the Block::getLEDGrid function of a Block---see the @ref discovering_blocks section for details of how to obtain a %Block object. + +Using an LED grid requires an LEDGrid::Program to operate the LEDs. +This program specifies some code to run on the device, and can also provide methods to be called from your application which can comminucate with the code running on the device via a block of shared memory. +The code which runs on the device must be specified using @ref the_littlefoot_language, which is described in the corresponding section. +However, for a very wide range of applications, the BitmapLEDProgram provided with the BLOCKS SDK is sufficient and you will not need to create your own. +Using a %BitmapLEDProgram to change the colour of LEDs is demonstated below. + +@code{.cpp} +// This should be called when doing the initial configuration of your application. +void setBitmapLEDProgram (Block& block) +{ + if (auto grid = block->getLEDGrid()) + grid->setProgram (new BitmapLEDProgram (*grid)); +} + +// Once a BitmapLEDProgram is loaded we can use its setLED method to change the +// colour of LEDs on the corresponding device. +void setLED (Block& block, int x, int y, Colour c) +{ + if (auto grid = block->getLEDGrid()) + if (auto program = dynamic_cast (grid->getProgram())) + program->setLED (x, y, c); +} +@endcode + +@section advanced_usage Advanced Usage + +Using a custom %LEDGrid::Program allows more precise control over the operation of the LEDs. +The code which will actually execute on the device, returned by your overriden LEDGrid::Program::getLittleFootProgram() function, must be specified in the LittleFoot language. +*/ diff --git a/extras/BLOCKS/doxygen/pages/juce_controlling_led_strips.dox b/extras/BLOCKS/doxygen/pages/juce_controlling_led_strips.dox index 48eaab5bb6..8d7549ea17 100644 --- a/extras/BLOCKS/doxygen/pages/juce_controlling_led_strips.dox +++ b/extras/BLOCKS/doxygen/pages/juce_controlling_led_strips.dox @@ -1,18 +1,17 @@ -/** -@page controlling_led_strips Controlling LED strips - -Control Blocks have a strip of LEDs which can be controlled via an LEDRow object. - -A pointer to an %LEDRow object can be obtained from the Block::getLEDRow method of a Block---see the @ref discovering_blocks section for details of how to obtain a %Block object. -Once you have an %LEDRow there are a few functions that you can use to interact with the strip of LEDs on a device. -A code snippet showing how to turn the whole strip of LEDs on a %Block orange is shown below. -@code{.cpp} -void setWholeLEDRowOrange (Block& block) -{ - if (auto ledRow = block->getLEDRow()) - for (int i = 0; i < ledRow.getNumLEDs(); ++i) - ledRow.setLEDColour (i, Colours::orange); -} -@endcode -*/ - +/** +@page controlling_led_strips Controlling LED strips + +Control Blocks have a strip of LEDs which can be controlled via an LEDRow object. + +A pointer to an %LEDRow object can be obtained from the Block::getLEDRow method of a Block---see the @ref discovering_blocks section for details of how to obtain a %Block object. +Once you have an %LEDRow there are a few functions that you can use to interact with the strip of LEDs on a device. +A code snippet showing how to turn the whole strip of LEDs on a %Block orange is shown below. +@code{.cpp} +void setWholeLEDRowOrange (Block& block) +{ + if (auto ledRow = block->getLEDRow()) + for (int i = 0; i < ledRow.getNumLEDs(); ++i) + ledRow.setLEDColour (i, Colours::orange); +} +@endcode +*/ diff --git a/extras/BLOCKS/doxygen/pages/juce_discovering_blocks.dox b/extras/BLOCKS/doxygen/pages/juce_discovering_blocks.dox index acc12f77dc..33ccc074ac 100644 --- a/extras/BLOCKS/doxygen/pages/juce_discovering_blocks.dox +++ b/extras/BLOCKS/doxygen/pages/juce_discovering_blocks.dox @@ -1,56 +1,55 @@ -/** -@page discovering_blocks Discovering BLOCKS - -Any BLOCKS application would be pretty limited without the ability to discover the BLOCKS that are connected to your computer. -This page gives an overview of the classes and methods available to aid BLOCKS discovery and provides sample code for getting notifications of any connections or disconnections. - -@section the_block_topology_object The BlockTopology object - -Groups of connected Lightpad and Control Blocks are described by a BlockTopology. - -A %BlockTopology contains an array of references to Block objects, which provide access to Lightpad and Control %Block functionality, and an array of BlockDeviceConnection objects, which describe the connections between devices. -Once you have a %BlockTopology you have all the information required to visualise and interact with your Lightpads and Control Blocks. -For more information about using %Block objects see the @ref the_block_object section. - -For Lightpads and Control Blocks a %BlockTopology can be obtained from a PhysicalTopologySource. - -@section the_physical_topology_source_object The PhysicalTopologySource object - -The current topology is provided by a %PhysicalTopologySource. -When instantiated, a %PhysicalTopologySource monitors for any connections from your computer to any Lightpad and Control Blocks and the PhysicalTopologySource::getCurrentTopology() method returns the current %BlockTopology. - -In an environment where Lightpad and Control can be connected and disconnected dynamically it is convenient to register your code for topologyChanged() callbacks from a %PhysicalTopologySource. -Then, when the current %BlockTopology changes, your application is able to react to the new configuration. -You can do this by inheriting from the TopologySource::Listener class and registering as a listener to a %PhysicalTopologySource object. -When you inherit from %TopologySource::Listener you must override the pure virtual method TopologySource::Listener::topologyChanged(), which is then called by a %PhysicalTopologySource on topology changes when you register as a listener. -A simple example is shown below. - -BlockFinder.h: -@include BlockFinder/BlockFinder.h - -BlockFinder.cpp: -@include BlockFinder/BlockFinder.cpp - -When instantiated this class simply monitors for changes to the connected Lightpad and Control Blocks and prints some information about them to stdout. -Once you have the current %BlockTopology object you have access to the available %Block objects and can start to interact with them. -A more complex application would probably do much more in the topologyChanged() method---see the @ref example_applications page. - -@section the_block_object The Block object - -A Block object is the main entry point for communicating between your application and any Lightpad and Control Blocks that are connected to your computer. - -All the different %Block types are subclasses of %Block so they provide the same interface (see the %Block class documentation). -About half of the %Block public member functions return information about the physical device it represents. -In the example code above you can see that we use some of these methods to query each %Block about its current status. -The more interesting %Block methods return pointers to objects you can use to control and receive events from individual BLOCKS. -More detail about these methods can be obtained from the following pages: - -@ref getting_touch_events - -@ref getting_control_button_events - -@ref controlling_led_grids - -@ref controlling_led_strips -*/ - +/** +@page discovering_blocks Discovering BLOCKS + +Any BLOCKS application would be pretty limited without the ability to discover the BLOCKS that are connected to your computer. +This page gives an overview of the classes and methods available to aid BLOCKS discovery and provides sample code for getting notifications of any connections or disconnections. + +@section the_block_topology_object The BlockTopology object + +Groups of connected Lightpad and Control Blocks are described by a BlockTopology. + +A %BlockTopology contains an array of references to Block objects, which provide access to Lightpad and Control %Block functionality, and an array of BlockDeviceConnection objects, which describe the connections between devices. +Once you have a %BlockTopology you have all the information required to visualise and interact with your Lightpads and Control Blocks. +For more information about using %Block objects see the @ref the_block_object section. + +For Lightpads and Control Blocks a %BlockTopology can be obtained from a PhysicalTopologySource. + +@section the_physical_topology_source_object The PhysicalTopologySource object + +The current topology is provided by a %PhysicalTopologySource. +When instantiated, a %PhysicalTopologySource monitors for any connections from your computer to any Lightpad and Control Blocks and the PhysicalTopologySource::getCurrentTopology() method returns the current %BlockTopology. + +In an environment where Lightpad and Control can be connected and disconnected dynamically it is convenient to register your code for topologyChanged() callbacks from a %PhysicalTopologySource. +Then, when the current %BlockTopology changes, your application is able to react to the new configuration. +You can do this by inheriting from the TopologySource::Listener class and registering as a listener to a %PhysicalTopologySource object. +When you inherit from %TopologySource::Listener you must override the pure virtual method TopologySource::Listener::topologyChanged(), which is then called by a %PhysicalTopologySource on topology changes when you register as a listener. +A simple example is shown below. + +BlockFinder.h: +@include BlockFinder/BlockFinder.h + +BlockFinder.cpp: +@include BlockFinder/BlockFinder.cpp + +When instantiated this class simply monitors for changes to the connected Lightpad and Control Blocks and prints some information about them to stdout. +Once you have the current %BlockTopology object you have access to the available %Block objects and can start to interact with them. +A more complex application would probably do much more in the topologyChanged() method---see the @ref example_applications page. + +@section the_block_object The Block object + +A Block object is the main entry point for communicating between your application and any Lightpad and Control Blocks that are connected to your computer. + +All the different %Block types are subclasses of %Block so they provide the same interface (see the %Block class documentation). +About half of the %Block public member functions return information about the physical device it represents. +In the example code above you can see that we use some of these methods to query each %Block about its current status. +The more interesting %Block methods return pointers to objects you can use to control and receive events from individual BLOCKS. +More detail about these methods can be obtained from the following pages: + +@ref getting_touch_events + +@ref getting_control_button_events + +@ref controlling_led_grids + +@ref controlling_led_strips +*/ diff --git a/extras/BLOCKS/doxygen/pages/juce_downloading_the_sdk.dox b/extras/BLOCKS/doxygen/pages/juce_downloading_the_sdk.dox index 52e37e47c4..207c80f5ba 100644 --- a/extras/BLOCKS/doxygen/pages/juce_downloading_the_sdk.dox +++ b/extras/BLOCKS/doxygen/pages/juce_downloading_the_sdk.dox @@ -1,12 +1,12 @@ -/** -@page downloading_the_sdk Downloading the SDK - -The BLOCKS SDK is distributed as part of the JUCE framework, which can be obtained from GitHub here. -The JUCE repository also contains the code for the @ref example_applications, which require the JUCE framework to compile. -Whilst you don't need to know anything about JUCE to build the examples using the supplied Visual Studio/Xcode/etc projects, it will probably be worthwhile reading a brief introduction to JUCE, which can be found here. - -You can also download the standalone BLOCKS SDK from GitHub here. -This is a stripped down version of what JUCE provides, including only the features required for the SDK. -Using this version of the SDK is much more complicated but may be more suitable for integrating BLOCKS into an existing application. -More details are provided in the @ref the_standalone_blocks_sdk section. -*/ +/** +@page downloading_the_sdk Downloading the SDK + +The BLOCKS SDK is distributed as part of the JUCE framework, which can be obtained from GitHub here. +The JUCE repository also contains the code for the @ref example_applications, which require the JUCE framework to compile. +Whilst you don't need to know anything about JUCE to build the examples using the supplied Visual Studio/Xcode/etc projects, it will probably be worthwhile reading a brief introduction to JUCE, which can be found here. + +You can also download the standalone BLOCKS SDK from GitHub here. +This is a stripped down version of what JUCE provides, including only the features required for the SDK. +Using this version of the SDK is much more complicated but may be more suitable for integrating BLOCKS into an existing application. +More details are provided in the @ref the_standalone_blocks_sdk section. +*/ diff --git a/extras/BLOCKS/doxygen/pages/juce_example_applications.dox b/extras/BLOCKS/doxygen/pages/juce_example_applications.dox index 068dfe4d34..10b9623121 100644 --- a/extras/BLOCKS/doxygen/pages/juce_example_applications.dox +++ b/extras/BLOCKS/doxygen/pages/juce_example_applications.dox @@ -1,30 +1,29 @@ -/** -@page example_applications Example Applications - -@section downloading_the_example_code Downloading the example code - -These example applications demonstrate the functionality of the BLOCKS SDK. - -The example applications are all distributed as part of the JUCE framework, which can be obtained from GitHub here. -You will find the examples in the JUCE/examples/BLOCKS/ directory. -Each example comes with projects for Visual Studio, Xcode, etc in the Builds subdirectory or each example directory, and these should open, compile and run without any trouble in the respective IDEs. - -A quick guide to getting up and running with JUCE can be found here. - -

Overview

- -@subpage example_blocks_monitor - -BlocksMonitor is a simple JUCE application that shows currently connected Lightpad and Control %Block devices and visualises touches and button presses. -It also displays some basic information about the Blocks. - -@subpage example_blocks_drawing - -BlocksDrawing is a JUCE application that allows you to use your Lightpad as a drawing surface. -You can choose from a palette of 9 base colours and paint them on the 15x15 LED grid, blending between colours using touch pressure. - -@subpage example_blocks_synth - -BlocksSynth is a JUCE application that turns your Lightpad into a simple monophonic synthesiser capable of playing 4 different waveshapes - sine, square, sawtooth and triangle. -*/ - +/** +@page example_applications Example Applications + +@section downloading_the_example_code Downloading the example code + +These example applications demonstrate the functionality of the BLOCKS SDK. + +The example applications are all distributed as part of the JUCE framework, which can be obtained from GitHub here. +You will find the examples in the JUCE/examples/BLOCKS/ directory. +Each example comes with projects for Visual Studio, Xcode, etc in the Builds subdirectory or each example directory, and these should open, compile and run without any trouble in the respective IDEs. + +A quick guide to getting up and running with JUCE can be found here. + +

Overview

+ +@subpage example_blocks_monitor + +BlocksMonitor is a simple JUCE application that shows currently connected Lightpad and Control %Block devices and visualises touches and button presses. +It also displays some basic information about the Blocks. + +@subpage example_blocks_drawing + +BlocksDrawing is a JUCE application that allows you to use your Lightpad as a drawing surface. +You can choose from a palette of 9 base colours and paint them on the 15x15 LED grid, blending between colours using touch pressure. + +@subpage example_blocks_synth + +BlocksSynth is a JUCE application that turns your Lightpad into a simple monophonic synthesiser capable of playing 4 different waveshapes - sine, square, sawtooth and triangle. +*/ diff --git a/extras/BLOCKS/doxygen/pages/juce_example_blocks_drawing.dox b/extras/BLOCKS/doxygen/pages/juce_example_blocks_drawing.dox index f26cb22047..9896685acd 100644 --- a/extras/BLOCKS/doxygen/pages/juce_example_blocks_drawing.dox +++ b/extras/BLOCKS/doxygen/pages/juce_example_blocks_drawing.dox @@ -1,35 +1,35 @@ -/** -@page example_blocks_drawing BlocksDrawing - -In order to compile and run this application you need to first download the JUCE framework, which can be obtained from GitHub here. - -@section blocks_drawing_introduction Introduction - -BlocksDrawing is a JUCE application that allows you to use your Lightpad as a drawing surface. You can choose from a palette of 9 base colours and paint them on the 15x15 LED grid, blending between colours using touch pressure. - -Navigate to the JUCE/examples/BLOCKS/BlocksDrawing/Builds/ directory and open the code project in your IDE of choice. Run the application and connect your Lightpad (if you do not know how to do this, see @ref connecting_blocks) - it should now display a 3x3 grid of colours to choose from. Touch a colour to set it as the current brush colour and then press the mode button to switch to canvas mode where you will be presented with a blank touch surface. Touch anywhere on the LED grid to start painting and use the pressure of your touch to control how bright the colour is. Try painting over an already painted LED to increase its brightness and blend between different colours by doing this with a different brush colour. To clear the canvas and start over, double-click the mode button. - -The concept of a BLOCKS topology and the methods for receiving callbacks from a Block object are covered in the @ref example_blocks_monitor example and this tutorial will cover the methods in the API for displaying grids and setting LEDs on the Lightpad. - -@section blocks_drawing_led_grid The LEDGrid Object - -Lightpads have a 15x15 LED grid which can be accessed and controlled through the LEDGrid object, a pointer to which is returned by the Block::getLEDGrid() method (for more details on how the %LEDGrid object operates, see @ref controlling_led_grids). In the topologyChanged() method of MainComponent this %LEDGrid pointer is passed to the setLEDProgram() method, which sets the LEDGrid::Program to either a DrumPadGridProgram or BitmapLEDProgram, depending on the selected mode. - -@section blocks_drawing_colour_palette Colour Palette - -In the colour palette mode the Lightpad displays a 3x3 grid of colours, constructed using the %DrumPadGridProgram class. A %DrumPadGridProgram pointer called colourPaletteProgram is declared as a private member variable of MainComponent and in the MainComponent::setLEDProgram() method this is set to point to a new %DrumPadGridProgram object and is passed the %LEDGrid object of the Lightpad in its constructor. After the program has been initialised, it is passed to the LEDGrid to display using the LEDGrid::setProgram() method and the layout of the grid is set up using the DrumPadGridProgram::setGridFills() method. This function takes 3 arguments: the number of rows, number of columns and an array of DrumPadGridProgram::GridFill objects containing a GridFill for each pad that controls its colour and fill type. The ColourGrid struct in MainComponent.h contains all of this information and handles the construction of the GridFill array in the ColourGrid::constructGridFillArray() method. An instance of this object called layout is declared as a member variable of MainComponent to easily change how the grid looks. The ColourGrid::setActiveColourForTouch() method is called in the MainComponent::touchChanged() callback and is used to determine which brush colour has been selected based on a Touch coordinate from the Lightpad. - -\image html BlocksDrawing_palette.JPG "Colour palette mode" - -@section blocks_drawing_canvas Canvas - -In canvas mode, the %LEDGrid program is set to an instance of %BitmapLEDProgram and uses the BitmapLEDProgram::setLED() method to set individual LEDs on the Lightpad to a particular colour. The ActiveLED struct declared in the private section of MainComponent is used to keep track of which LEDs are on and their colour and brightness. MainComponent contains an %Array of these objects called activeLeds. -In the MainComponent::setLEDProgram() method the program is set up and passed to the %LEDGrid object the same way as in the colour palette mode but the MainComponent::redrawLEDs() method is also called which iterates over the activeLeds array and sets the appropriate LEDs on the Lightpad so the LED states persist between mode switches. When a Touch is received in the MainComponent::touchChanged() callback the MainComponent::drawLEDs() method is called with 4 arguments: x and y coordinates, touch pressure and brush colour. This method iterates over the activeLed array and checks to see if there is an active LED at the given coordinate. If it is blank, an ActiveLED object is created and added to the array with the given coordinates and colour using touch pressure for brightness. If there is already an active LED at the coordinate, the colour of that LED will be blended with the current brush colour, the proportion of which is determined by the touch pressure. - -\image html BlocksDrawing_canvas.JPG "Unleash your inner Picasso!" - -@section blocks_drawing_summary Summary - -This tutorial and the accompanying code project have introduced the %LEDGrid object and shown how to use the %LEDGrid::Program object to display basic grids and set individual LEDs on the Lightpad. - -*/ +/** +@page example_blocks_drawing BlocksDrawing + +In order to compile and run this application you need to first download the JUCE framework, which can be obtained from GitHub here. + +@section blocks_drawing_introduction Introduction + +BlocksDrawing is a JUCE application that allows you to use your Lightpad as a drawing surface. You can choose from a palette of 9 base colours and paint them on the 15x15 LED grid, blending between colours using touch pressure. + +Navigate to the JUCE/examples/BLOCKS/BlocksDrawing/Builds/ directory and open the code project in your IDE of choice. Run the application and connect your Lightpad (if you do not know how to do this, see @ref connecting_blocks) - it should now display a 3x3 grid of colours to choose from. Touch a colour to set it as the current brush colour and then press the mode button to switch to canvas mode where you will be presented with a blank touch surface. Touch anywhere on the LED grid to start painting and use the pressure of your touch to control how bright the colour is. Try painting over an already painted LED to increase its brightness and blend between different colours by doing this with a different brush colour. To clear the canvas and start over, double-click the mode button. + +The concept of a BLOCKS topology and the methods for receiving callbacks from a Block object are covered in the @ref example_blocks_monitor example and this tutorial will cover the methods in the API for displaying grids and setting LEDs on the Lightpad. + +@section blocks_drawing_led_grid The LEDGrid Object + +Lightpads have a 15x15 LED grid which can be accessed and controlled through the LEDGrid object, a pointer to which is returned by the Block::getLEDGrid() method (for more details on how the %LEDGrid object operates, see @ref controlling_led_grids). In the topologyChanged() method of MainComponent this %LEDGrid pointer is passed to the setLEDProgram() method, which sets the LEDGrid::Program to either a DrumPadGridProgram or BitmapLEDProgram, depending on the selected mode. + +@section blocks_drawing_colour_palette Colour Palette + +In the colour palette mode the Lightpad displays a 3x3 grid of colours, constructed using the %DrumPadGridProgram class. A %DrumPadGridProgram pointer called colourPaletteProgram is declared as a private member variable of MainComponent and in the MainComponent::setLEDProgram() method this is set to point to a new %DrumPadGridProgram object and is passed the %LEDGrid object of the Lightpad in its constructor. After the program has been initialised, it is passed to the LEDGrid to display using the LEDGrid::setProgram() method and the layout of the grid is set up using the DrumPadGridProgram::setGridFills() method. This function takes 3 arguments: the number of rows, number of columns and an array of DrumPadGridProgram::GridFill objects containing a GridFill for each pad that controls its colour and fill type. The ColourGrid struct in MainComponent.h contains all of this information and handles the construction of the GridFill array in the ColourGrid::constructGridFillArray() method. An instance of this object called layout is declared as a member variable of MainComponent to easily change how the grid looks. The ColourGrid::setActiveColourForTouch() method is called in the MainComponent::touchChanged() callback and is used to determine which brush colour has been selected based on a Touch coordinate from the Lightpad. + +\image html BlocksDrawing_palette.JPG "Colour palette mode" + +@section blocks_drawing_canvas Canvas + +In canvas mode, the %LEDGrid program is set to an instance of %BitmapLEDProgram and uses the BitmapLEDProgram::setLED() method to set individual LEDs on the Lightpad to a particular colour. The ActiveLED struct declared in the private section of MainComponent is used to keep track of which LEDs are on and their colour and brightness. MainComponent contains an %Array of these objects called activeLeds. +In the MainComponent::setLEDProgram() method the program is set up and passed to the %LEDGrid object the same way as in the colour palette mode but the MainComponent::redrawLEDs() method is also called which iterates over the activeLeds array and sets the appropriate LEDs on the Lightpad so the LED states persist between mode switches. When a Touch is received in the MainComponent::touchChanged() callback the MainComponent::drawLEDs() method is called with 4 arguments: x and y coordinates, touch pressure and brush colour. This method iterates over the activeLed array and checks to see if there is an active LED at the given coordinate. If it is blank, an ActiveLED object is created and added to the array with the given coordinates and colour using touch pressure for brightness. If there is already an active LED at the coordinate, the colour of that LED will be blended with the current brush colour, the proportion of which is determined by the touch pressure. + +\image html BlocksDrawing_canvas.JPG "Unleash your inner Picasso!" + +@section blocks_drawing_summary Summary + +This tutorial and the accompanying code project have introduced the %LEDGrid object and shown how to use the %LEDGrid::Program object to display basic grids and set individual LEDs on the Lightpad. + +*/ diff --git a/extras/BLOCKS/doxygen/pages/juce_example_blocks_monitor.dox b/extras/BLOCKS/doxygen/pages/juce_example_blocks_monitor.dox index 3131c7bf6f..0d53be7f69 100644 --- a/extras/BLOCKS/doxygen/pages/juce_example_blocks_monitor.dox +++ b/extras/BLOCKS/doxygen/pages/juce_example_blocks_monitor.dox @@ -1,41 +1,40 @@ -/** -@page example_blocks_monitor BlocksMonitor - -In order to compile and run this application you need to first download the JUCE framework, which can be obtained from GitHub here. - -@section blocks_monitor_introduction Introduction - -BlocksMonitor is a simple JUCE application that shows currently connected Lightpad and Control %Block devices and visualises touches and button presses. It also displays some basic information about the Blocks. - -Navigate to the JUCE/examples/BLOCKS/BlocksMonitor/Builds/ directory and open the code project in your IDE of choice. Run the application and connect your Blocks (if you do not know how to do this, see @ref connecting_blocks). Any devices that you have connected should now show up in the application window and this display will be updated as you add and remove Blocks. Lightpads are represented as a black square and will display the current touches as coloured circles, the size of which depend on the touch pressure, and Control Blocks are shown as rectangles containing the LED row and clickable buttons on the hardware. If you hover the mouse cursor over a %Block, a tooltip will appear displaying the name, UID, serial number and current battery level. - -\image html BlocksMonitor.png "The BlocksMonitor application with a Lightpad and 3 Control Blocks connected" - -@section blocks_monitor_topology Topology - -One of the fundamental concepts of the BLOCKS API is topology - a topology is a set of physically connected Blocks and the connections between them. Knowing when the topology has changed and accessing a data structure containing the current topology is the basis of any Blocks application. - -To access the current topology, MainComponent inherits from the TopologySource::Listener base class and implements the TopologySource::Listener::topologyChanged() method, a callback which is used to inform listeners when any physical devices have been added or removed. In order to receive these callbacks, MainComponent contains an instance of the PhysicalTopologySource class and registers itself as a listener to this object in its constructor. When the topologyChanged() method is called, this object can be used to access the updated topology through the PhysicalTopologySource::getCurrentTopology() method which returns a BlockTopology struct containing an array of currently connected Block objects and an array of BlockDeviceConnection structs representing the connections between them. - -@section blocks_monitor_block_object The Block Object - -The array of %Block objects contained in the %BlockTopology struct can be used to access individual %Block objects and determine their type using the Block::getType() method. The application uses this information to construct an on-screen representation of the currently connected Blocks by creating either a LightpadComponent or ControlBlockComponent object for each %Block in the current topology. Both of these classes derive from BlockComponent, a relatively simple base class that contains some virtual functions for painting the %Block on screen and handling callbacks from the touch surface and/or buttons on the %Block. In its constructor, BlockComponent takes a pointer to the %Block object that it represents and adds itself as a listener to the touch surface (if it is a Lightpad) and buttons using the Block::getTouchSurface() and Block::getButtons() methods, respectively. It inherits from the TouchSurface::Listener and ControlButton::Listener classes and overrides the TouchSurface::Listener::touchChanged(), ControlButton::Listener::buttonPressed() and ControlButton::Listener::buttonReleased() methods to call its own virtual methods, which are implemented by the LightpadComponent and ControlBlockComponent classes to update the on-screen components. - -To visualise touches on the Lightpad, LightpadComponent contains an instance of the TouchList class called touches and calls the TouchList::updateTouch() method whenever it receives a touch surface listener callback in the LightpadComponent::handleTouchChange() method. The LightpadBlock::paint() method then iterates over the current TouchSurface::Touch objects in the %TouchList and visualises them on the component at 25Hz. - -The ControlBlockComponent class represents a generic Control %Block with 15 LEDs, 8 circular buttons and 1 rounded rectangular button. When a button is pressed on the physical Control %Block, the BlockComponent::handleButtonPressed() function is called and this class uses the ControlButton::ButtonFunction variable to determine which button was pressed and should be activated on the on-screen component. The same process is repeated for when the button is released. This class also overrides the BlockComponent::handleBatteryLevelUpdate() method to update which LEDs should be on based on the battery level, which is accessed in the BlockComponent base class using the Block::getBatteryLevel() and Block::isBatteryCharging() methods. - -These callback methods are a simple and powerful way to get user input from the Blocks and use this data to drive some process in your application. In this example, the input is simply mirrored on the screen but it could be used to control any number of things such as audio synthesis (see the @ref example_blocks_synth example) and graphics (see the @ref example_blocks_drawing example). - -@section blocks_monitor_connections Blocks Connections - -The %BlockTopology struct returned by the %PhysicalTopologySource::getCurrentTopology() method also contains an array of BlockDeviceConnection objects representing all the current DNA port connections between Blocks in the topology. A single %BlockDeviceConnection struct describes a physical connection between two ports on two Blocks and contains a Block::UID and Block::ConnectionPort object for each of the two devices. - -This information is used to calculate the position and rotation of each connected %Block and update the corresponding topLeft and rotation member variables of its BlockComponent so that the correct topology is displayed on the screen. The topLeft variable is a Point that describes the position of the top left of the BlockComponent in terms of logical device units relative to the top left of the master %Block at Point (0, 0). Initially, all BlockComponent instances have the topLeft position (0, 0) and the MainComponent::positionBlocks() method iterates first over all of the Blocks connected to the master %Block and then any remaining Blocks and calculates the correct topLeft %Point and rotation for each using the array of %BlockDeviceConnection objects. Then, in the MainComponent::resized() method these attributes are used to correctly position the components. - - -@section blocks_monitor_summary Summary - -This tutorial and the accompanying code has introduced the %BlockTopology and %Block objects, and demonstrated how to receive callbacks from connected Blocks when the touch surface or buttons are pressed, allowing you to use this input in your own applications. -*/ - +/** +@page example_blocks_monitor BlocksMonitor + +In order to compile and run this application you need to first download the JUCE framework, which can be obtained from GitHub here. + +@section blocks_monitor_introduction Introduction + +BlocksMonitor is a simple JUCE application that shows currently connected Lightpad and Control %Block devices and visualises touches and button presses. It also displays some basic information about the Blocks. + +Navigate to the JUCE/examples/BLOCKS/BlocksMonitor/Builds/ directory and open the code project in your IDE of choice. Run the application and connect your Blocks (if you do not know how to do this, see @ref connecting_blocks). Any devices that you have connected should now show up in the application window and this display will be updated as you add and remove Blocks. Lightpads are represented as a black square and will display the current touches as coloured circles, the size of which depend on the touch pressure, and Control Blocks are shown as rectangles containing the LED row and clickable buttons on the hardware. If you hover the mouse cursor over a %Block, a tooltip will appear displaying the name, UID, serial number and current battery level. + +\image html BlocksMonitor.png "The BlocksMonitor application with a Lightpad and 3 Control Blocks connected" + +@section blocks_monitor_topology Topology + +One of the fundamental concepts of the BLOCKS API is topology - a topology is a set of physically connected Blocks and the connections between them. Knowing when the topology has changed and accessing a data structure containing the current topology is the basis of any Blocks application. + +To access the current topology, MainComponent inherits from the TopologySource::Listener base class and implements the TopologySource::Listener::topologyChanged() method, a callback which is used to inform listeners when any physical devices have been added or removed. In order to receive these callbacks, MainComponent contains an instance of the PhysicalTopologySource class and registers itself as a listener to this object in its constructor. When the topologyChanged() method is called, this object can be used to access the updated topology through the PhysicalTopologySource::getCurrentTopology() method which returns a BlockTopology struct containing an array of currently connected Block objects and an array of BlockDeviceConnection structs representing the connections between them. + +@section blocks_monitor_block_object The Block Object + +The array of %Block objects contained in the %BlockTopology struct can be used to access individual %Block objects and determine their type using the Block::getType() method. The application uses this information to construct an on-screen representation of the currently connected Blocks by creating either a LightpadComponent or ControlBlockComponent object for each %Block in the current topology. Both of these classes derive from BlockComponent, a relatively simple base class that contains some virtual functions for painting the %Block on screen and handling callbacks from the touch surface and/or buttons on the %Block. In its constructor, BlockComponent takes a pointer to the %Block object that it represents and adds itself as a listener to the touch surface (if it is a Lightpad) and buttons using the Block::getTouchSurface() and Block::getButtons() methods, respectively. It inherits from the TouchSurface::Listener and ControlButton::Listener classes and overrides the TouchSurface::Listener::touchChanged(), ControlButton::Listener::buttonPressed() and ControlButton::Listener::buttonReleased() methods to call its own virtual methods, which are implemented by the LightpadComponent and ControlBlockComponent classes to update the on-screen components. + +To visualise touches on the Lightpad, LightpadComponent contains an instance of the TouchList class called touches and calls the TouchList::updateTouch() method whenever it receives a touch surface listener callback in the LightpadComponent::handleTouchChange() method. The LightpadBlock::paint() method then iterates over the current TouchSurface::Touch objects in the %TouchList and visualises them on the component at 25Hz. + +The ControlBlockComponent class represents a generic Control %Block with 15 LEDs, 8 circular buttons and 1 rounded rectangular button. When a button is pressed on the physical Control %Block, the BlockComponent::handleButtonPressed() function is called and this class uses the ControlButton::ButtonFunction variable to determine which button was pressed and should be activated on the on-screen component. The same process is repeated for when the button is released. This class also overrides the BlockComponent::handleBatteryLevelUpdate() method to update which LEDs should be on based on the battery level, which is accessed in the BlockComponent base class using the Block::getBatteryLevel() and Block::isBatteryCharging() methods. + +These callback methods are a simple and powerful way to get user input from the Blocks and use this data to drive some process in your application. In this example, the input is simply mirrored on the screen but it could be used to control any number of things such as audio synthesis (see the @ref example_blocks_synth example) and graphics (see the @ref example_blocks_drawing example). + +@section blocks_monitor_connections Blocks Connections + +The %BlockTopology struct returned by the %PhysicalTopologySource::getCurrentTopology() method also contains an array of BlockDeviceConnection objects representing all the current DNA port connections between Blocks in the topology. A single %BlockDeviceConnection struct describes a physical connection between two ports on two Blocks and contains a Block::UID and Block::ConnectionPort object for each of the two devices. + +This information is used to calculate the position and rotation of each connected %Block and update the corresponding topLeft and rotation member variables of its BlockComponent so that the correct topology is displayed on the screen. The topLeft variable is a Point that describes the position of the top left of the BlockComponent in terms of logical device units relative to the top left of the master %Block at Point (0, 0). Initially, all BlockComponent instances have the topLeft position (0, 0) and the MainComponent::positionBlocks() method iterates first over all of the Blocks connected to the master %Block and then any remaining Blocks and calculates the correct topLeft %Point and rotation for each using the array of %BlockDeviceConnection objects. Then, in the MainComponent::resized() method these attributes are used to correctly position the components. + + +@section blocks_monitor_summary Summary + +This tutorial and the accompanying code has introduced the %BlockTopology and %Block objects, and demonstrated how to receive callbacks from connected Blocks when the touch surface or buttons are pressed, allowing you to use this input in your own applications. +*/ diff --git a/extras/BLOCKS/doxygen/pages/juce_example_blocks_synth.dox b/extras/BLOCKS/doxygen/pages/juce_example_blocks_synth.dox index 0e29eeb328..eff61f4f63 100644 --- a/extras/BLOCKS/doxygen/pages/juce_example_blocks_synth.dox +++ b/extras/BLOCKS/doxygen/pages/juce_example_blocks_synth.dox @@ -1,37 +1,37 @@ -/** -@page example_blocks_synth BlocksSynth - -In order to compile and run this application you need to first download the JUCE framework, which can be obtained from GitHub here. - -@section blocks_synth_introduction Introduction - -BlocksSynth is a JUCE application that turns your Lightpad into a simple monophonic synthesiser capable of playing 4 different waveshapes - sine, square, sawtooth and triangle. - -Navigate to the JUCE/examples/BLOCKS/BlocksSynth/Builds/ directory and open the code project in your IDE of choice. Run the application and connect your Lightpad (if you do not know how to do this, see @ref connecting_blocks) - it should now display a simple 5x5 grid where each pad plays a note in the chromatic scale using a sine wave starting from the bottom-left (C3). It is possible to play any of the 25 notes but for ease of use tonics (the root note of the scale) are highlighted in white and notes in the C-major scale are highlighted in green. When a note has been played it is possible to change the amplitude using touch pressure and to pitch bend between adjacent notes by sliding left and right. Pressing the mode button on the Lightpad will change to the waveshape selection screen where the currently selected waveshape is rendered on the LEDs and you can switch between the 4 different waveshapes by touching anywhere on the %Block surface. - -The concept of a BLOCKS topology and the methods for receiving callbacks from the Block object are covered in the @ref example_blocks_monitor example and the basic methods for displaying grids and setting LEDs on the %Block are covered in the @ref example_blocks_drawing example. This example will cover how to render custom programs on the LEDGrid using the Littlefoot language and how to do some simple audio synthesis using data from the Lightpad. - -@section blocks_synth_note_grid Note Grid - -In the synthesiser mode the Lightpad displays a 5x5 grid constructed using the DrumPadGridProgram class. The SynthGrid struct in MainComponent.h handles the setup and layout of this grid and sets the colours of the pads to white for tonics, green for notes in the C major scale and black for notes that are not in the C major scale. The ColourGrid::getNoteNumberForPad() method is called in the MainComponent::touchChanged() callback and returns the corresponding MIDI note number for a Touch coordinate on the Lightpad. This note number is then passed to the Audio class to be played on the synthesiser. - -\image html BlocksSynth_grid.JPG "Synthesiser note grid" - -@section blocks_synth_waveshape_display Waveshape Display - -In the waveshape selection mode the LEDGrid::Program is set to an instance of the WaveshapeProgram class, which is contained in the WaveshapeProgram.h file. This class inherits from %LEDGrid::Program so that it can be loaded onto the %LEDGrid and its LittleFoot program can be executed on the Lightpad. The class itself is relatively simple and contains a method to set which waveshape should be displayed, a method to load the coordinates for each of the four waveshapes into the heap and two pure virtual methods overridden from %LEDGrid::Program - LEDGrid::Program::getLittleFootProgram() and LEDGrid::Program::getHeapSize(). The heap is the area of shared memory that is used by the program to communicate with the host computer and the size of this memory is set using the getHeapSize() method. In the private section of WaveshapeProgram the structure of the shared data heap is laid out with variables containing the offsets for each section and the totalDataSize variable contains the total size (in bytes) that is required and is returned by the WaveshapeProgram::getHeapSize() method. The heap contains space for a variable that determines which waveshape type to display and the Y coordinates for 1.5 cycles of each of the four waveshapes. - -The WaveshapeProgram::getLittleFootProgram() method returns the LittleFoot program that will be executed on the BLOCKS device. The repaint() method of this program is called at approximately 25Hz and is used to draw the moving waveshape on the LEDs of the Lightpad. Each time this method is called, it clears the LEDs by setting them all to black then calculates the heap offset based on the waveshape type that has been set and uses a for loop to iterate over the 15 LEDs on the X-axis and draw an LED 'circle' using the drawLEDCircle() method at the corresponding Y coordinate for the selected waveshape. The read position of the heap is offset using the yOffset variable which is incremented each repaint() call and wraps back around when the end of the heap section for the selected waveshape is reached to draw a 'moving' waveshape. - -\image html BlocksSynth_waveshape.gif "A sine wave dispayed in the waveshape selection mode" - -@section blocks_synth_audio Audio - -The Audio class handles the audio synthesis for this application and overrides the AudioIODeviceCallback::audioDeviceIOCallback() method to call the Synthesiser::renderNextBlock() method of a Synthesiser object. This object is initialised to be capable of rendering sine, square, sawtooth and triangle waves on separate MIDI channels in the constructor of Audio, and Audio contains methods for sending note on, note off, channel pressure and pitch wheel messages to the Synthesiser. When a note is triggered on the Lightpad, the Audio::noteOn() method is called with 3 arguments: a MIDI channel corresponding to the waveshape that should be generated, a MIDI note number and an initial velocity. Whilst the note is playing, the amplitude and pitch are modulated by calling the Audio::pressureChange() and Audio::pitchChange() methods from the MainComponent::touchChanged() callback. The pressure value of the Touch instance is used to directly control the Synthesiser amplitude and the distance from the initial note trigger on the X-axis of the Lightpad is scaled to +/-1.0 and used to modulate the frequency of the currently playing note. -The Oscillators.h file contains the waveshape rendering code. It contains an Oscillator base class which inherits from SynthesiserVoice and has a pure virtual Oscillator::renderWaveShape() method that is overridden by subclasses to render the 4 different waveshapes. - -@section blocks_synth_summary Summary - -This tutorial and the accompanying code project have expanded on the topics covered by previous tutorials, showing you how to display more complex, custom programs on the %LEDGrid using the LittleFoot language and how to control simple audio synthesis parameters using the Lightpad. - -*/ +/** +@page example_blocks_synth BlocksSynth + +In order to compile and run this application you need to first download the JUCE framework, which can be obtained from GitHub here. + +@section blocks_synth_introduction Introduction + +BlocksSynth is a JUCE application that turns your Lightpad into a simple monophonic synthesiser capable of playing 4 different waveshapes - sine, square, sawtooth and triangle. + +Navigate to the JUCE/examples/BLOCKS/BlocksSynth/Builds/ directory and open the code project in your IDE of choice. Run the application and connect your Lightpad (if you do not know how to do this, see @ref connecting_blocks) - it should now display a simple 5x5 grid where each pad plays a note in the chromatic scale using a sine wave starting from the bottom-left (C3). It is possible to play any of the 25 notes but for ease of use tonics (the root note of the scale) are highlighted in white and notes in the C-major scale are highlighted in green. When a note has been played it is possible to change the amplitude using touch pressure and to pitch bend between adjacent notes by sliding left and right. Pressing the mode button on the Lightpad will change to the waveshape selection screen where the currently selected waveshape is rendered on the LEDs and you can switch between the 4 different waveshapes by touching anywhere on the %Block surface. + +The concept of a BLOCKS topology and the methods for receiving callbacks from the Block object are covered in the @ref example_blocks_monitor example and the basic methods for displaying grids and setting LEDs on the %Block are covered in the @ref example_blocks_drawing example. This example will cover how to render custom programs on the LEDGrid using the Littlefoot language and how to do some simple audio synthesis using data from the Lightpad. + +@section blocks_synth_note_grid Note Grid + +In the synthesiser mode the Lightpad displays a 5x5 grid constructed using the DrumPadGridProgram class. The SynthGrid struct in MainComponent.h handles the setup and layout of this grid and sets the colours of the pads to white for tonics, green for notes in the C major scale and black for notes that are not in the C major scale. The ColourGrid::getNoteNumberForPad() method is called in the MainComponent::touchChanged() callback and returns the corresponding MIDI note number for a Touch coordinate on the Lightpad. This note number is then passed to the Audio class to be played on the synthesiser. + +\image html BlocksSynth_grid.JPG "Synthesiser note grid" + +@section blocks_synth_waveshape_display Waveshape Display + +In the waveshape selection mode the LEDGrid::Program is set to an instance of the WaveshapeProgram class, which is contained in the WaveshapeProgram.h file. This class inherits from %LEDGrid::Program so that it can be loaded onto the %LEDGrid and its LittleFoot program can be executed on the Lightpad. The class itself is relatively simple and contains a method to set which waveshape should be displayed, a method to load the coordinates for each of the four waveshapes into the heap and two pure virtual methods overridden from %LEDGrid::Program - LEDGrid::Program::getLittleFootProgram() and LEDGrid::Program::getHeapSize(). The heap is the area of shared memory that is used by the program to communicate with the host computer and the size of this memory is set using the getHeapSize() method. In the private section of WaveshapeProgram the structure of the shared data heap is laid out with variables containing the offsets for each section and the totalDataSize variable contains the total size (in bytes) that is required and is returned by the WaveshapeProgram::getHeapSize() method. The heap contains space for a variable that determines which waveshape type to display and the Y coordinates for 1.5 cycles of each of the four waveshapes. + +The WaveshapeProgram::getLittleFootProgram() method returns the LittleFoot program that will be executed on the BLOCKS device. The repaint() method of this program is called at approximately 25Hz and is used to draw the moving waveshape on the LEDs of the Lightpad. Each time this method is called, it clears the LEDs by setting them all to black then calculates the heap offset based on the waveshape type that has been set and uses a for loop to iterate over the 15 LEDs on the X-axis and draw an LED 'circle' using the drawLEDCircle() method at the corresponding Y coordinate for the selected waveshape. The read position of the heap is offset using the yOffset variable which is incremented each repaint() call and wraps back around when the end of the heap section for the selected waveshape is reached to draw a 'moving' waveshape. + +\image html BlocksSynth_waveshape.gif "A sine wave dispayed in the waveshape selection mode" + +@section blocks_synth_audio Audio + +The Audio class handles the audio synthesis for this application and overrides the AudioIODeviceCallback::audioDeviceIOCallback() method to call the Synthesiser::renderNextBlock() method of a Synthesiser object. This object is initialised to be capable of rendering sine, square, sawtooth and triangle waves on separate MIDI channels in the constructor of Audio, and Audio contains methods for sending note on, note off, channel pressure and pitch wheel messages to the Synthesiser. When a note is triggered on the Lightpad, the Audio::noteOn() method is called with 3 arguments: a MIDI channel corresponding to the waveshape that should be generated, a MIDI note number and an initial velocity. Whilst the note is playing, the amplitude and pitch are modulated by calling the Audio::pressureChange() and Audio::pitchChange() methods from the MainComponent::touchChanged() callback. The pressure value of the Touch instance is used to directly control the Synthesiser amplitude and the distance from the initial note trigger on the X-axis of the Lightpad is scaled to +/-1.0 and used to modulate the frequency of the currently playing note. +The Oscillators.h file contains the waveshape rendering code. It contains an Oscillator base class which inherits from SynthesiserVoice and has a pure virtual Oscillator::renderWaveShape() method that is overridden by subclasses to render the 4 different waveshapes. + +@section blocks_synth_summary Summary + +This tutorial and the accompanying code project have expanded on the topics covered by previous tutorials, showing you how to display more complex, custom programs on the %LEDGrid using the LittleFoot language and how to control simple audio synthesis parameters using the Lightpad. + +*/ diff --git a/extras/BLOCKS/doxygen/pages/juce_getting_control_button_events.dox b/extras/BLOCKS/doxygen/pages/juce_getting_control_button_events.dox index 32e59a3e05..8b762a9a76 100644 --- a/extras/BLOCKS/doxygen/pages/juce_getting_control_button_events.dox +++ b/extras/BLOCKS/doxygen/pages/juce_getting_control_button_events.dox @@ -1,40 +1,39 @@ -/** -@page getting_control_button_events Getting control button events - -Control button events are communicated from Lightpad and Control Blocks to your application via ControlButton objects. - -You can obtain an array of %ControlButton pointers associated with a specific Lightpad or Control %Block from its corresponding Block object using the Block::getButtons method---see the @ref discovering_blocks page for an example of how to obtain %Block objects. -Each pointer to a %ControlButton will be valid for the lifetime of the %Block object. - -Once you have a %ControlButton you must register as a ControlButton::Listener to receive button pressed and button released callbacks. -The process for doing this is to have one of your application's classes inherit from %ControlButton::Listener and override the pure virtual methods ControlButton::Listener::buttonPressed and ControlButton::Listener::buttonReleased. -Then, when you register your derived class as a listener to a particular %ControlButton, your overriden methods will be called when the corresponding button is pressed and released. - -Registering a class derived from %ControlButton::Listener with multiple %ControlButton objects is done as follows: -@code{.cpp} -class ControlButtonListenerExample : public ControlButton::Listener -{ -public: - ControlButtonListenerExample (Block& block) - { - for (auto button : block->getButtons()) - button->addListener (this); - } - - virtual void buttonPressed (ControlButton&, sourceControlButton, Block::Timestamp timestamp) override - { - // Do something when the sourceControlButton is pressed! - } - - virtual void buttonReleased (ControlButton&, sourceControlButton, Block::Timestamp timestamp) override - { - // Do something when the sourceControlButton is released! - } -}; -@endcode - -When your overriden buttonPressed or buttonReleased methods are called you have access to two paramters: a reference to the %ControlButton that generated this event and timestamp for the event. - -You will find multiple examples of control button listeners in the @ref example_applications pages. -*/ - +/** +@page getting_control_button_events Getting control button events + +Control button events are communicated from Lightpad and Control Blocks to your application via ControlButton objects. + +You can obtain an array of %ControlButton pointers associated with a specific Lightpad or Control %Block from its corresponding Block object using the Block::getButtons method---see the @ref discovering_blocks page for an example of how to obtain %Block objects. +Each pointer to a %ControlButton will be valid for the lifetime of the %Block object. + +Once you have a %ControlButton you must register as a ControlButton::Listener to receive button pressed and button released callbacks. +The process for doing this is to have one of your application's classes inherit from %ControlButton::Listener and override the pure virtual methods ControlButton::Listener::buttonPressed and ControlButton::Listener::buttonReleased. +Then, when you register your derived class as a listener to a particular %ControlButton, your overriden methods will be called when the corresponding button is pressed and released. + +Registering a class derived from %ControlButton::Listener with multiple %ControlButton objects is done as follows: +@code{.cpp} +class ControlButtonListenerExample : public ControlButton::Listener +{ +public: + ControlButtonListenerExample (Block& block) + { + for (auto button : block->getButtons()) + button->addListener (this); + } + + virtual void buttonPressed (ControlButton&, sourceControlButton, Block::Timestamp timestamp) override + { + // Do something when the sourceControlButton is pressed! + } + + virtual void buttonReleased (ControlButton&, sourceControlButton, Block::Timestamp timestamp) override + { + // Do something when the sourceControlButton is released! + } +}; +@endcode + +When your overriden buttonPressed or buttonReleased methods are called you have access to two paramters: a reference to the %ControlButton that generated this event and timestamp for the event. + +You will find multiple examples of control button listeners in the @ref example_applications pages. +*/ diff --git a/extras/BLOCKS/doxygen/pages/juce_getting_touch_events.dox b/extras/BLOCKS/doxygen/pages/juce_getting_touch_events.dox index 75e25f1c37..6a02a61efe 100644 --- a/extras/BLOCKS/doxygen/pages/juce_getting_touch_events.dox +++ b/extras/BLOCKS/doxygen/pages/juce_getting_touch_events.dox @@ -1,36 +1,35 @@ -/** -@page getting_touch_events Getting touch events - -Touch events are communicated from BLOCKS devices to your application code via TouchSurface objects. - -You can obtain a pointer to the %TouchSurface associated with a specific BLOCKS device from its corresponding Block object using the Block::getTouchSurface() method---see the @ref discovering_blocks page for an example of how to obtain %Block objects. -For devices without a touch surface (such as the Control Block) this method will return nullptr, but if the device is capable of sending touch events then the pointer to the %TouchSurface will be valid for the lifetime of the %Block object. - -Once you have a %TouchSurface you must register as a TouchSurface::Listener to get touch events. -The process for doing this is to have one of your application's classes inherit from %TouchSurface::Listener and override the pure virtual method TouchSurface::Listener::touchChanged. -Then, when you register your derived class as a listener to a particular %TouchSurface, your overriden method will be called when the corresponding device is touched. - -A safe way of registering a class derived from %TouchSurface::Listener with a %TouchSurface is as follows. -@code{.cpp} -class TouchSurfaceListenerExample : public TouchSurface::Listener -{ -public: - TouchSurfaceListenerExample (Block& block) - { - if (auto touchSurface = block->getTouchSurface()) - touchSurface->addListener (this); - } - - virtual void touchChanged (TouchSurface& sourceTouchSurface, const TouchSurface::Touch& touchEvent) override - { - // Do something with touchEvent here! - } -}; -@endcode - -When your overriden touchChanged method is called you have access to two paramters: a reference to the %TouchSurface that generated this event and a reference to a TouchSurface::Touch. -The %TouchSurface::Touch class contains member variables describing the postion, pressure, velocity, timestamp and more. - -You will find multiple examples of using TouchSurfaces in the @ref example_applications pages. -*/ - +/** +@page getting_touch_events Getting touch events + +Touch events are communicated from BLOCKS devices to your application code via TouchSurface objects. + +You can obtain a pointer to the %TouchSurface associated with a specific BLOCKS device from its corresponding Block object using the Block::getTouchSurface() method---see the @ref discovering_blocks page for an example of how to obtain %Block objects. +For devices without a touch surface (such as the Control Block) this method will return nullptr, but if the device is capable of sending touch events then the pointer to the %TouchSurface will be valid for the lifetime of the %Block object. + +Once you have a %TouchSurface you must register as a TouchSurface::Listener to get touch events. +The process for doing this is to have one of your application's classes inherit from %TouchSurface::Listener and override the pure virtual method TouchSurface::Listener::touchChanged. +Then, when you register your derived class as a listener to a particular %TouchSurface, your overriden method will be called when the corresponding device is touched. + +A safe way of registering a class derived from %TouchSurface::Listener with a %TouchSurface is as follows. +@code{.cpp} +class TouchSurfaceListenerExample : public TouchSurface::Listener +{ +public: + TouchSurfaceListenerExample (Block& block) + { + if (auto touchSurface = block->getTouchSurface()) + touchSurface->addListener (this); + } + + virtual void touchChanged (TouchSurface& sourceTouchSurface, const TouchSurface::Touch& touchEvent) override + { + // Do something with touchEvent here! + } +}; +@endcode + +When your overriden touchChanged method is called you have access to two paramters: a reference to the %TouchSurface that generated this event and a reference to a TouchSurface::Touch. +The %TouchSurface::Touch class contains member variables describing the postion, pressure, velocity, timestamp and more. + +You will find multiple examples of using TouchSurfaces in the @ref example_applications pages. +*/ diff --git a/extras/BLOCKS/doxygen/pages/juce_main.dox b/extras/BLOCKS/doxygen/pages/juce_main.dox index a5f122b0c8..4b64c381cb 100644 --- a/extras/BLOCKS/doxygen/pages/juce_main.dox +++ b/extras/BLOCKS/doxygen/pages/juce_main.dox @@ -1,65 +1,65 @@ -/** -@mainpage Documentation - -Welcome to the BLOCKS SDK documentation. -
- -Here you will find all the information required to start creating BLOCKS applications. -A brief summary of the main sections is below. - -
-@subpage downloading_the_sdk - -This section describes how to obtain the SDK source code, either via the JUCE framework or @ref the_standalone_blocks_sdk. - -
-@subpage connecting_blocks - -Lightpad and Control Blocks communicate with a computer over USB-C or Bluetooth, and communicate with each other via magnetic connections on their sides. -This section contains instructions for configuring your setup so that all the components can communicate with each other. - -
-@subpage discovering_blocks - -Once you have connected your device to your computer you need to be able to discover it from your application. -This section outlines the procedure for Lightpad and Control %Block discovery and provides some simple example code which monitors for new connections. - -
-@subpage getting_touch_events - -This section explains how to capture touch events from a compatible device and, building on the @ref discovering_blocks section, displays some example code. - -
-@subpage getting_control_button_events - -Lightpad and Control Blocks have control buttons, either a mode button on their side or labelled buttons on top, and this section shows you how to obtain button pressed and button released events. - -
-@subpage controlling_led_grids - -This section explains how to control the LED grid on a Lightpad. - -
-@subpage the_littlefoot_language - -Advanced SDK users can specify specialised programs to run on Lightpad Blocks. -These programs must be written in the LittleFoot language, which is described -in this section. - -
-@subpage controlling_led_strips - -Control Blocks have a strip of lights running along one side and this section provides instructions for controling the individual LEDs. - -
-@subpage controlling_control_buttons - -As well as providing button pressed and button released events, control buttons also have LEDs. -This section explains how to change the colour of different buttons. - -
-@subpage the_standalone_blocks_sdk - -The easiest way to get started using the SDK is via the JUCE framework, but if you want to integrate BLOCKS functionality into your existing application then it may be more convenient to use @ref the_standalone_blocks_sdk. -This section gives an overview of building and using the BLOCKS SDK as a library. -*/ +/** +@mainpage Documentation + +Welcome to the BLOCKS SDK documentation. +
+ +Here you will find all the information required to start creating BLOCKS applications. +A brief summary of the main sections is below. + +
+@subpage downloading_the_sdk + +This section describes how to obtain the SDK source code, either via the JUCE framework or @ref the_standalone_blocks_sdk. + +
+@subpage connecting_blocks + +Lightpad and Control Blocks communicate with a computer over USB-C or Bluetooth, and communicate with each other via magnetic connections on their sides. +This section contains instructions for configuring your setup so that all the components can communicate with each other. + +
+@subpage discovering_blocks + +Once you have connected your device to your computer you need to be able to discover it from your application. +This section outlines the procedure for Lightpad and Control %Block discovery and provides some simple example code which monitors for new connections. + +
+@subpage getting_touch_events + +This section explains how to capture touch events from a compatible device and, building on the @ref discovering_blocks section, displays some example code. + +
+@subpage getting_control_button_events + +Lightpad and Control Blocks have control buttons, either a mode button on their side or labelled buttons on top, and this section shows you how to obtain button pressed and button released events. + +
+@subpage controlling_led_grids + +This section explains how to control the LED grid on a Lightpad. + +
+@subpage the_littlefoot_language + +Advanced SDK users can specify specialised programs to run on Lightpad Blocks. +These programs must be written in the LittleFoot language, which is described +in this section. + +
+@subpage controlling_led_strips + +Control Blocks have a strip of lights running along one side and this section provides instructions for controling the individual LEDs. + +
+@subpage controlling_control_buttons + +As well as providing button pressed and button released events, control buttons also have LEDs. +This section explains how to change the colour of different buttons. + +
+@subpage the_standalone_blocks_sdk + +The easiest way to get started using the SDK is via the JUCE framework, but if you want to integrate BLOCKS functionality into your existing application then it may be more convenient to use @ref the_standalone_blocks_sdk. +This section gives an overview of building and using the BLOCKS SDK as a library. +*/ diff --git a/extras/BLOCKS/doxygen/pages/juce_the_littlefoot_language.dox b/extras/BLOCKS/doxygen/pages/juce_the_littlefoot_language.dox index 4e115eb8ba..82b5a57954 100644 --- a/extras/BLOCKS/doxygen/pages/juce_the_littlefoot_language.dox +++ b/extras/BLOCKS/doxygen/pages/juce_the_littlefoot_language.dox @@ -1,24 +1,23 @@ -/** -@page the_littlefoot_language The LittleFoot Language - -@section littlefoot_description A description of the LittleFoot language - -A description of the LittleFoot language is contained in the SDK source code at juce_blocks_basics/littlefoot/LittleFoot Language README.txt: -@includedoc "LittleFoot Language README.txt" - -@section littlefoot_example A LittleFoot example - -The %BitmapLEDProgram class is a simple example of a LittleFoot program. - -%juce_blocks_basics/visualisers/juce_BitmapLEDProgram.h -@include juce_blocks_basics/visualisers/juce_BitmapLEDProgram.h - -juce_blocks_basics/visualisers/juce_BitmapLEDProgram.cpp -@include juce_blocks_basics/visualisers/juce_BitmapLEDProgram.cpp - -The repaint() method of the LittleFoot program is called at approximately 25 Hz, and each time it simply inspects the heap (the shared area of memory used to communicate between your application code and your LittleFoot program) and sets the LEDs based on the heap's content. -To update the heap, and hence the LEDS, your application code calls BitmapLEDProgram::setLED. - -A more advanced example can be found in the source code of the DrumPadGridProgram class or in the @ref example_blocks_synth example. -*/ - +/** +@page the_littlefoot_language The LittleFoot Language + +@section littlefoot_description A description of the LittleFoot language + +A description of the LittleFoot language is contained in the SDK source code at juce_blocks_basics/littlefoot/LittleFoot Language README.txt: +@includedoc "LittleFoot Language README.txt" + +@section littlefoot_example A LittleFoot example + +The %BitmapLEDProgram class is a simple example of a LittleFoot program. + +%juce_blocks_basics/visualisers/juce_BitmapLEDProgram.h +@include juce_blocks_basics/visualisers/juce_BitmapLEDProgram.h + +juce_blocks_basics/visualisers/juce_BitmapLEDProgram.cpp +@include juce_blocks_basics/visualisers/juce_BitmapLEDProgram.cpp + +The repaint() method of the LittleFoot program is called at approximately 25 Hz, and each time it simply inspects the heap (the shared area of memory used to communicate between your application code and your LittleFoot program) and sets the LEDs based on the heap's content. +To update the heap, and hence the LEDS, your application code calls BitmapLEDProgram::setLED. + +A more advanced example can be found in the source code of the DrumPadGridProgram class or in the @ref example_blocks_synth example. +*/ diff --git a/extras/BLOCKS/doxygen/pages/juce_the_standalone_blocks_sdk.dox b/extras/BLOCKS/doxygen/pages/juce_the_standalone_blocks_sdk.dox index 44c6b9d69a..9df215e549 100644 --- a/extras/BLOCKS/doxygen/pages/juce_the_standalone_blocks_sdk.dox +++ b/extras/BLOCKS/doxygen/pages/juce_the_standalone_blocks_sdk.dox @@ -1,69 +1,68 @@ -/** -@page the_standalone_blocks_sdk The standalone BLOCKS SDK - -The easiest way to get started developing BLOCKS applications is to use the JUCE framework, but if you would prefer not to use JUCE directly the standalone BLOCKS SDK can be obtained from the BLOCKS-SDK repository. - -The most straightforward way to use the SDK is to compile the SDK source code into a static library. -Then, in your BLOCKS application code, you can use the header files in the SDK to give you access to the BLOCKS classes and functions. -Finally, when you want to compile your application, you must link against the static library to get all the BLOCKS functionality. - -@section standalone_building_library Building the SDK library - -The source code for the BLOCKS SDK library is contained within the SDK directory of the BLOCKS-SDK repository. -Here you will find header files that you can include in your own projects and the Build subdirectory contains an Xcode project, a Visual Studio project and a Linux Makefile for compiling the SDK source code into a static library. -Use the appropriate choice for your platform, select either the "Debug" or "Release" configuration, and build the project. - -For MacOS this will produce libBLOCKS-SDK.a in either the SDK/Build/MacOS/Debug/ or SDK/Build/MacOS/Release/ directory, for Linux this will produce libBLOCKS-SDK.a in either the SDK/Build/Linux/Debug/ or SDK/Build/Linux/Release/ directory, and for Windows this will produce BLOCKS-SDK.lib in either the SDK\\Build\\Windows\\x64\\Debug or SDK\\Build\\Windows\\x64\\Release folder. - -@section standalone_using_header Using the SDK header file - -To use BLOCKS classes and functions in your application you must include the BlocksHeader.h file in your source code. -You also need to tell the compiler to look in the SDK directory for additional header files, which you can configure inside your Xcode or Visual Studio project. -If you are using the command line to compile your application then you can see an example of how to do this in examples/BLOCKS-SDK/BlockFinder/Linux/Makefile (which is also configured for MacOS, despite being located inside the Linux directory). - -@section standalone_linking Linking against the SDK library - -You must also tell your compiler where to find the SDK static library before your BLOCKS application will compile, and include all of the dependencies for your platform, which are listed in the @ref standalone_dependencies section. -Again, this is configured in your Xcode or Visual Studio project, but if you are using the command line you can see an example of how to do this in examples/BLOCKS-SDK/BlockFinder/Linux/Makefile (which, again, is also configured for MacOS). - -@section standalone_example An example application - -The source code for this example can be found in the BLOCKS-SDK repository at examples/BlockFinder/, with the parts that are specific to different operating systems in the corresonding subdirectories. - -The main functionality of the application is contained within the following class: - -BlockFinder/BlockFinder.h: -@include BlockFinder/BlockFinder.h - -BlockFinder/BlockFinder.cpp: -@include BlockFinder/BlockFinder.cpp - -All this class does is create a PhysicalTopologySource and register for TopologySource::Listener::topologyChanged() callbacks---for more information about how this works you should see the @ref discovering_blocks section. -When the topology changes we print some information about the available BLOCKS. - -The main function of the MacOS application is the easiest to understand. - -BlockFinder/MacOS/main.mm: -@include BlockFinder/MacOS/main.mm - -Here we simply perform some JUCE initialisation, instantiate a BlockFinder class, then run the event loop. -Whilst in the event loop, the finder object receives TopologySource::Listener::topologyChanged() callbacks and we see output printed to stdout when BLOCKS are connected or disconnected. - -@section standalone_dependencies Standalone SDK dependencies - -- A C++11 compatible compiler - -@subsection standalone_libraries_macos MacOS frameworks - -- Accelerate -- AudioToolbox -- CoreAudio -- CoreMIDI - -@subsection standalone_libraries_linux Linux packages - -- x11 -- alsa -- libcurl -*/ - +/** +@page the_standalone_blocks_sdk The standalone BLOCKS SDK + +The easiest way to get started developing BLOCKS applications is to use the JUCE framework, but if you would prefer not to use JUCE directly the standalone BLOCKS SDK can be obtained from the BLOCKS-SDK repository. + +The most straightforward way to use the SDK is to compile the SDK source code into a static library. +Then, in your BLOCKS application code, you can use the header files in the SDK to give you access to the BLOCKS classes and functions. +Finally, when you want to compile your application, you must link against the static library to get all the BLOCKS functionality. + +@section standalone_building_library Building the SDK library + +The source code for the BLOCKS SDK library is contained within the SDK directory of the BLOCKS-SDK repository. +Here you will find header files that you can include in your own projects and the Build subdirectory contains an Xcode project, a Visual Studio project and a Linux Makefile for compiling the SDK source code into a static library. +Use the appropriate choice for your platform, select either the "Debug" or "Release" configuration, and build the project. + +For MacOS this will produce libBLOCKS-SDK.a in either the SDK/Build/MacOS/Debug/ or SDK/Build/MacOS/Release/ directory, for Linux this will produce libBLOCKS-SDK.a in either the SDK/Build/Linux/Debug/ or SDK/Build/Linux/Release/ directory, and for Windows this will produce BLOCKS-SDK.lib in either the SDK\\Build\\Windows\\x64\\Debug or SDK\\Build\\Windows\\x64\\Release folder. + +@section standalone_using_header Using the SDK header file + +To use BLOCKS classes and functions in your application you must include the BlocksHeader.h file in your source code. +You also need to tell the compiler to look in the SDK directory for additional header files, which you can configure inside your Xcode or Visual Studio project. +If you are using the command line to compile your application then you can see an example of how to do this in examples/BLOCKS-SDK/BlockFinder/Linux/Makefile (which is also configured for MacOS, despite being located inside the Linux directory). + +@section standalone_linking Linking against the SDK library + +You must also tell your compiler where to find the SDK static library before your BLOCKS application will compile, and include all of the dependencies for your platform, which are listed in the @ref standalone_dependencies section. +Again, this is configured in your Xcode or Visual Studio project, but if you are using the command line you can see an example of how to do this in examples/BLOCKS-SDK/BlockFinder/Linux/Makefile (which, again, is also configured for MacOS). + +@section standalone_example An example application + +The source code for this example can be found in the BLOCKS-SDK repository at examples/BlockFinder/, with the parts that are specific to different operating systems in the corresonding subdirectories. + +The main functionality of the application is contained within the following class: + +BlockFinder/BlockFinder.h: +@include BlockFinder/BlockFinder.h + +BlockFinder/BlockFinder.cpp: +@include BlockFinder/BlockFinder.cpp + +All this class does is create a PhysicalTopologySource and register for TopologySource::Listener::topologyChanged() callbacks---for more information about how this works you should see the @ref discovering_blocks section. +When the topology changes we print some information about the available BLOCKS. + +The main function of the MacOS application is the easiest to understand. + +BlockFinder/MacOS/main.mm: +@include BlockFinder/MacOS/main.mm + +Here we simply perform some JUCE initialisation, instantiate a BlockFinder class, then run the event loop. +Whilst in the event loop, the finder object receives TopologySource::Listener::topologyChanged() callbacks and we see output printed to stdout when BLOCKS are connected or disconnected. + +@section standalone_dependencies Standalone SDK dependencies + +- A C++11 compatible compiler + +@subsection standalone_libraries_macos MacOS frameworks + +- Accelerate +- AudioToolbox +- CoreAudio +- CoreMIDI + +@subsection standalone_libraries_linux Linux packages + +- x11 +- alsa +- libcurl +*/ diff --git a/extras/Projucer/Source/Application/jucer_CommandLine.cpp b/extras/Projucer/Source/Application/jucer_CommandLine.cpp index 71ba6acf2d..4d0f5201f8 100644 --- a/extras/Projucer/Source/Application/jucer_CommandLine.cpp +++ b/extras/Projucer/Source/Application/jucer_CommandLine.cpp @@ -92,7 +92,7 @@ namespace { Array files; - for (DirectoryIterator di (folder, true, "*.cpp;*.cxx;*.cc;*.c;*.h;*.hpp;*.hxx;*.hpp;*.mm;*.m;*.java;", File::findFiles); di.next();) + for (DirectoryIterator di (folder, true, "*.cpp;*.cxx;*.cc;*.c;*.h;*.hpp;*.hxx;*.hpp;*.mm;*.m;*.java;*.dox;", File::findFiles); di.next();) if (! di.getFile().isSymbolicLink()) files.add (di.getFile());