USER GUIDE
Table of Contents Introduction.......................................................................................................................................... 1 About This Guide....................................................................................................................................................................................................2 What is FlowBotics Studio?....................................................................................................
Table of Contents Components.........................................................................................................................................................................................................22 Adding a Component...............................................................................................................................................................................22 Selections and the Action Panel.....................................................
Table of Contents Template Connectors...............................................................................................................................................................................49 Input and Output Names..........................................................................................................................................................................49 Make Module...........................................................................................
Table of Contents Focus on the previous Module.................................................................................................................................................................67 Data Types & Signal Flow................................................................................................................. 68 Stream Data.....................................................................................................................................................
Table of Contents Module GUI...........................................................................................................................................................................................................87 Module GUI Component..........................................................................................................................................................................87 MGUI Connectors......................................................................
Table of Contents Effect on Code Execution......................................................................................................................................................................108 Scheduling Events..............................................................................................................................................................................................109 Scheduling an Event......................................................................
Table of Contents Pen Alignment........................................................................................................................................................................................141 Line Joins...............................................................................................................................................................................................141 Dashes..................................................................................
Table of Contents Processing Frames in a DLL.................................................................................................................................................................168 Ruby Limitations.................................................................................................................................................................................................170 Single Interpreter........................................................................
Table of Contents The DLL..............................................................................................................................................................................................................187 Data Types.............................................................................................................................................................................................187 Ints......................................................................
Introduction Introduction ABOUT THIS GUIDE AND SOFTWARE OVERVIEW 1 of 212
Introduction About This Guide This manual provides a detailed description of the FlowBotics Studio software and its functions. Its purpose is to show you how the software works and what it’s capabilities are. For information about individual components that ship with the software, see the Component Reference guide: http://www.flowbotics.com/manuals/flowbotics-studio-component-reference.
Introduction What is FlowBotics Studio? FlowBotics Studio is a graphical computer programming language for the rapid development of software applications. Using the software you have complete flexibility to create exactly the kind of application you want. You can add customised controls to modify parameters in real time and group these controls together to make powerful user interfaces. Your completed creations can then be exported as completely independent executable applications.
Introduction Components and links are laid out on a 1024x1024 square grid which we call a schematic. In order to allow for more sophisticated schematics we have a special type of component called a module. Modules are special types of component in that they are defined by their own schematic. containing other components and modules. Modules can also have an interactive front panel with it’s own controls and custom graphics. Any component that is not a module we call a Primitive.
User Interface User Interface A FIRST LOOK AROUND 5 of 212
User Interface Before you can begin using the software you need to know a little bit about the user interface. Let’s start by taking a look at the main application window and how it’s laid out. Across the top of the window is the menu bar. All the applications functions can be accessed from here and it’s the first place you should look if you’re new to the software and you want to get an idea of what you can do with it.
User Interface Toolbox The toolbox provides the building blocks for a schematic – the components. There are already over 450 components to choose from and they are growing in number all the time. Of course if there are hundreds of components then you’ll want to be able to put your hands on the component you’re after quickly and with little effort. Thankfully there are several mechanisms in place to make this exceptionally easy.
User Interface Favourites and Recent The first two buttons on the top row change the list of components so that only Favourites or Recently used components are shown. The Recently used filter shows the components that you used last. They are ordered such that the most recently used is at the top of the list. The Favourites filter shows only components that you have marked as a favourite (more on this later), Category Filters The next 3 buttons on the top row filter the list by category.
User Interface Clear All Filters To clear ALL the filters (including the search) you can either right-click on the filter pane or press the ESC key on your keyboard. Favourites You can create a list of Favourite components that you use most often. By using the Favourites filter in the Filter Pane you have a very quick way to get at the components you need with the minimum of effort.
User Interface The second way to create a local toolbox is to select a module and then then choose Create Local Toolbox from the Schematic menu or press SHIFT + CTRL + T. On this occasion the Local Toolbox will contain all the components that are inside the module. Note that the local toolbox has no dependency on the components from which it was created. This means that you can create a local toolbox then delete the components that it was made from.
User Interface Tag Bar The toolbox incorporates a tag system which allows you to organise components based on some shared characteristic. Tags are added and displayed on the Tag Bar. You can then apply tags to individual components and use the Tag Bar to instantly filter the toolbox based on a particular tag or set of tags. Editing Tags There are some tags already provided but you can completely change these if you want to. To make any kind of changes you first need to unlock the tag bar for editing.
User Interface Tagging Components Once you have some tags you can then add them to components in the toolbox. To change the tags for a component click the tag button for that component. This is located at the bottom-right corner of each component in the toolbox. Tag Button A pop-up menu will appear with all the tags on the tag bar. Click on an unchecked tag to add it or a checked tag to remove it. Components can have more than one tag.
User Interface Single Tag Multiple Tags Locked Tag 13 of 212
User Interface Navigator The Navigator allows you to see where you are in your schematic. This is extremely useful when you have several layers of modules because the Schematic Window only shows the module that you’re editing. Jumping The Navigator is not just visual, it’s interactive too. You can jump to any module in the current chain by clicking on it. You can also use the number keys to do this (providing you are not using the PC keyboard for MIDI input).
User Interface Panning The current module in the chain is highlighted. Inside you’ll see a rectangle representing the portion of the module that you can see in the schematic window. This is the called the View Rectangle. You can click and drag this to pan around the schematic. Bookmarks You can bookmark particular parts of your schematic so that you can easily return to them. To do this simply go to the part of your schematic you want to bookmark, hold SHIFT and press one of the function keys (F1…F15).
User Interface Schematic Window The schematic window is where everything comes together. Components can be dragged here from the toolbox. You can connect components by dragging links between them. The schematic window has all the features that you’d expect in an editor: undo, copy and paste, multiple selection, zooming, and context sensitive help are all fully supported. Zooming The Schematic Window is fully zoomable.
User Interface 2. Now right-click and hold that button down too. The cursor will change to show a hand grabbing the schematic. 3. Now move the mouse and the schematic will move with it. Release both mouse buttons to finish dragging. You can also pan by holding the space bar down. The cursor will change to the hand. Keep the space bar down and drag the schematic around.
Components & Links Components & Links THE BASIC ELEMENTS OF A SCHEMATIC 18 of 212
Components & Links Components Components and links are the bricks and mortar of a FlowBotics Studio schematic. Understanding how to edit and manipulate these basic elements is essential for working with the software as most of the interaction you’ll have with FlowBotics Studio will be through the schematic. We introduced the concept of components and links right at the start of this guide. We’ll go over this again now but in a little more detail this time.
Components & Links Links Links define how information flows between components in a schematic. A link passes from the output connector of one component to the input connector of another component. The direction of information flow is generally left to right or from output to input but in some cases information can pass from input to output as well. You can have multiple links from the same output connector. You can also have multiple links passing to the same input connector.
Components & Links Infinite Feedback Links can be connected from a component into itself to create feedback paths. However, in some circumstances this may create an infinite feedback loop. If this happens the software will ‘freeze’ the affected link(s). A frozen link is shown as a red dashed or dotted line. Frozen links continue to function but data flow through them is reduced (but not restricted altogether) to prevent the software locking up.
Components & Links Components Adding a Component Dragging From the Toolbox To add a component to a schematic, simply go to the toolbox, pick the component you want and drag it into your schematic.
Components & Links Stacking Components Sometimes you may want to add more than one component at a time. You can do this by stacking up components before dragging them all to the schematic. To increase the number in the stack just click on the component the same number of times as the number you require. You’ll see a counter appear in the bottom-left corner of the component in the toolbox. Stack indicator To decrease the number in the stack right-click on the component.
Components & Links Shortcut Key Indicators 24 of 212
Components & Links Disabled Components On some occasions it is not possible for you to add a particular component to your schematic. This is because some components are only allowed once within a particular module or the whole schematic. This can also occur if you're running the Free or Enterprise editions and you reach one of the limits for components of a particular type. If this happens the component will have a red 'no entry' symbol over the top of it.
Components & Links Selections and the Action Panel To select a component simply click on it. When you do this you'll see the action panel. This contains a number of buttons. the 'X' button will delete the component. The 'N' button will allow you to name the component. Other buttons may appear depending on the type of component selected - more on these later. The commands in the action panel can also be invoked from the menu bar and the context menu. To get the context menu, right-click on the component.
Components & Links Naming Components You can give a component a name. This is just a label that can be used to remind you the role of a component in your schematic. To give a component a name, click the 'N' button on the action panel or right-click on the component and select Rename. Alternatively you can select the component and press CTRL+R. An edit box will appear above the component. Type the name here then press ENTER, TAB or just click on another part of your schematic.
Components & Links Resizing Some components can be resized to make them bigger or smaller. Some components only resize horizontally, others resize vertically as well. If a component can be resized, the resize control will appear in the bottom-right corner of the selection highlight. The control is a white arc that traces the corner of the selection.
Components & Links Multiple Selections You can select multiple components at the same time. This is useful if you want to move a group of components but maintain their relative spacing or if you want to delete a whole load of things in one go. There are two ways to create a multiple selection. The first way is to hold down SHIFT and then click on each of the components in turn. If a component is already selected, clicking on it will remove it from the selection.
Components & Links Connector Labels Most components have a short label for each of their input connectors. There isn’t enough room on the component body for both inputs and output labels. The outputs are usually less ambiguous and fewer in number and so input labels are usually preferred. Component labels are usually very short and provide a quick reminder of what each connector is for. If you need more information you can select the component (by clicking on it).
Components & Links Links In this section you'll learn how to move a link to another connector or delete it completely. You'll also see how to change link order and how to bend a link. Creating a Link Links must start at an input connector and end at an output connector. You can link another component or to itself, to create a feedback path say. To create a link: 1. Move your mouse over an output connector. The connector highlight will show as you pass over it. 2.
Components & Links Allowed Links Sometimes it is not possible to make a link between a pair of connectors. When this happens the mouse cursor will change to show this. In general links can be made only between connectors of the same type. However, there are several exceptions to this. For example, Floats and Ints can be connected so can Floats and Stream connectors. A complete description of all these exceptions can be found in Chapter Converting Between Data Types on page 78.
Components & Links Deleting a Link There are several ways to delete a link. You can pick it up and drop it into empty space. Just move it from the input connector (as described above) but don't link it to another connector. You can also right-click on the link and select Delete Link from the context menu. For really quick deleting, hold down CTRL. When your mouse passes over a link, the delete button will appear. Click the button and the link is gone.
Components & Links Link Order When there are many links ending at the same input connector, the order of the links can affect the behaviour of your schematic. For example, if you have two links that are passing String data to a string connector, the first string to arrive will have the second one appended to it. The order of a link is indicated by an order marker. This is a series of notches perpendicular to the link at it's end point.
Components & Links Bending Links In a complex schematic with many components, sometimes a straight line just won't do. Often you'll struggle to avoid creating links that run over components or each other. To get round this problem, you can bend any link to make your schematic clearer and easier to read. All you have to do is click on the link and pull it into place. Each bend you put in a link creates a control point. The control points define the path of the link.
Components & Links Straight Links In schematics with lots of links that overlap or follow a similar path it can sometimes be neater to have the links follow a straight line path instead of a curve. You can do this in one of two ways. If the link is still a single line then if you go to bend the link (as described earlier) but hold SHIFT + CTRL as you click to add the first control point, the link will now be a non-curved (straight) link.
Components & Links If you don’t want to have to wait for the link to be created you can instantly accept the suggested link by clicking the right mouse button. There are several options for Auto Linking. These can be adjusted by selecting Schematic from the Options menu. You can change the time between suggestion and link creation you can also set how close connectors have to be before a link is suggested.
Components & Links Smart Linking If you need to link several components together quickly then you can use the smart linking feature. Simply position your components in a logical way, select them then either click the Link Components button on the action panel or select Link Components from the Schematic Menu. The software will make a best guess at how you want the components to be linked together.
Components & Links Removing Multiple Links You can remove all the links in a selection in one go. Simply right-click on the selection and choose Remove Links from the pop-up menu. This can be very useful when you have a large section of schematic that you need to disconnect Swapping Links Sometimes you might want to replace a component in a schematic with another component.
Components & Links 3. The Wireless Input and Output must have the same connector type When a link is established the connection indicators on the Wireless Input and Output will light up. Wireless links only work down the module hierarchy, you can’t link back upwards. Also, the range of a wireless output only extends as far as the next wireless output below it which has the same label and connector type.
Components & Links The schematic jumps to the first Wireless Input component that that connects to Max. We can see from the highlight that this is component 1 of 2. The schematic shows the path through the schematic to this component and the wireless connection. Because we selected a Module Wireless Output the connection is shown from the point of transmission ie the parent module. We can clearly see that the receiver is inside the 'To 0-1' module inside 'Preset'.
Modules Modules MANAGING COMPLEXITY 42 of 212
Modules You may recall from the introduction that components are broken into two types: primitives and modules. A primitive has a predefined behaviour. It’s a black box whose behaviour can't be changed. A module on the other hand has it's behaviour defined by a schematic. You can add inputs and outputs and the internal behaviour can be modified to do virtually anything you want. The module component can be found in the toolbox under the Module filter group.
Modules Key Differences Apart from the fact that a module has it’s own schematic there are a few other key differences between Modules and Primitives. This section outlines those differences. More details are given in subsequent sections. Appearance First off modules can be differentiated from Primitives by the way they look. A module has a light grey background whereas a primitive has a dark grey border with a drop shadow and title bar.
Modules Front Panel Any module can have a front panel. This is shown on the module itself and provides an interactive surface for adding controls or displaying graphics. The front panel graphics and interaction is all defined in the module’s schematic. Properties If you want to control the behaviour of a module in a more interactive manner then instead of using input connectors you can define a properties panel. Again the properties panel is defined by the module’s schematic.
Modules Toolbox The final key difference between a module and a primitive is that a module can be dragged to the toolbox for use at a later date. You can drag a module on it’s own or you can drag all selected modules in one go. Dragging a module to the toolbox When you do this the module will automatically acquire any tags you have selected at the time. If no tag is selected then the module will have no tags added automatically.
Modules Basic Operations You can do everything to a module that you can do to a primitive. You can delete it, name it, move it around etc. The key difference between a module and a component is that you can go into a module and view or edit it's schematic. Moving into a Module With most operations in FlowBotics Studio there are many ways to do the same thing. Moving into a module is no exception. To move into a module, either: 1. Click the Move into Module button on the action panel 2.
Modules Inputs and Outputs To get information into and out of a module you need to add inputs and outputs. To do this, just drag them in from toolbox in the usual way (you'll find them under the Module group). The example opposite shows a module with two inputs and three outputs. For a quick way to add Module Inputs and Module Output components you can use keyboard shortcuts. A select few components are used much more frequently than the others.
Modules Template Connectors The connectors for the Module Input and Module Output components are what we call Template Connectors. These have no defined type. There are two ways you can assign a type to a template connector: 1. Automatically pick up the type from another connector by creating a link to that connector. 2. Set the type explicitly by right-clicking on the connector and choosing the type from the context menu.
Modules Make Module You’ll find that as you build a schematic you’ll want and need to section parts off into separate modules in order to manage the increasing complexity. You can do this easily using the Make Module feature. Simply select a number of components then click the Make Module button on the selection action panel (or right-click on the selection and select Make Module).
Modules Wireless Modules Most modules will have fixed output connectors that you physically link up to other connectors. However, it is sometimes useful to make a module output wireless. Instead of using a Module Output component you use a Module Wireless Output component. By adding wireless outputs to your module the module becomes a wireless module.
Modules Front Panel Every module has the option of having a front panel. Front panels allow you to add interactive elements to your schematic and they are the mechanism by which you provide a graphical user interface (GUI) for your creations. Enabling the Front Panel The front panel is shown on the module itself. By default the front panel is disabled. To enable it, select the module then click the G (GUI) button (you can also right-click on the module and select Enable Front Panel).
Modules Editing the Front Panel When you place knobs, sliders and other controls inside a module that has a front panel then these items will instantly appear on the front panel. However, everything will be stacked up in the top-left corner. In order to arrange the items you need to unlock the front panel. First select the module then click the padlock button on the action panel (you can also right-click on the module and select Edit Front Panel or hold CTRL and press E).
Modules Selecting You can select items in the front panel in the usual way by clicking on them. If you hold SHIFT you can click to add or remove items from the selection. You can also click on an empty part of the front panel and drag to select all items in a rectangular area. To select all the items you can use CTRL+A. If one item is underneath another you can hold ALT and click to alternate between selecting the top item and the one below.
Modules Moving Having selected items you can then move them by dragging them around. By default the position snaps to the grid but you can prevent this by holding CTRL as you drag. You can also use the cursor keys to nudge a selection by one grid square at a time in any direction. If you hold CTRL while nudging you will move a distance equivalent to 1 pixel at the default zoom level. If you’re zoomed in or out then you’ll move by a distance that is equivalent to 1 pixel at the current zoom level.
Modules Jumping If you want to jump straight to the module that is represented by a front panel item then all you need to do is hold SHIFT and double-click on it.
Modules Sub-Panel Editing Each front panel item is a module with its own front panel and so may contain its own front panel items. You can edit these sub panel items in place. Simply double-click on an item and the editor will mask out everything around the item and allow you access to the sub panel items below. Double-clicking on the masked area will move you back up one level.
Modules Hiding Item Boundaries When editing a front panel, each item has its boundary marked with a rectangle. If you're editing a sub panel item then you may have some masking applied as well. Sometimes these things can get in the way of you seeing exactly how your layout will look. To help with this you can hide all the boundaries and masking by pressing the X key. Press this key again to return things to normal.
Modules Grouped Items Sometimes front panel items are grouped together. This is determined by the way that the modules are constructed. We’ll talk about how this comes about later on so for now we’ll just talk about what happens when it occurs. Grouped items are indicated by a thin dotted line around the items. The only way that grouped items behave differently from those that are not grouped is that they are constrained to appear in the same draw order relative to each other.
Modules The module will appear as it would be if no front panel were present. You can maximize the module again to show the front panel if you wish by performing the same action. Visibility in Parent Module Panels There are some circumstances under which you don’t want a module’s front panel to appear in parent module front panels.
Modules Properties We’ve already seen how to access and change the properties of a module but how do they get there in the first place? In this section you’ll learn how to add properties to your own modules. Enabling the Properties Panel To enable the properties panel all you need to do is select the module and click the P button on the action panel. You can also right-click on the module and select Enable Properties.
Modules Adding Property Items The items on the property panel each map onto a particular component somewhere within the module or it’s sub-modules. There are six different types of components that can be enabled for display on the properties panel. They are: Int, Float, String, Boolean, Index Selector and Trigger Button. To enable one of these components for display on the properties, right-click on the component and select Property.
Modules Control Types Each of the five property enabled component types has a control that represents it on the Properties panel. There are just three different types of control. Float, Int and String components are represented by Edit controls. These have a label which takes it’s text from the label of the component. Boolean components are shown as a check box. Again the label for the check box uses the text from the label of the Boolean component The Trigger Button component is represented by a button.
Modules Resizing The size of the properties panel can be adjusted independently of the size of the module. When the panel is open any resizing of the module will only apply to the properties panel. When you click away or close the properties panel the module will return to it’s original size. Customizing You are not just restricted to the three control types described earlier. Because the panel works just like an extra front panel you can in fact add any kind of controls or graphics you like.
Modules Synchronising You’ll often find that you have many copies of the same module scattered around your schematic. This is one of the great benefits of modules – you create one and then you can use it in many other places. However, what happens when you want to change the behaviour of the module? Well, you certainly don’t want to have to change all your copies one by one. You could change just one of them and then copy and paste it again but that’s not great either.
Modules Synchronise All If you didn’t think in advance that you wanted copies of a module to be in sync then don’t worry. There’s an easy way to put them all in sync after they have been created. Just right-click on one of the modules and select Synchronise All. All the modules that match the module you clicked will be put into sync, regardless of where they reside in your schematic. Note that if any of the original copies have been altered in any way then they cannot be brought into sync.
Modules Focus Mode If you're building an application to export sometimes you may want to preview it or even just use it without all the editing interface getting in the way. You can do this using a feature called Focus Mode. Focus Mode applies to a particular module. It collapses the application window around a module and allows you to have it as the main focus – as if it was the application.
Data Types & Signal Flow Data Types & Signal Flow CONNECTOR TYPES EXPLAINED 68 of 212
Data Types & Signal Flow FlowBotics Studio supports over 30 different types of data. Each type has it’s own connector with a unique symbol for easy recognition. Although there are many different types of data they all fall into one of three different categories: Stream, Triggered or Event. Stream data covers all digital audio and control signals. These signals are fluctuating at sampling rate and so any components which process them will also perform calculations at sampling rate.
Data Types & Signal Flow Stream Data If you are interested in audio applications or processing data at high data rates then you'll need to work with stream data. Streams deliver high data rate digital signals which you can then process in the software. This is know as Digital Signal Processing (or DSP). If you're not familiar with DSP then the next section will give you a quick overview.
Data Types & Signal Flow Poly connector - represents multi-channel audio signals. Each channel is an independent fast moving stream of floating point data that fluctuates at sampling rate. The data is multi-channel because there is one channel for each note that you play. When to Use Poly or Mono You would use a combination of Poly components (a Poly section) to model the polyphonic part of a synth. With a Poly section you can generate separate audio signals for each voice or note that you play.
Data Types & Signal Flow Poly and Mono Sections In Audio Applications To get any data to flow through a poly or mono section you have to connect it up correctly. In most cases you’ll want to use MIDI input from a keyboard or other source to generate notes. You then want each note to make a sound that you can hear. The most common setup would be as shown below: 1. The MIDI to Poly module converts incoming MIDI note data into Poly signals 2. The Poly section processes the signals 3.
Data Types & Signal Flow Boolean Connectors There are Boolean equivalents of the Poly, Mono and Stream data types. They are only seen on a few components, most notably the Poly and Mono comparison components. The MIDI to Poly module has a Poly Boolean output which shifts from false to true when a note is played and can therefore be used as a gate signal.
Data Types & Signal Flow Triggered Data How it Works Triggered data only flows through a schematic when an event occurs that ‘triggers’ a change. Until this happens sections of triggered data remain in a steady state. When an event does occur a message called a Trigger is sent out through output connectors on one or more components. The trigger flows through the links until it reaches another component. That component then assesses whether it’s state would be affected.
Data Types & Signal Flow Float - a 32 bit floating point number Int - a 32 bit signed integer in the range –2147483648 to 2147483648 String – an alphanumeric string of characters of unlimited length Boolean – one of two values: true or false Trigger - not really a data type (there is no data) but used to pass trigger messages Array Types These types represent resizable arrays of some of the primary types. An array is just an ordered list of items of the same type.
Data Types & Signal Flow Ruby Types In Ruby all data is considered to be an object. Numbers are objects, strings are objects, arrays are objects. Outside of Ruby code objects all have the same type: VALUE so when you pass Ruby objects between Ruby components you pass them through the Ruby Value connector. Value – can refer to any Ruby object Special Types There are a handful of data types that stand on their own.
Data Types & Signal Flow Event Data How it Works Like triggered data, Event data only flows through a schematic when something occurs that causes a change. Until this happens sections of event data remain in a steady state. When an event does occur a message called an Event is sent out through output connectors on one or more components. The Event flows through the links until it reaches another component. This all sounds very similar to the Trigger system. However, there are two important differences.
Data Types & Signal Flow Converting Between Data Types In most cases you will create links between connectors of the same type. However, FlowBotics Studio supports several automatic and intuitive conversions between data types which you'll find extremely handy. String <> Boolean You can get a boolean value from a string and also convert from a boolean to a string: Int <> Boolean Boolean and Int are also interchangeable. Zero represents a false value, any other value is considered to be true.
Data Types & Signal Flow Int/Float > Poly/Mono A Float or Int can be connected to Poly or Mono inputs. These act like signals that maintain a constant level. You can't however connect a Poly or Mono to a Float or Int. In fact Poly and Mono connectors can only be connected to themselves. MIDI <> String This is not so much a conversion as a handy way to check what MIDI data is coming from a MIDI output. Attach a String data component and note on/off, control change and pitch bend messages etc.
Data Types & Signal Flow Float Array <> String You can easily convert between a string and a float array. String Shortcuts The String data component can be used as a shortcut for defining various GUI data types. Colours, Areas, Pens and more can all be defined in a single text string. Area To create an area use the format "x,y,w,h" where x and y give the top-left corner of the area and w and h give the width and height of the area. All dimensions are in grid squares of course.
Data Types & Signal Flow The colour part is exactly the same as for specifying a colour with a string (see above). The thickness is a floating point number in grid squares. The style can be any one of the following strings: solid, dash, dot, dashdot, dashdotdot You can leave the style parameter out and a solid style will be assumed. Font Fonts can be generated by Strings using the format "typeface,size,style". Typeface is the name of the font face e.g. Arial or Tahoma.
Exporting Exporting CREATING STANDALONE APPLICATIONS 82 of 212
Exporting Creating Standalone Applications FlowBotics Studio can be used to create complete applications that will run on their own. First click the EXE button on the action panel of the module you want to export (or right-click on the module and select Create Standalone from the pop-up menu). The Create Standalone Application dialog will appear. Application Name The application name is the name of the .exe file that will be generated. By default the software will use the module label.
Exporting Full Screen Check this box if you want your application to launch and fill the whole screen. This is the ideal option for applications intended for embedded systems. Include context menu for zoom and exit This option determines whether the default right click menu is present in your exported exe. This menu allows users of the exe to change zoom level, move to full screen and exit the application.. Enable ESC to Quit This option enables the Escape key as a means of exiting your generated exe.
Exporting Library Dependencies On most occasions your exported exe can be distributed on its own. However, some components in FlowBotics Studio are reliant on external libraries. If your project uses these components and you then export to a standalone you will need to distribute the supporting libraries together with your executable. You will be informed of any dependency when you export.
Advanced GUI Editing Advanced GUI Editing THE GUI COMPONENTS AND HOW TO USE THEM 86 of 212
Advanced GUI Editing Module GUI In the Modules chapter we learned how to enable a module’s front panel, add items to it and move them around. We used sliders, knobs and switches from the toolbox. These are themselves modules but their front panels are constructed using GUI components. In this chapter you’ll see how to create your own front panels using the GUI components. Working at this level you have complete control over every detail of how your front panel looks and behaves.
Advanced GUI Editing MGUI Connectors All GUI information is sent through View connectors. These are yellow circles with a V in the middle. The MGUI has one View output. Anything connected to this will either draw onto the front panel or handle mouse messages from it. View – handles all drawing and mouse messages The two Float outputs can be used to get the size of the front panel if this is needed. For the moment you only need to know about the output connectors.
Advanced GUI Editing Coordinate System FlowBotics Studio uses a grid system to position components. Exactly the same grid system is used by the vast majority of GUI components for drawing and for mouse events. The grid system is floating point based so you can have fractions of a grid square. This allows for more precise positioning of drawing elements. Of course there's no getting away from the fact that the screen uses pixels and that these form a discrete grid of points.
Advanced GUI Editing Drawing This section describes how to draw using the GUI components. With the introduction of the Ruby component you can now also draw using Ruby code. This is now the recommended way of drawing in FlowBotics Studio. For more details see the Drawing section in the Ruby Component chapter. Drawing on a Panel Drawing on a front panel is a simple matter of picking a drawing primitive and connecting the View output of the MGUI to the View input of the primitive.
Advanced GUI Editing Chaining GUI Components Most GUI components have a view output connector. This allows other GUI components to be linked to them so chains of graphical elements can be created. The example below shows how this is done. The effect on the link order is as follows: the link to the red rectangle is taken first followed by any links from it's output connector. Then it's back to the next link from the MGUI etc.
Advanced GUI Editing Mouse Handling This section describes how to handle mouse interaction using the Mouse components. With the introduction of the Ruby component you can now also do this using Ruby code. For more details see the Interaction section in the Ruby Component chapter. Mouse Area In order to receive mouse messages in a part of your front panel you must first define a mouse area. This is done using the Mouse Area component.
Advanced GUI Editing The example below shows how the Mouse Drag component can be used to change the size of a rectangle. We've created our own rectangle module to handle the drawing in this example. This makes the schematic a bit neater.
Advanced GUI Editing Mouse Moves You can also track the mouse as it moves over a mouse area. This is done using the Mouse Move component. Before you can use this you need to enable mouse move messages on the appropriate MGUI component. Mouse move messages are disabled by default to reduce unnecessary performance overheads. Try replacing the Mouse Drag component in the previous example with a Mouse Move component and you’ll see how this works.
Advanced GUI Editing 95 of 212
Advanced GUI Editing Redrawing Redraw Control If you change a property of a drawing element during a mouse operation like dragging, you'll often want the changes to be reflected immediately in the module front panel. To allow for maximum flexibility FlowBotics Studio allows you to control when parts of the front panel are redrawn. In the rectangle dragging example we used the simplest kind of redraw - we just forced the whole panel to refresh. This was done using the Redraw component.
Advanced GUI Editing For this example we've created a module that handles the storage of the old area and it's combination with the new area. This uses an Area Sample and Hold to keep the old Area for when it's needed.
Ruby Component Ruby Component A WORLD OF POSSIBILITIES 98 of 212
Ruby Component Introduction The Ruby component is by far the most flexible component in the FlowBotics Studio toolbox. It encapsulates the full Ruby language, it allows passing of data via an efficient time precise event system and it integrates fully with FlowBotics Studio triggered data types, mouse events and graphics. The Ruby component can be used for anything from simple equations to complex class libraries, user interaction and graphics rendering. It really does open up a world of possibilities.
Ruby Component Inputs and Outputs The Ruby component can interface with most other triggered data types in FlowBotics Studio. By default the component has one String input and one String output. Adding or Removing To change the number of inputs and outputs just click and drag the handles under the bottom most connectors.
Ruby Component Naming It's useful to be able to name connectors, not only for readability (so it's clear what the data represents) but also because in the case of input connectors the label can be used within your Ruby code as a variable or as a reference to an input. There are two ways to add connector labels. First you can right-click on the connector and then click the N button.
Ruby Component Code Editor Basics The code editor is where all the action happens. This is where you type in your Ruby code, have it process the input data and send any results to the output(s). The editor has syntax colouring to make code more readable. It supports all the operations you'd expect including cut, copy and paste (CTRL+X, CTRL+C and CTRL+V), automatic scroll bars and mouse wheel scrolling. A local undo is also implemented to allow you to undo and redo typing, deletions, pastes etc.
Ruby Component As you can see, the error message is displayed in red to differentiate it from evaluated output. Note that the error messages come directly from the Ruby interpreter. They can sometimes seem unrelated to the error. However, the Ruby Component evaluates your code while you are typing so if an error does pop up you'll know exactly what change caused it. One final thing worth mentioning is the output pane only shows the value of the very last evaluated expression.
Ruby Component Input Data Data that arrives at a Ruby component is stored in an instance variable called @ins. This is a Ruby array and it stores the last value to arrive at each input. You can look at this by simply typing it into the component. Note that instance variables are coloured gold in the code editor. To access the value at any input use the Ruby Array element reference []. Values are zero indexed so to get the value at the second input use @ins[1].
Ruby Component Note that output is not a keyword, it's a method of the RubyEdit class. Usually you would invoke a method on an object. However, in the case of the Ruby component all code is evaluated in the context of the RubyEdit instance that represents it. You could just as easily write self.output and you'd get the same result.
Ruby Component This can be very useful if you have events data running at a high rate and you want to read it via triggered data at a lower rate. The example above shows a Tick25 being used to read the output at 25Hz regardless of the rate of change of the value inside the Ruby component.
Ruby Component The event Method As we mentioned earlier, the Ruby Component evaluates your code as you type. If your code contains expressions (as opposed to declarations or definitions) then these are executed and the last result is displayed in the Output pane. Outside of the editor your code will also execute whenever data arrives at an input. This allows you to use the Ruby component for data processing.
Ruby Component We have added overrides of the standard comparison operators to the RubyEditConnector class which means that as well as comparing with integer values in the event method you can also compare directly with a string. The previous example showed how it can be used to compare with an integer. Comparing with a string (if you have a label for the connector) is just the same: Comparison will work in case statements too. You can also use any of the inequality operators.
Ruby Component Scheduling Events You may recall from the Data Types and Signal Flow section that, unlike triggered data which is sent immediately, event data can be scheduled to be sent at some time in the future. To do this a schematic has a clock. The clock is an elapsed time, in real world seconds, which begins when the schematic is loaded or created. The clock does not represent a time of day, it is simply a counter which continually increases.
Ruby Component The above example creates a counter that moves in one second steps and continues without end. Note that, just like for the output method, you can use a connector label instead of an index to identify where you want to send a value to. Scheduling Methods You can also schedule method calls using the scheduleMethod method. scheduleMethod methodName, arg1, arg2, … , time Where methodName is a string specifying the name of the method, arg1, arg2 etc.
Ruby Component Ruby Values Earlier in this guide we talked about the Ruby Value connector type. This is used to pass data from one Ruby component to another. It's a very simple concept but as you'll see, it's also incredibly powerful as it gives you the flexibility to define and use your own data types. We'll start with a quick reminder of what a Ruby Value is. The Ruby Value Type In Ruby all data is considered to be an object.
Ruby Component Of course you can be even more clever than that. In the previous example we were passing a Ruby Hash. However, we can pass anything we like. So we could create our own class with its own data and pass that. This next example shows a RobotArm class designed to model a multiple link robot arm. This is getting quite advanced now but you can see that the options for extending the types of data passed around are almost limitless.
Ruby Component Persistence The Ruby component saves its state. If you save a schematic with a Ruby component in it then when you load it back the @ins and @outs arrays are restored to exactly how they were before. This ensures that the component maintains its state at all times. The only exception to this is bitmaps. Because bitmaps can be very large these are not automatically saved as part of the input and output arrays.
Ruby Component If you have multiple values you want to save and restore then the easiest way to deal with these is to put them in an Array and return that in saveState. Let's say you have variables @x, @y, @name. Here's some example code that would save and restore these: In loadState we use Rubys syntax for assigning variables to consecutive elements in an array.
Ruby Component Debugging FlowBotics Studio is designed to make programming easier. However, it can never be foolproof and so at some point you are bound to find yourself facing bugs which have you scratching your head. This aim of this section is to provide you with information, hints and tips that will hopefully make the debugging process much less of a headache. Error Reporting The first thing you need to know when you have an error is where it is.
Ruby Component The example below shows how the mouse coordinates can be watched as the cursor moves across the View (not that this requires mouse move messages to be enabled on the MGUI inside the module – see the Interaction section for more on this). If you just want to quickly see one value in a Ruby Edit then you can omit the string label input. This will show with the label 'Quick Watch' in the output pane.
Ruby Component Drawing As well as handling data the Ruby component can also be used to handle mouse events and draw to a front panel. This section covers drawing and the next handles mouse interaction. To enable your Ruby component to draw to a front panel you need to add a View input connector and then link this to a View output connector from an MGUI (either directly or by a series of links) or from a Wireless Input that connects to a front panel in a module above.
Ruby Component Drawing Units Before we begin we should quickly talk about the units of measurement we use for drawing. Because all drawing in FlowBotics Studio is scalable we work in grid step units and not in pixels (see the Coordinates section in the chapter on Advanced GUI Editing). All coordinates, measurements and sizes are in grid steps. If you ever need to know the size of a grid square you can call the gridStep method on the View object at any time.
Ruby Component Basic Shapes You can draw a number of different basic shapes using methods of the View class. They all take a drawing instrument (either a Pen for outlines or a Brush for fills) and then a number of other parameters to define position and size. The parameters are usually points, collections of points or rectangles. These are represented by Ruby arrays. A point is represented by a two element array with the first element being the x coordinate and the second being the y coordinate.
Ruby Component The drawCurve method can take two additional forms: drawCurve instrument, points, tension drawCurve instrument, points, offset, segments, tension The tension input determines the curvature. A value of zero will produce straight lines, a value of 0.5 will produce curves at the standard curvature and increasing tensions will produce more curvy lines. The offset value determines the point at which drawing will begin and the segments input determines how many segments of the curve are drawn.
Ruby Component addArc rect, startAngle, sweepAngle addCurve points addBeziers points addLines points Note that when you add line elements, consecutive lines will automatically get joined at their end and start points. You can then call the closeFigure method to make the end of the last line join with the start of the first to form a closed shape. The addCurve and addClosedCurve methods can also take the same optional input parameters that the drawCurve and drawClosedCurve methods take.
Ruby Component The first two inputs are the same as for the isVisible method. The pen input defines the pen that the path would be drawn with. The point is then tested to see if it would lie on the drawn path. Obviously the wider the pen, the more likely this is. The return value is either true or false. Text You can draw text to a View using the drawString method. However, before we talk about this you're going to need to know about two other drawing classes.
Ruby Component Here's an example: The StringFormat object can be replaced by nil in the drawString method call should you wish to go with the default alignment of top-left. Measuring Text Sometimes you need to be able to measure how much screen space a block of rendered text will occupy. For this purpose there is the measureString method: measureString text, font, stringFormat, location The input parameters are the same as for the drawString method.
Ruby Component Specifies that parts of characters are allowed to overhang the string's layout rectangle. By default, characters are first aligned inside the rectangle's boundaries, then any characters which still overhang the boundaries are repositioned to avoid any overhang and thereby avoid affecting pixels outside the layout rectangle. An italic, lowercase letter F ( f) is an example of a character that may have overhanging parts.
Ruby Component drawBitmapSection bitmap, source, position [, alpha, rotation, origin] The 'bitmap' parameter is the bitmap you want to display. In the case of drawBitmapSection the 'source' parameter is a 4 element array representing the rectangular section of the bitmap that you want to display. The rectangle array is defined by [x,y,w,h] where x,y define the top-left and w,h define the size of the section in pixels.
Ruby Component getInterpolationMode mode Redraw If values changes in another method which affects what should be displayed by the draw method then you need to be able to request a redraw. This is very easy to do. All you do is call the redraw method. If you have more than one View connected to your Ruby component then you should also provide the input connector reference of the View you want to redraw as an input parameter to the redraw method.
Ruby Component To reset the clipping region just call resetClip or you can also pass nil as the region for the setClip method. The getClip method will return an array representing the bounding rectangle of the current clip region in the format [x,y,width,height]. Smoothing By default all graphics are smoothed. The otherwise sharp jagged edges around graphics objects are antialiased to make them appear smooth.
Ruby Component getViewSize connectorReference You need to pass the index of the View connector that you want to query (or you can leave it blank and zero will be assumed). The method returns a two element array containing the width and height. In the example below we've pressed the trigger button and the event method has been called triggering the call to getViewSize and the result is then displayed in the watch list. If you don't have a View connected then the call to getViewSize will return nil.
Ruby Component Advanced Brushes The Drawing section covered how to create a solid brush and use it to fill basic shapes or draw text. In this section we'll look at more advanced brush options. Linear Gradients You can create filled areas that flow smoothly between colours using the LinearGradientBrush class. This is a variation on the standard Brush class and can be used as an instrument for drawing in all the shape drawing methods just like the standard Brush.
Ruby Component translateTransform x, y scaleTransform sf-x, sf-y resetTransform The rotation method takes an angle in Degrees. The translate method takes x and y offsets. The scale method takes x and y scale factors – these are floats with 1.0 meaning no change. The resetTransform method does exactly what it says, it resets any applied transforms. The example below shows a gradient that has been stretched and translated. Blending You don't just have to have a straight gradient.
Ruby Component This is all best illustrated with an example. The picture below shows a gradient with three blend points in between the end points which themselves are set to zero (ie. color1): You can also introduce a whole range of colours into the gradient using the setInterpolationColors method. This is very similar to the setBlend method except that instead of a blend factor you have a Color object paired with the position along the gradient.
Ruby Component Path Gradients Path gradients provide another way of producing smooth transitional fills between different colours. Unlike the LinearGradientBrush they create a radial gradient from a central colour out towards a set of surrounding colours. The surrounding area is defined by a path and colours can be distributed along the path. A single central colour is also defined and the colour gradient is calculated by blending outwards from the central point.
Ruby Component Wrapping In a similar way to the LinearGradientBrush a PathGradientBrush has a bounding rectangle which contains the whole path. This makes the brush into a tile. The tile can then be used repeatedly to pave any area that is painted with the brush. Unlike the LinearGradientBrush, the default for the PathGradientBrush is to not tile or clamp. You can change this by setting the wrap mode using the setWrapMode method.
Ruby Component Both methods take two inputs. The first is the focus. This is a float between 0 and 1 which defines the relative distance of the end point colour from the start point. A value of 0.5 would put it bang in the middle for example. The second parameter is the scale. This is also a float between 0 and 1 and it defines the intensity of the colour at the focus point. Here's an example of these in action.
Ruby Component This is all best illustrated with an example. The picture below shows a gradient with three blend points in between the end points which themselves are set to zero (ie. color1): You can also introduce a whole range of colours into the gradient using the setInterpolationColors method. This is very similar to the setBlend method except that instead of a blend factor you have a Color object paired with the position along the gradient.
Ruby Component Centre Point By default the centre point is calculated for you based on the path. However, you can set the position of the centre point yourself using the setCenterPoint method. setCenterPoint x, y All you need to do is pass the x and y coordinates of the point you want to have as the new centre. The example below shows a displaced centre point being used to create a 3D effect by creating the illusion of reflected light from a ball.
Ruby Component Focus Scales By default the centre colour is focused at the centre point. However, you can change the focus size around this point by using the setFocusScales method. setFocusScales scaleX, scaleY The method takes two scale factors. These are applied to the path that defines the brush and the resulting shape defines the area that is filled with the centre colour. Scale factors of 1.0 will make the whole shape the focus colour so most of the time the scale factors you use will be less than 1.
Ruby Component The hatch style strings are as follows: "HORIZONTAL" "NARROWHORIZONTAL" "VERTICAL" "DARKVERTICAL" "FORWARDDIAGONAL" "DARKHORIZONTAL" "BACKWARDDIAGONAL" "DASHEDDOWNWARDDIAGONAL" "CROSS" "DASHEDUPWARDDIAGONAL" "DIAGONALCROSS" "DASHEDHORIZONTAL" "05PERCENT" "DASHEDVERTICAL" "10PERCENT" "SMALLCONFETTI" "20PERCENT" "LARGECONFETTI" "25PERCENT" "ZIGZAG" "30PERCENT" "WAVE" "40PERCENT" "DIAGONALBRICK" "50PERCENT" "HORIZONTALBRICK" "60PERCENT" "WEAVE" "70PERCENT" "PLAID" "75PERCENT" "DIVOT" "80PERCENT
Ruby Component Texture Brushes A TextureBrush is defined by a bitmap. When you fill an area with a TextureBrush the bitmap is used repeatedly to tile the area you want to fill. You can create an instance as follows: b = TextureBrush.new bitmap The bitmap input parameter needs to be a Bitmap object. You need to pass a Bitmap object into your Ruby component so that you can use it in your TextureBrush. The example below shows how a TextureBrush is created and used.
Ruby Component The example below shows the four different wrap modes in action. Transformations You can rotate, translate or scale a TextureBrush after it has been created. To do this you use the following methods: rotateTransform angle translateTransform x, y scaleTransform sf-x, sf-y resetTransform The rotation method takes an angle in Degrees. The translate method takes x and y offsets. The scale method takes x and y scale factors – these are floats with 1.0 meaning no change.
Ruby Component Advanced Pens The Drawing section we covered the very basics of Pens. In this section we'll look at Pens in more detail and show you some of the more advanced things that you can do with them. Pen Alignment By default lines drawn with a pen are centred. This means that if you have a thicker pen then part of the pen will fall on either side of the line. Sometimes this is not the behaviour you want so you can change it using the setAlignment method for the Pen.
Ruby Component setLineJoin type The method takes a single input.
Ruby Component Dashes Pens can be set to draw broken rather than solid lines. Y can do this using the setDashStyle method of the Pen object. setDashStyle type The method takes a single input.
Ruby Component Here's an example showing how the round and triangle options work: Brushed Lines We've seen how it's possible to fill a shape using a brush. Well you can also use a brush to fill a line drawn with a pen. To do this use the setBrush method of the Pen object. setBrush brush The input is a brush object. You can use any kind of brush, gradient, hatched, texture, path or solid.The example below shows two lines being drawn with hatch and texture brushes.
Ruby Component “square”, “round”, “triangle”, “noanchor”, “squareanchor”, “roundanchor”, “diamondanchor”, “arrowanchor” Here is an example that shows how to use line caps: Scaling Line caps are scaled automatically in proportion to the line thickness. This scaling can make it difficult to achieve the style you're looking for. For example, if you create a single pixel thickness line with an arrow end cap the arrow will be just 2 pixels wide.
Ruby Component Custom Line Caps If you want to create your own custom line caps then you can do this using the CustomLinecap class. You create an instance of this class the use it to set the start or end cap for the pen. Before you can do any of this you will need to create a GraphicsPath object. This will define the shape of the line cap. You create a graphics path in the same way as usual. The units are still grid squares, however the coordinate system is relative to the line.
Ruby Component Scaling The custom line cap scales proportionally to the pen size. The default is for this to scale 1:1. You can change this by using the setWidthScale method of the CustomLineCap class. Setting this to 2 for example, would make the cap be double the size it would be normally at whatever pen width. The width of the pen used to stroke the path would also be double the pen width.
Ruby Component Interaction In the previous section we saw how you can draw to a front panel using a Ruby Component. In this section we'll talk about handling mouse events from a front panel. You'll need a View input set up in exactly the same way as for the drawing. Alternatively, if you just want to handle mouse event input you can create a Mouse connector instead of the View. The way you handle events within the Ruby component is exactly the same in both cases.
Ruby Component The example above shows how the mouse cursor changes to the default 'hand' to indicate that interaction is possible. In this case we've elected to handle mouse events regardless of where the mouse pointer is in the View. However, you could use the x and y position to return a different result depending on whether the mouse is in a particular area or location.
Ruby Component Mouse Capture & Dragging If you want to handle drag operations, where the user clicks, holds then moves the cursor, you will need to capture the mouse. To do this you call the captureMouse method. This should be done in response to a mouse down event. Now, so long as the mouse button remains down FlowBotics Studio will look for a method called mouseMoveCaptured in your Ruby component. If it exists it will be called each time you move the mouse.
Ruby Component Space “Space” Return / Enter “Return” or “Enter” Arrow Key Up “Up” or “Arrow Up” Arrow Key Down “Down” or “Arrow Down” Arrow Key Left “Left” or “Arrow Left” Arrow Key Right “Right” or “Arrow Right” Mouse Move If you want to capture mouse movements when no mouse buttons are pressed then you first need to to enable this on the MGUI component you're connecting to. By default mouse move messages are suppressed in order to improve performance.
Ruby Component 1 or “ibeam” 2 or “pointer” 3 or “handpointer” 4 or “move” 5 or “pointeradd” 6 or “pointerdel” 7 or “smallpointer” 8 or “resizeew” 9 or “resizens” 10 or “handopen” 11 or “handclosed” 12 or “crosshair” 13 or “deny” 152 of 212
Ruby Component Controls and Dialogs There a few user interface elements that we use Windows controls and dialogs for. We have primitives for these but when you're programming an interface using Ruby components it's far easier to be able to access them from with your code. This section describes these elements and how to use them. In Place Edit Controls Edit controls are pretty much essential for gathering precise numerical or text input.
Ruby Component Drop Lists For selecting from a discrete list of options we have the drop list control.
Ruby Component Message Boxes It's useful to be able to provide warnings when performing unrecoverable actions or to ask a user for confirmation. This is where message boxes come in.
Ruby Component 156 of 212
Ruby Component Sounds FlowBotics Studio has a comprehensive signal processing engine for handling sound. Using this you can do just about anything you want from an audio perspective. However, sometimes all you want to do is play a sound. So to save you having to bother with the audio engine we have provided a simple way to play a sound from within your Ruby code. You do this using the playSound method. Playing This method takes a path to the sound file that you want to play.
Ruby Component Utility Methods Currently we only have one utility method that doesn't fit into any of the categories above and that's the schematicLocation method. You can use this method to give you the path to where the current schematic is located. In exported exes it will give you the location of the exe.
Ruby Component External DLLs You can call functions in external DLLs from inside your Ruby code. This is done by making use of the Ruby Win32API extension. All you do is create an instance of the Win32API class that has all the information about the function call you want to make. You then execute the Win32API call method to execute the function. All very straightforward. Let's take a look in detail about how this is all achieved.
Ruby Component This is the name of the function you want to call. It must be exactly as it is written in the dll and is case sensitive. inTypes This defines the number of inputs to the function and their types. Each parameter is represented by a single character. You can use a Ruby array with each element as a character ( e.g. ['I','n','c'] ) or you can use a string ( e.g. “inc” ).
Ruby Component This will show a message box whenever the trigger button is pressed. The input parameters to the MessageBox call are parent window, message, title, type. Notice that the message and title are passed as strings. You don't need to do any packing. We use 'p' in the input types because these strings are char* values, not constants. Here's one final example. This shows how to retrieve a string value from a function call.
Ruby Component MIDI When you send MIDI data to a Ruby component it is represented by an instance of the MIDI class. Using Ruby you are then free to process this MIDI object in any way you like. You can create new MIDI objects and you can send objects out of the Ruby component to play a synth in your schematic or somewhere else. Reading MIDI Objects The MIDI class is a very straightforward. A single instance of the class represents one individual MIDI message.
Ruby Component When a MIDI object containing sysex arrives at a Ruby component you can look at it using the to_array method. This will give you a Ruby array containing two entries. The first is the sysex hex data string and the second is the number of hex bytes in that string (as each byte is two characters this number will of ocurse be half the length of the string). The above example shows how to look at the data in a system exclusive message. You can see the array with the hex data as the first entry.
Ruby Component The example above will play a middle C at full velocity lasting a quarter of a second whenever you press the trigger button. We need to make use of the optional time input to the event method here. This gives us the current time and we schedule the 'off' MIDI event to be sent at time now + 0.25 seconds. MIDI System Exclusive To create a MIDI sysex message you simply provide the sysex string to the new method. The following example shows how you do this.
Ruby Component Frames FlowBotics Studio processes high data rate signals such as audio using Streams. These allow you to perform one-sample-at-a-time processing at rates of 44.1Khz and beyond with minimal compromise in performance. Frames allow you to process this data via the Ruby component without losing a single sample. Because of the high data rates involved you can't do this processing one sample at a time – the processing overhead would be way too much.
Ruby Component Writing Samples In the same way that you can read a single sample you can also write to a single sample: myFrame[i] = 3.0 – assigns 3.0 to the sample at index i in myFrame If you want to assign an array of Ruby Floats to a Frame then you'll need to create a new Frame object. Here's how you do it: f = Frame.new smpls – creates a new Frame from the array called smpls Frame To Mono The Frame To Mono component takes Frames and passes them back into the Mono stream.
Ruby Component Frame Sync If you just want to generate a signal then you don't need the Mono To Ruby component, you just need to generate Frames from your Ruby component and pass them to the Frame to Mono. However, what you do need is a way to sync the Frame output with the Mono stream and also a way of finding out the required frame size. This is where the Frame Sync component comes into play. The example here shows a generated sine wave.
Ruby Component Processing Frames in a DLL You can process Frames in an external DLL. This is useful if you need maximum performance or if you have existing algorithms written in another language that you want to make use of. To show you how this is done we've created a function, written in C, for a simple delay effect and put this in an external DLL.
Ruby Component To call this from FlowBotics Studio we need to use a Ruby component and the Win32API class. See the earlier section on External DLLs for more information about using Win32API. We use a circular buffer for the delay and this together with the current buffer index needs to be managed on the FlowBotics Studio side. For the buffer we use a Frame object. You can see from the C code of the external DLL that the function is called delayFrame and it takes 5 ints followed by two pointer inputs.
Ruby Component Ruby Limitations Our main aim for Ruby in FlowBotics Studio was to provide a scripting mechanism that binds tightly into our graphical programming environment and allows you to do things that were not possible before or were very difficult previously using graphical programming techniques. Ruby integration brings a massive number of benefits but this is Ruby within FlowBotics Studio and as such there are some limitations when compared with using pure Ruby via text files and the command line.
Ruby Component Declaration Persistence The Ruby interpreter is running constantly. Because of this any declared classes, global or instance variables and constants will remain declared even if you delete the code for them. Currently the only way to flush all the declarations is to save your schematic and restart FlowBotics Studio. Gems All seasoned Rubyists will know about Gems. These are packaged libraries of code that you can install and use to extend Ruby beyond its standard capabilities.
Ruby Component Ruby DLL Ruby functionality is provided by an external DLL. This dll is called msvcr90-ruby191.dll. In order to use this with FlowBotics Studio it has to be compiled using Microsoft Visual Studio 2008. To comply with the Ruby licence agreement we provide details here of how to build it. Changes We have made no changes to the Ruby source that change the way that the Ruby interpreter functions. However, we have added a small section of code into eval.
DSP Code Component DSP Code Component THE ULTIMATE LOW-LEVEL DSP TOOL 173 of 212
DSP Code Component DSP Coding For most tasks, FlowBotics Studio's graphical programming approach meets your needs nicely. However, when it comes to programming DSP a more algorithmic approach is required. For this purpose we have the Code Component. Using the code component you can do any kind of processing you like. The component uses a very small set of commands to allow you to translate DSP algorithms into very simple code.
DSP Code Component Syntax Colouring The editor colours the code to indicate correct syntax. Input/Output commands, operators and brackets are purple, variables are blue and data types and functions are green. If at some point the syntax colouring stops and all text after that point turns black, this is an indication that there is an error in the syntax at that point. Editor The code editor supports copy and paste through the standard shortcut keys (CTRL+C, CTRL+V).
DSP Code Component Assignments Having set up your inputs, outputs and local variables you can then move on to implementing your DSP algorithm. To assign a value to a variable or to send it to an output, use the equals operator =. You can assign fixed values or you can use a regular expression to calculate the value. The example opposite shows how you can combine all the elements discussed so far to create a simple moog filter.
DSP Code Component % > >= < <= & Calculates the remainder after dividing the left-hand side by the right-hand side Comparison operators These generate a mask based on the result of the comparison Bitwise AND operator. Use this to apply a mask One limitation of the code component is that you can only have 8 successive operations in an expression. For example, the expression: a = 0+1+2+3+4+5+6+7+9+10; is not allowed because there are 9 addition operations in a row.
DSP Code Component Advanced Features Arrays You can declare arrays in the code component. These act as buffers that you can use for storing past values for example or for using as a lookup table. An array is declared as follows: float buffer[100]; This defines an array called buffer which is 100 floats (4x100=400 bytes) in size. Initialising By default all the entries in the array are set to zero. You have two other options for initialising an array: 1.
DSP Code Component Hop There are some calculations that don’t need to be calculated for every sample, it’s sufficient to recalculate for every 4 th sample say. For this purpose we have the hop command. The syntax for the hop command is as follows: hop(8) { < code in here is executed only for every 8th sample > } Hops must be powers of 2 and the maximum hop length is 4096 so values of 2,4,8,16,32,64,128,256,512,1024,2048 and 4096 are the only acceptable values.
DSP Code Component < code in here is executed only for the first sample > } Stage(2) We'll jump to Stage(2) now because this is the default stage. Any code written outside of a Stage definition is assumed to be Stage(2). Stage(2) code is executed for every sample (including the first) and happens after Stage(0). Stage(1) and Stage(3) These two stages are only used for implementing delays.
DSP Code Component Debugging Using Syntax Colouring We’ve already seen that the first indication you’ll have that your code is incorrect will be a discontinuity in the syntax colouring. The following example shows this. You can see that the colouring stops with the sin function. This indicates that there is something wrong with the expression. Sure enough we forgot the ‘1’, the line should read: a = sin1(in); If we make this correction everything becomes coloured correctly.
DSP Code Component 182 of 212
DLL Component DLL Component THE ULTIMATE IN FLEXIBILITY AND PERFORMANCE 183 of 212
DLL Component Introduction The DLL component allows you to call your own custom code which you write in C/C++ and compile into an external dynamic link library (DLL). The DLL can be kept external to the software or you can choose to embed it directly inside a DLL component so it's completely self contained. This allows you to create your own components which you can easily share with others. You can of course already make your own components from modules in FlowBotics Studio.
DLL Component The Component The DLL component has 6 inputs and 3 outputs initially. The Dll and Func inputs are for the path to the dll and the name of the function you want to call. The Embed input determines whether the dll is left external to the software or whether it is to be embedded into the component. The 3 boolean outputs will indicate whether the inputs that lie opposite them have succeeded.
DLL Component We add the connectors in pairs in order to keep things simple and also because for Ruby Frame types you must have a matching input and output. You still have all the flexibility you need. If you need an input but not an output, just ignore the corresponding output and vice-versa. Connector Types The DLL component supports 9 FlowBotics Studio data types: Float, Int, String, Float Array, Int Array, String Array, Boolean, Bitmap and Ruby Frame.
DLL Component The DLL Now that we've looked at the component let's turn our attentions to the dll. As you've seen, the DLL component calls a particular function in your dll. This function must have a very specific declaration which goes as follows: extern "C" __declspec(dllexport) void myFunction( int nParams, int* pIn, int* pOut ) nParams tells you how many parameters are being passed. This is equal to the number of inputs you created on the DLL component.
DLL Component Ints Say we have a DLL component where input 'x' has been defined as an Int connector.
DLL Component { } delete *((char**)&pOut[x]); pOut[x] = 0; // Create new string (assume we have declared 'length' – add 1 for null terminator) char* s = new char[length+1]; // {initialise the string here} // Don't forget to null terminate s[length] = 0; // Assign to correct entry in the output array *((char**)&pOut[x]) = s; If you're using the same length string each time then you could create it once and save having to delete and make a new one each time.
DLL Component int size = *((int*)pIn[x]); int* array = (int*)pIn[x]+1; You can see that we interpret the first entry as an int giving us the array length. The array itself then begins at the second entry, hence the '+1'. To set the output value we need to create a new array. The management of memory is up to you.
DLL Component // Create new array (assume we have declared 'length' – add 1 for size at front) char** array = new char*[length+1]; // Set the size *((int*)array) = length; // Create the strings in the array for( int i=1; i
DLL Component To set the output value we need to create a new byte array. Again, this is very similar to the arrays and strings.
DLL Component Also, for most of the types you should always check that pIn[x] or pOut[x] are zero before attempting to extract values using the above casts so the macros incorporate this check too which reduces crashing.
DLL Component Example 2 – String Uppercase This example takes a string and makes it uppercase. There's a bit more to it in that you need to manage the memory for the output string that holds the result.
DLL Component pData[i] = (mix)*pBuffer[ctr] + curr; pBuffer[ctr] = pBuffer[ctr]*feed + curr; if( ctr >= delay ) ctr = 0; } GETINT(pOut,4) = ctr; } } } } 195 of 212 ctr++;
DLL Component Connecting Once you have built your dll it's time to connect to it from FlowBotics Studio. Drag in a DLL component and connect Strings to specify the dll path and function name. Connect Boolean components to the first three outputs so you can check that the component is communicating with your dll. The first two should read 'true' if the dll and function have been found. If they read 'false' then check carefully the path and function and make sure they match your dll.
DLL Component That's it! Click the trigger button and your dll will process the inputs and send any result out. A note about Outputs As we saw in the previous section the array of output data is populated in your dll code. Anything you put there will be accessible from the outputs on the DLL component. However, how and indeed whether the outputs send out this data depends on which Exec input you use to invoke the call to your dll function.
DLL Component 198 of 212
DLL Component Debugging Working at such a low level, it's inevitable that you will run into bugs at some point. Thankfully most compilers will allow you to attach to the FlowBotics Studio process so you can step into your code and see where any crashes are occurring. The next section describes how to do this in Visual Studio. Debugging using Visual Studio To debug your dll using Visual Studio: 1. First run FlowBotics Studio and open the schematic which you are using to connect to your dll. 2.
DLL Component 4. 5. From the process list select FlowBotics Studio and click 'Attach' Visual Studio will now attach to FlowBotics Studio. You can set break points in your dll code then trigger the Exec input on the dll component inside FlowBotics Studio and Visual Studio will stop execution at the break point you have specified. You can now step through your code, trap crashes and browse variables in the usual way.
DLL Component If the dll is used by other DLL Components in your schematic then it will be released from those too. However, it won't release if you have other schematics open that have locked it or if other DLL components in the same schematic are continuously triggering the Exec input. Once the dll has been released you can rebuild it and then re-trigger the Exec input to see the results of your changes. In this way you can rapidly run through the code – test – debug cycle.
DLL Component Sharing The main advantage of the DLL Component is that it allows you to create your own components without compromising on performance safe in the knowledge that any trade secrets are kept hidden from the world. All you need to do is wrap your DLL Component in a module. There are then two ways you can share your new modules with others. Share the DLL Separately Simply share the dll and your schematic with the module in it.
DLL Component CONS Larger files – because the dll is stored in the schematic the file size will be larger. No Debug – once embedded you can't debug the dll code (not usually an issue when sharing though). No shared Globals – you can't create global data to share amongst calls from different dl components.
Options Options CUSTOMISING THE APPLICATION 204 of 212
Options The Options Dialog There are a number of application and schematic level options/features that you can change in order to make the software work the way you want it to. You can get at these by going to the Options menu and selecting one of the seven categories under which the various parameters are organised. Application These options apply to features and settings that apply at application level. Startup Options By default the software will load up the example file that ships with the software.
Options Thankfully you can switch this off. You can choose between the software launching with a blank schematic (the fastest way to load up) or the schematic that you were working on last time you closed down. If you double-click on a file in Explorer it will usually open in FlowBotics Studio for editing. However, you can choose to have double-clicked files open in Focus Mode and run the schematic as if it were an Exe.
Options Navigator Performance When you change a front panel item like a knob or a slider this often results in values changing in other parts of your schematic. Any modules that are shown in the navigator will be updated to reflect these changes. On some PCs this can be very slow. You can therefore choose how often the Navigator updates. The default is for minimal updates and often this is all you need.
Options Toolbox Adaptive Scrolling Enabling this option makes the toolbox scrolling amount adapt to the speed at which you move your mouse wheel. Move the wheel slowly and you'll get small movements. Move it quickly and the toolbox scrolls rapidly, building momentum as it goes. When you stop scrolling the toolbox will slowly brake to a halt. You can control how quickly or slowly the toolbox braking is applied.
Options Schematic Mouse Behaviour When drag selecting you can choose whether components will become part of the selection once they are fully enclosed in the drag rectangle or when they touch some part of the area covered by the drag rectangle. You can decide whether a right-click brings up the standard context menu or if moves you up to the parent when inside a module. Zoom Level The default zoom level is defined as a number of pixels.
Options Properties By default a module’s properties panel will close as soon as you click away (provided it isn’t pinned open). You can switch this off so that the properties remain open until you close them. Export Target Folders When you export standalone exes they are saved to a particular folder. You can set this here. SSE/2 Support The PC on which you generate your exports may support SSE2 or it may just support SSE.
Options Advanced R&D Components We will periodically offer some components on a trial basis to gather feedback or for testing. You can decide whether to show these components by checking the box. Link Curvature When you bend links they take a curved form. You can decide how curved you want them to be from highly curved to perfectly straight lines. Note that this affects the way that links look in any schematic you open.
Options SSE/2 Support The PC on which you create your schematics may support SSE2 or it may just support SSE. When you save a schematic the software saves code that is optimised for the SSE capabilities of your own PC. If you then give the schematic to someone whose PC has different SSE capabilities from you the software needs to make adjustments on loading so that the schematic will work. These adjustments can slow down the loading process.