Menu

Home

bruno

Open Source Nord Modular G2 Editor

This page is under construction!

The Clavia Nord Modular synthesizer comes as a keys version:

fig1

and a rack version:

fig1

It has DSP chips, which you can program in the style of an analog modular synthesizer, but using pc software. Here is a screenshot of the original software for the NMG2:

fig1

This project aims to offer an alternative for the original clavia nmg2 editor.

There's really nothing wrong with the Clavia software, it still works perfectly on all the latest windows and mac os systems. The only problem is that the G2 synthesizer is not made anymore and also there's no active development of the software.

I own a G2 rack model, and because I'm interested in software development and I missed the functionality of the keys version to have more physical interaction with the synthesizer I started to develop some software utilities for my rack model. Then I found a world of technical information about the G2 on the electro-music forum and also a lot of helpful an enthousastic people there. One thing led to another, and eventually I found myself developing an open source editor for the G2.

Here you find the software I've developed so far. I hope, by putting it all on sourceforge, it will be of use for anyone interested in the G2, or in software development. I also hope there will be people willing to contribute to the development of G2 software in any way posible.

So here is the same patch in the open source editor.

fig1

The editor looks a bit different than the original, that's because it's not finished yet of course ;) but also because I'm not really interested in making an exact copy of the original. It's far more interesting to explore what can be done with an open source editor, that can make this synthesizer modular on more levels than one:

  • The editor can be part of a network of musical applications, for example a vst that runs in a DAW and an editor on a mobile device and another application that keeps the actual usb connection with the hardware
  • By putting the functionality into components, it's possible to make all kinds of editors or applications for the G2. If you don't like this open source editor, you could make you own using the components, or make something else like a patch mutator.
  • The editor could be made for all kinds of existing or future operating systems, maybe using the Delphi code I've developed until now or else by porting it to another language. That's always more easy than building it out of nothing.

Architecture

The software is set up as a client-server system, one element of the system, the server, has an usb connection to the G2 hardware. Then, using tcp-ip, multiple clients can connect to the server. The clients could be other editors, or vst's.

The main reason for this setup is for the vst. It is nice feature to have a vst for the G2 that you can use in your Daw, for automating things but also to be able to save a patches/performances with your Daw project.

It's a problematic to have the Vst itself connect to the G2 hardware over usb. It's possible but the problem is that (as far as I know at least) it's not possible to share the usb connection over multiple applications. So if you had this Vst running, and you wanted to change something in the patch, you would have to close the vst, start the editor, make the change, close the editor and start the vst again.

With the client-server setup, this is not necessary. Before you start the vst, you would start the editor that makes the usb connection to the G2 hardware and is also acting as the server. The Vst connects to the editor as a Tcp-client. Now you can use both simultaneously. For example, you want to add a parameter to automate in the daw, you would assign the parameter in the editor to the global parameter pages. The knob assignment shows up in the vst automatically, so you could start to automate it in your Daw.

This setup allows for other configurations also, for example, you could have the editor running on a mobile device that is a tcp-client to an editor on a fixed computer somewhere that has the usb connection with the G2 hardware.

Requirements

For end users:
  • Windows XP and upwards
  • a G2 synthesizer (hardware)
  • Libusb-win32 generic usb driver (which you can download from sourceforge)
For developers:
  • Delphi 2007 or later
  • or Lazarus/FPC
  • Indy10, necessary for the client-server system
  • Libusb-win32 generic usb driver

Installation for end users:

Installing the usb driver:
  1. First you have to download libusb-win32. Go to the libusb-win32 sourceforge page and download the latest snapshot.
  2. Here comes the important part: make a restore point of your system, so you can go back to your old setup if something goes wrong.
  3. Then, if you have the original Clavia usb driver installed, you have to install the libusb-win32 driver as a filter driver on top of the original Clavia driver. Now you can still use the original Clavia software but also use the open source editor!
Installing the editor:

Next thing is to copy the files and folders in the "Build" folder, somewhere on your drive, renaming the Build folder to, for example "nmg2edtor". The file structure inside this folder should be kept the same as in the original "Build" folder, because the editor expects certain files and folders to be present relative to it's own location.

Installing the VST:

