- 1 Programming tips and tricks for the Managed Machines in Buzz Build 1416+
Programming tips and tricks for the Managed Machines in Buzz Build 1416+
You should read the documentation given in the BuzzGUI svn here in IBuzzMachine.cs.
In coding Managed Machines for Buzz, there are two elements which can be used for different parts of the same buzz machine. The IBuzzMachine and the IMachineGUI interfaces, the first is the audio handling, and the second is an optional graphical user interface. Buzz will display any parameters and attributes, menu items, and about boxs you set up with the IBuzzMachine, but the IMachineGUI will allow for a custom interface such as the ones in the Jeskola Loop Recorder and NoteMatrix machines.
Equivalence to the old unmanaged machines
If you have already programmed unmanaged machines, using c++ and machineinterface.h, you will find a lot of the set up of the code is now done for you and much has been simplified. The main parts of a buzz machine that remain are Parameter Declaration, Tick, and Work, but they are accessed in different ways.
The MachineInfo data block has been replaced by the MachineDecl attribute of the IBuzzMachine class, and the majority of the old parameter declaration is now in the ParameterDecl attribute, which can be applied to int, bool, and float classes for Global parameters, and to a public method which take one of those classes and a track identifier for Track parameters. The type of class which the parameter uses replicates the switch, byte, word, and note parameter types you are used too; if you want a byte parameter, simply set MaxValue=254 or lower in ParameterDecl for an int.
In addition to this, the Interpolator class has been added which can handle the inertia and scale of parameters for you, as can be seen in IBuzzMachine.cs and the example below.
The code which you would have put in Tick(), handling the new input your machine has been given, should now occur in the YourParameter.set() method for global params and YourParameter(int,int) method for track params.
Work used to have a few different implementations based on the type of machine that you were writing, with mono, stereo, and multio versions. In the managed machines, Work can occur either by sample or by block, and effects and generators define different methods.
Saving and retrieving data from files and templates is considerably simplified, as you will see below. Midi input handling, menu access, and a Stop command are also provided for in the managed machine interface.
Order called of constructors and methods
For a managed machine with a MachineState, global and track parameters, and no GUI.
Create new machine in machine view:
State() YourMachine() YourMachine.Work()
Load from template
State() YourMachine() YourMachine.Work() (multiple) State() MachineState.set YourMachine.Work() (multiple) ImportFinished()
Tick, ie the setting of the parameters for your machine, can be called from ??
Buzz allows your managed machines to save machine specific data in bmx's and templates, and load that data upon bmx or template loading. If you are using peer machines, you will have to handle the possibility of being saved in a template through ImportFinished, but other than this specific case, a State class is used to init, save, and load your data.
As can be seen in example below, the State class is defined as a subclass of IBuzzMachine, and a MachineState property of the State type is the mechanism buzz uses to call your code and serialize it. MachineState.get should save your data into the State class, and MachineState.set must import that data into your machine.
If you are writing a peer or control machine, you must also handle the ImportFinished method to reassign machines when machine names may be changed upon template import or cloning of machines. This provides a dictionary of the old machine names linked to their new names.
You do not need to do these steps when your machine only needs to save the parameters, this is automated by buzz.
TODO: show basic machine, ie gain in example. where IBuzzMachine ends and IMachineGUI starts..
Recommended settings in VC express / VC2010.
Output path for both builds (debug and release) should be in the correct buzz directory, "C:\Program Files\Jeskola\buzz\gear\effects" for effects and "C:\Program Files\Jeskola\buzz\gear\generators" for everything else.
Use "Any CPU" build platform.
Set assembly name to "YourMachine.NET".
Attach to process
In VC 2010 and C#, you can attach your debugger to buzz and then see where bugs are in your code. Start buzz as normal after compiling your managed machine, choose "attach to process" from the debug menu, and select buzz.exe from the window you are shown. Then add your machine to buzz, and you will be able to debug normally.
Launch Buzz from the compiler. (from Ixix's tip)
Attaching to process is useful for finding where the bug is, but it won't allow the "edit and continue" feature in VC2010 or Express, which allows you to fix the bug during execution! So you can use this trick to allow launching Buzz for debugging. (If there's an easier way to do it we'd love to know.)
For Visual Studio C# Express: Edit the solution's startup project file (YourMachine.csproj here) and add this to the first PropertyGroup:
<StartAction>Program</StartAction> <StartProgram>C:\Program Files\Jeskola Buzz\Buzz.exe</StartProgram>
I've also added this to the post-build event for each project...
copy "$(TargetPath)" "C:\Program Files\Jeskola Buzz\"
This can also be done in the full VC 2010, using the project debug properties:
Start external program = "C:\Program Files\Jeskola Buzz\Buzz.exe" Command line arguements = "/nocr" Working directory = "C:\Program Files\Jeskola Buzz\"
Now just hit F5 and it builds, copies the files and launches Buzz all in one step. You can add break points as normal (F9), and you should be able to edit the code when exceptions are thrown, saving you lots of time.