The Vst dll should be copied to your Steinberg or vst Folder. Then you have to copy these two files into the same folder:

  • ModuleDef.xml
  • ParamDef.xml

These files contain all the module and parameter properties. The Vst loads these files when it is started in your Daw.

Example working with the editor and vst:

So now I would like to show how the editor and vst could work together. A complete manual of the editor and vst might be available somewhere in the future. For the editor at least, many things in the original NMG2 manual also apply to the open source editor, for example the shortcut keys should be the same in both applications.

The reason for giving this example is to explain some of the inner workings of the editor and the vst, so when you should encounter a problem, and chances are you will, then you might be able to make a better bug report.

When the editor is started, it follows a certain starup sequence.

  1. The first thing the application does is looking of the libusb driver. If it doesn't find one, an error message is shown and the application will not start.
  2. Then it will look for "module_map.bmp" in the folder "Img". This is a bitmap with the icons for all the modules.
  3. Next it will try to load the "G2_editor_ini.xml" file. In this file all the form positions are stored and some other application settings, like ip settings and so on. When it doesn't find this file, no problem, it will use the defaults.
  4. The application waits a few miliseconds, then it will try to load the "ModuleDef.xml" file and the "ParamDef.xml" file. These files hold information about modules and parameters, like names, high values, low values, number of connectors, number of parameters and so on for every module and parameter type.
  5. Then the application will try to make an USB connection to the G2. If it finds one, it will start three threads:
    1. an USB message send thread
    2. an USB message receive thread
    3. a TCP server thread
  6. Then it will start an USB message exchange with the G2, to synchronise all the data in the editor with the data in the G2. That is for example the synthesizer settings, the performance settins, all the patch data held in the 4 slots, the knobs, the global knobs, the controller assignments and so on
  7. For every module that the editor has to show on the screen, it loads and parses the module panel definition file, located in the "Modules" folder.

If all goes well, the editor ends up with your default performance loaded. In my case it's a single module:

fig5

You can view the log file, that will give a detailed log of the messages send to the G2 and received, you can imagine I've spend a lot of time there hunting for patch load errors :( But I think a solved most of them now.

Anyway, if something goes wrong, you might get some info from the log. Of course, writing this log makes the editor respond a bit slower, but as this is a beta version, having the log info is more important. You could turn it of by checking off "Log messages" in the main application.

fig5

Adding modules is done with the a right mouseclick. The popup menu shows the module icons that mentioned earlier.

fig5

I added an ADSR envelope here. You will notice that the modules do not show all the info yet that the original editor does. The display only shows values from 0 - 127, in stead of note values and there are no graphical displays yet to show for example the ADSR envelope. These are examples of things that remain to be done, by me, or maybe by you ;)

fig5

So I go on adding modules and drawing cables between connectors, maybe add bit of color here and there hoping to make an interesting fm base sound. Of course I'm only starting to learn patching, if you want to see and hear some real great patches for the G2, you should visit the electro-music forum.

fig5

I'm saving the patch. At the moment it's not possible to edit the name of the patch in the editbox directly, that's one of these things that remains to be done. However, if I save the patch and then load it again, it shows the patch filename in the edit box.

fig5

Now I'm going to start the DAW, which is Ableton in my case. The G2 VST is showing in the Plug-in devices window. It is named "g2_vst_2011" at the moment.

fig5

This is what my VST folder looks like, apart from the g2_vst_2011.dll and another vst, there are also two xml files that the VST loads when activated : "ModuleDef.xml" and "ParamDef.xml", these files are required for the VST.

fig5

I can drag the VST to an audio channel, it will be activated then and try to load the two xml files. Then it will try to establish a TCP connection with the editor. If all goes well, the vst will show up. It basically consists of the global parameter pages.

fig5

The VST holds a copy of all the patch data, so when it start's up, it exchanges a series of messages with the editor, acting as the server. These messages are the same as the ones that are exchanged between the G2 hardware and the editor when it is started up.

The end result is that the G2 hardware will hold patch data, the editor holds a copy of this patch data and the VST holds a copy.

From now on, all changes that are made in the patch data have to be synchronized between these two applications and the G2 itself. That is the job of the editor acting as the server. All messages pass through the server and the server will on the one side update the G2 over USB and on the other side will broadcast the messages to all connected clients.

Back to the VST, one of the mayor benefits of the VST is that it can store it's internal data into the Ableton project. So when I save the project now, it will save the patch data with it.

fig5

So when close Ableton and initialize the slot in the editor. Then start Ableton again and load the project, the patch that was saved in the project shows up again in the editor!

Now I'll show how you can automate the parameters. For example, if I want to automate the FM amount of OscB, I have to assign it to a global knob. It will then automatically show up in the VST.

fig5

Then you can set the VST in ableton to "Configure" mode, now when you wriggle the knob a bit, it will add the parameter in the VST panel.

fig5

You can also add parameters for the variations the same way.

fig5

There are 120 knobs in the global pages 8 knobs, 3 page columns and 5 pages. Added to that are the variations for the 4 slots, so I've defined a total of 124 possible parameters in the VST.

Now I'll do some more things in the editor to show some other features. First I make a copy of variation one to variation two.

fig5

Next I activate the "Edit all" button on the panel strip of slot "A". I select morph knob "Keyb" and set a morph amount on the release knob of the ADSR.

By activating the "Edit all" button, I can set this morph value to all 8 variations at once.

fig5

(...)

Installation for developers:

  • install the libusb-win32 driver as a filter driver on top of the original Clavia driver
  • download and install the Indy10 library into your Delphi IDE, if not already present
  • download/checkout the source code and put it somewhere on your disk, keeping the folder structure intact
  • install the NMG2Controls package into your Delphi IDE

Description of files and folders:

  • Build : This is the folder where all the compiled files and binaries are located. Here are also located the module and parameter database files.
    • Dcu : This folder is where the compiled units go
    • Img : Folder for icons and pictures
    • Modules : Folder with the module panel data, for each module a text file describing the panel layout. The editor loads and parses these files when a module is added in a patch.
    • Win32 : Default folder that Delphi creates for windows 32bit applications
    • G2_editor_ini.xml : Ini file for the G2_editor application, as a xml file
    • ModuleDef.xml : Module properties : names, connectors, parameters etc. Both the editor and the vst load this file on startup
    • ParamDef.xml : Parameter type properties : names, high value, low value etc. Both the editor and the vst load this file on startup
    • ...
  • Project : This folder holds all the project files
    • DelphiFMX : Delphi XE2 Firemonkey project. This project is in an experimental stage right now. With the firemonkey framework both Windows and Osx applications can be made. At the moment I have some performance issues with this the firemonkey scrollbox.
    • DelphiVCL : Delphi VCL holds the projects based on the traditional Delphi visual component libraries. Only for Windows. These projects are in a beta phase of developement.
      • G2_editor_D2007... : The editor project files for the Delphi2007 compiler
      • G2_editor_D2011... : The editor project files for the DelphiXE2 compiler
      • G2_server_D2011... : Experimental project, only a server no editting, for DelphiXE
      • G2_vst_2007... : The VST project files for Delphi2007
      • G2_vst_D2011... : The VST project files for DelphiXE
      • NMG2_controls_D2007... : The G2 components package project files for Delphi2007
      • NMG2_controls_D2011... : The G2 components package project files for DelphiXE
      • Test_vst_D2011... : VST Test application for DelphiXE
    • FPC : I also started a Free pascal/Lazarus project for developing the editor for use in Linux. I got the editor and usb interface working, problem is a buggy scrollbox component (again), so I've stopped developing it for the moment. The source code probably won't compile now, because I neglected to keep it up to date while developing the VCL, so some work has to be put into this to get it working again.
      • G2_editor... : The editor project files for FPC/Lazarus
      • nmg2_controls.... : The G2 components package project files for FPC/Lazarus
  • Source : This folder holds the source code
    • NMG2Controls : Folder with the units for the G2 components: the base code
      • delphi_version.inc : Include file that has some compiler version definitions.
      • fastbitmap.pas : a unit that I've compiled and extended from various internet sources, for fast rendering of anti aliased lines and circles, for use with VCL components or Freepascal components.
      • graph_util_vcl.pas : some VCL only utility functions
      • LibUSBWin.pas : The header file for the libusb-win32 driver, by Yvo Nelemans that I've made unicode compliant.
      • libusb.pp : The header file for the libusb1.0 driver for unix and Freepascal
      • g2_database.pas : unit contains some wrapper classes to read/write xml files
      • g2_file.pas : a big unit, containing all the chunk definitions of G2 patch and performance files. Here all the base classes for the G2 components are defined.
      • g2_mess.pas : Here functionality is added to the file components to code and decode G2 usb messages in order to change/modify patches.
      • g2_usb.pas : In this unit functionality is added to the mess components to send/receive messages over usb or tcp-ip. Here also the client-server functionality is implemented
      • g2_graph.pas : here functionality is added to the usb components to render them on the screen. I've put the graph components low in the hierarchy because VCL components are basically not thread safe, so in the vst, I only use usb components.
      • g2_classes.pas : here the final components are defined for use in a G2 application. Not much functionality is added here.
    • OSC : Utility library to encode/decode osc-packets, downloaded from DelphiOSCUtils at Github. I've made some arrangements in the code in order to use this, but it should be developed further.
    • VST : Folder with the sources to build the VST, based on Tobybears VST Template
    • XML : Folder with the sources to read and write XML files, taken from FPC and modified to work with unicode.
    • .pas and .dfm files : These are the sources and form definition files that make up the G2 editor.
  • Wiki : Place to put screenshots/images for showing on this wiki page.

Here is a diagram of the most important G2 components:

G2 Components

....

Example of Delphi source code

The editor is written in Pascal, using Delphi 2007 and Delphi 2011. I didn't really consider another development platform because one of my motivations of doing this project was to improve my development skills, and I happen to do my software developing, professionally, with Delphi. In any case, Delphi is a great developing tool.

The main diference between Delphi 2007 and Delphi 2011, is that Delphi 2011 supports unicode. I started the project with Delphi 2007 but somewhere along the way my computer crashed and I took the opportunity to upgrade it to windows 7, and installed Delphi 2011. De source code had to be made unicode compliant, that meant basically that I had to replace the datatype "String" with "Ansistring" and "Char" with "Ansichar" and "PChar" with "PAnsiCHar". I did that not only in my own source code , but also in some of the supporting units that I got from other sources (XML units from Freepascal for example).

Delphi is a object oriented language. You build applications by using visual or non visual objects. There come many default objects with Delphi and then there are third party libraries or objects that people share on the internet. You can of course derive you own objects from the standard ones, and that's what I did to make the G2 objects.

Apart from the editor itself, it was my intention to develop some objects with which you could build your own G2 application. These objects are contained in a so called "component package". You can add this package to you Delphi IDE, after which the G2 objects are available on the component palette. I'm not going to explain how you install a component package, you can find that in the Delphi help. The G2 components are contained in the NMG2_controls package.

So I'll show how you could make a simple "off line" G2 application with these components, that way I can give you some insight into the workings of the source code.

TG2

First I start a new VCL project "NMG2_test". You have to set the search paths to point to de NMGControls sources and the XML sources, like so (relative to your project folder):

fig1

With that out of the way you can build the application, first I drop a TG2 object on the form. The TG2 object contains all the functionality for communicating with the G2 hardware.

fig1

On the left side, you have to set a couple of properties for the TG2 object.

  • ClientType : could be ctEditor or ctVST. I made this distinction to be able to filter messages depending on the application type. I don't want to sent led data for example to the vst's.
  • Host : when the application is a client, host specifies the IP of the server application.
  • ID : an unique id (taken from the system timer) for a client, a server application has id = 0
  • IsServer : this indicates if the application is a server or a client. Only a server can have an USB connection to the G2 hardware. Multiple clients can connect to a server. A VST is always a client.
  • LogLevel : gives some control over the amount of log messages that are written to the internal log.
  • LogLines : the internal log.
  • Name : a name for the TG2 object, I changed this to G2 for the example
  • Port : the TCP_IP port over wich clients en server communicate. Must be the same of course for server and client.
  • ScrollboxFX : Here we can select a patching area of the FX section. The scrollbox must be a TGGraphScollbox object
  • ScrollboxVA : Same for the VA section
  • SelectedSlotIndex : the currently selected slot in the G2.
  • Tag : standard Delphi property.
  • USBActive : Setting this to True for a server initializes the USB connection, for a client it initializes the connection to the server (which must itself be active of course).
TG2GraphScrollbox

So in order to be able to make patches, we have to add two scrollboxes and connect them to the G2 object. The TG2GraphScrollbox object is derived from the standard Delphi scrollbox, which in itself is a wrapper around the same windows object. The most important thing that I've overridden in the object is the Paint method, this controls how the child objects of the scrollbox are rendered on the screen.

So you could take a look at the procedure "procedure TG2GraphScrollBox.WMPaint(var Msg: TWMPaint);" in the unit g2_graph.pas:

  • From windows we get the rectangle area that has to be repainted
  • An off-screen bitmap as a canvas to paint on is created
  • First the background is painted on the bitmap, these are the rack rails, but could also be another background image
  • Second the modules that overlap with the rectangular area are painted on the bitmap, the modules paint there own child controls on themselves.
  • Thirthly the cable sections that overlap the rectangle are painted on the bitmap
  • Lastly any dragging outlines that are currently visible are Xored over the bitmap image
    Then the bitmap is copied to the scrollbox canvas.

By using the off-screen bitmap you get a more stable picture. All the child objects of the scrollbox are derived from the standard Delphi TGraphicControl. That is a light weight non - windowed object. These child objects are only painted from within the Scrollbox paint method, so the exact painting order of the objects can be controlled, I always want to have the cables on top for example.

fig1

I've added a property "Location" to the scrollbox, this I've set to ltVA or ltFX for the example.
Now the scrollbox properties of the G2 object can be filled in.

fig1

Now I want to be able to add modules to the patching area. For this simple example, I'll just put an edit box on the form in which you can type the module type id and I add an "OnMouseUp" event to the VA scrollbox.

fig4

In the event handler we write the code to add a module to the appropriate patching area:

fig5

This means that when the right mouse button is pressed in the scrollbox, an "add module" message is send for the selected patch to the G2. This message needs a couple of parameters :

  • Location : ltVA or ltFX
  • ModuleType : the number that is typed in the Edit1 box
  • Col : the module column of the patching area. That is calculated by dividing the mouse x coord by the default module width (UNITS_COL)
  • Row : the module row in the patching area

The constants UNITS_COL and UNITS_ROW are defined in the unit "g2_types.pas", so you have to add this unit to the uses list.

Ok, now I'm going to run the application, I type "4" in the edit box, that's the 2-out module, and I right click in the upper scrollbox. The application responds with an error message: "Module database not loaded".

fig1

Module database files

We provided the "add module" message with 4 parameters, but in the message that is actually send to the G2 some more parameters are needed. Also, the data necessary to be able to paint the module to the screen must be provided. All this is contained in the module database files, these consist of the following:

  • ModuleDef.xml : a xml file containing all the module names, properties parameters and connectors
  • ParamDef.xml : a xml file containing the properties of the different parameter types
  • Modules (Folder): a folder containing a panel layout file for each module type. These are necessary to be able to render the modules on the screen, so this one is not needed for a the current VST application.

These files and the folder must be in the same folder where the application executable resides. So in my case in the NMG2_test\Win32\Debug folder:

fig1

The .dcu fles in the above picture are "Delphi compiled units", you can instruct Delphi to put these in a seperate folder.
Now I have to give the instruction to the G2 object in the Form OnCreate event, to load the module database.

fig1

Now when I run the application I can make a patch:

fig1

Debugging the VST

One nice thing of the Delphi IDE is that it allows for debugging the VST while it is running in Ableton. This is usefull, also to see in general how Ableton handles the VST's. One thing I noticed for example that at startup Ableton loads and unloads all VST's in the VST folder. When one VST fails to load, it will disable that VST.

Also usefull is to see in what order the methods of the VST program are called from Ableton when it a VST is loaded into a project.

To enable debugging, you have to set the host application to point to Ableton in the Delphi project options.

fig1

You would also set the build output folder of the project to the Ableton VST folder.

Now when you can start the whole thing by running the project in Delphi in Debug mode. It will start Ableton, the when you drag the VST to an audio channel, you can debug it in the the IDE.

fig1

Project Admins:


MongoDB Logo MongoDB