[Done] Idea: Generic Synth Mapper

Yo!

So, my brain can’t really can’t stop working on the “synth mapper” tool idea.

The idea is to make a general tool for controlling synths via midi/sysex (synths that allows you to do this via midi/sysex).

It should gives the user:

  • a UI with sliders and switches that control all the parameters of the synth
  • the ability to load/save tones/patches (+ share online?)
  • the ability to midi-map each parameter in renoise
  • some more cool integration with Renoise, effect commands, automation etc

It should be simple to create mappings for new synths, so that almost anyone can contribute.

(I’m not an english speaking person, is “mapping” the correct word at all?)

So, please provide feedback and suggestions.

First, I need a name for it. The name “Guru” appeared in my head. i kinda like it.

I need examples of synths you want to control. And I need a link to a manual or other page with the midi specs.

These I know of:

  • Roland JX8P/XP10/MKS70
  • Roland Juno 1/2
  • Roland Juno 106

So, about creating mapping for a synth. I’ve been thinking about making it as .lua files that are bundled with the tool.

XML has been suggested, but I’m not sure how to implement it as such, and I’m thinking you need more control over functionality for special cases, and maybe control over the layout, the UI can’t be too generic. Some scripting aces will have to help me out. I will get back with details on this…

Later
CB

This is a great idea for a tool.

It would come in extremely handy - and I know I would use my hardware synths in greater extent if I had this.
Sysx can be a real hassle for me, since I have to exit and re-enter Renoise for each synth bank change for many of my synths because I need to free up a midi driver for an external sysx librarian…

Anyway, I hope this tool-project will be realized.

GURU seems like a good name B)

I would love to see support for these:

Roland JV-1080
manual: http://www.synthman.com/cgibin/x.cgi/roland/support/manuals/JV-1080_OM.pdf)

Korg Mikrokorg XL
manual: http://www.google.no/url?sa=t&rct=j&q=korg%20mikrokorg%20xl%20midi&source=web&cd=1&ved=0CDAQFjAA&url=http%3A%2F%2Fwww.korg.com%2Fservices%2Fdownloads%2Fpdf%2FmicroKORG_XL_OM_E1.pdf&ei=kZlxT5H6GbPT4QTthaGNDw&usg=AFQjCNHu9A_TXMEZdQ9ktyhmjQsxvgwgjA&cad=rja

Korg Poly-800 mkii
manual: http://www.soundprogramming.net/manuals/Korg_Poly800II_Manual.pdf

Roland D-10
manual: ftp://ftp.roland.co.uk/productsupport/D-10/01_D-10_OM.pdf

I’m currently trying to voice a few problems (without much luck) when using programs/patches with external synths together with Instr. MIDI Control devices… as the mapped sliders send out CC on startup, overwriting the program/patch:


A tool like you’re suggesting could certainly be a way to solve this problem. I don’t know much about coding but I’d be happy to help out with mapping and stuff for the gear I got. Here are MIDI specs for my most used gear for starters:

DSI Tetra: http://www.davesmithinstruments.com/downloads/tetra/doc/Tetra_Manual_v.1.3.pdf (page 47)
MFB-503: http://www.mfberlin.de/Manual/M503_M.pdf
Mssiah (C64 cartridge): http://www.mssiah.com/files/MSSIAH_MonoSynthesizer.pdf (page 49)

I have two hardware synthesizers at home, which I currently barely use, but would love to use more, if patch/settings management would be
easier in Renoise:

Waldorf Blofeld: Waldorf Blofeld Manual

DSI Evolver: DSI Evolver Manual

I would gladly help testing of course!

I may assist with any specific queries, but I don’t have any hardware to test such a tool. However, I wish you the best of luck with it.

A suggestion: For maximum flexability, you will probably want to write a framework (similar as was created for Duplex). Then you can define hardware (why limit it to synths…) with XML. For example:

  
<control name="Filter Cutoff" type="midi_cc" param1="72"><br>
<control name="Bank select" type="nrpn" param1="22," param2="23"><br>
<br>```

<br>
<br>
The above is crappy example XML but hopefully gets the idea across.<br>
<br>
<br>
<br>
[quote="Cornbeast"]<br>
Sysx can be a real hassle for me, since I have to exit and re-enter Renoise for each synth bank change for many of my synths because I need to free up a midi driver for an external sysx librarian...<br>[/quote]<br>
<br>
If you are only receiving and transmitting midi dumps try the <a href="http://www.renoise.com/tools/sysex-librarian">SysEx Librarian tool</a>.<br>
<br>
I hear it's quite good <img src="https://files.renoise.com/forum/emoticons/default/tongue.gif" class="bbc_emoticon" alt=":P"></control></control>

Thanks mxb, will definitely check this out, nice work.

Yes, that’s great idea for a tool.
I would probably plug my waldorf micro-q again! :)

The manual on waldorf web site does not contain any information on sysex AFAIK, but I can send you some pdf by pm if you want.

I would go with lua files too. Lua is really great to describe data (it’s one of its design goal). This is simpler to implement (using loadfile), and it would probably be simpler to write mappings (without any external tools). And as you said, one could easily embed some logic in the mapping file, which would be hard to achieve with pure XML.

Allright, sounds like christmas eve in here!

Thanks for the loadfile tip, didn’t know of it, looks useful.

CB

Would be great :)
i could help you with testing on Access Virus C and microwave xt

Hello

So, I’ve been banging my head now against some lua mysteries.

I’m thinking; how would one like to define each synth as a lua file, well, like for example ViewBuilder. For example:

  
mapper = GuruSynthMapper()  
x = mapper:synth_definition{  
 name = "Synth X",  
 mapper:parameter_group{  
 name = "DCO 1",  
 mapper:parameter{  
 name = "Waveform"  
 },  
 mapper:parameter{  
 name = "Range"  
 }  
 }  
}  
  

Right? Better suggestions?

So, how then is ViewBuilder implemented?

ViewBuilder seems to be a class, and text, slider etc are functions. You call the class ViewBuilder like a function ().

I’m not bright enough to figure out if there’s a way to get the source or more info about ViewBuilder, so can anyone shed light on this.

CB

This is a simple lua syntactic sugar: when you call a function with only one argument and this argument is a table, you can omit the parenthesis.

So your example is the equivalent of:

  
x = mapper:synth_definition ({  
 name = "Synth X",  
 mapper:parameter_group ({  
 name = "DCO 1",  
 mapper:parameter({  
 name = "Waveform"  
 }),  
 mapper:parameter({  
 name = "Range"  
 })  
 })  
})  

You just have to implement methods for GuruSynthMapper. Each method then look for specific keys in its only argument (the table).

I have waldorf micro q, its will be great. http://www.waldorfmusic.de/en/archiv/micro-q-series/downloads.html

Sorry if this thread went knee deep in lua

Now I did something like this.

Is this sane or not in a lua world?

First some classes (do i even need to do it like classes?)

  
class 'synth_definition'  
function synth_definition:__init(tbl)  
 self.name = tbl.name  
 self.children = tbl  
end  
  
class 'parameter_group'  
function parameter_group:__init(tbl)  
 self.name = tbl.name  
 self.children = tbl  
end  
  
class 'parameter'  
function parameter:__init(tbl)  
 self.name = tbl.name  
 self.children = tbl  
end  
  

And then the .lua file for a synth def which are opened with dofile:

  
return synth_definition {  
 name = "Roland JX-8P",  
 parameter_group {  
 name = "Group 1",  
 parameter {  
 name = "Param 1.A"  
 },  
 parameter_group {  
 name = "Group 1.2",  
 parameter {  
 name = "Param 1.2.A"  
 },  
 parameter {  
 name = "Param 1.2.B"  
 },  
 parameter {  
 name = "Param 1.2.C"  
 }   
 },  
 parameter_group {  
 name = "Group 2.2",  
 parameter {  
 name = "Param 2.2.A"  
 },  
 parameter {  
 name = "Param 2.2.B"  
 },  
 parameter {  
 name = "Param 2.2.C"  
 }   
 }   
 }  
}  
  

So then I managed to recursively go trough each .children table and create a viewbuilder ui with columns and text items printing the .name of each class.

You could define them as simple functions instead of classes, and return tables instead of objects, the difference is very thin (objects are tables).

With classes you can easily use inheritance, so this is probably simpler. (You can use delegation with tables too, but this involve playing with metatables…)

Actually its the shit. Thanks again for this tool, mxb.

Could you give me an example of this, from code i wrote?

Bear with me, this is a bit confusing since you seem to be able to do virtually anything with a table.

At first i did like this:

  
super = {  
 sub = {  
 }  
}  
  

but then I couldn’t have two occurances sub, since its adding the key [“sub”] to super i guess.

CB

Yes, Lua tables are a very powerful and elegant data structure, but the first contact might be a bit tough.

I highly recommend reading the parts of “Programming in Lua” about data structures, and also this part about persistence which describes a data format similar to what you want (except its really simple and flat).

Remember that you don’t need a key name when constructing tables. For example:

  
super =  
 {  
  
 param_group = "LFO",  
  
 {  
 param = "Rate",  
 sysex = "...",  
 },  
  
 {  
 param = "Shape",  
 sysex = "...",  
 },  
  
}  
  

Construct a table, which contains 3 elements. One is stored at the key “param_group”, and the two others are anonymous, they are store with numerical index. You can access them with super[1] and super[2]. You can query the number of (numerically indexed) elements with #super. If that helps, you can think as if tables had two parts: one traditional array, and one dictionary.

But I think your first approach, with classes, was nice. You can easily attach methods to each type of parameter, and use inheritance. If you want to use pure tables, you’ll have to deal with metatables to do this, which is a bit tougher (but really fun – depending on your definition of fun).

Thanks, got the hang of it now after a bit reading and experimenting.

Here’s a table alternative of the thing i did with classes:

  
function synth_definition(tbl)  
 tbl.type = "synth_definition"  
 return tbl  
end  
  
function parameter_group(tbl)  
 tbl.type = "parameter_group"  
 return tbl  
end  
  
function parameter(tbl)  
 tbl.type = "parameter"  
 return tbl  
end  
  
synthDef = synth_definition{  
 name = "My synth",  
 parameter_group{  
 name = "Paramgroup A",  
 parameter{  
 name = "Param A1"  
 },  
 parameter{  
 name = "Param A2"  
 }   
 },  
 parameter_group{  
 name = "Paramgroup B",  
 parameter{  
 name = "Param B1"  
 },  
 parameter{  
 name = "Param B2"  
 }   
 }   
}  
  

So, I’m adding .type in the functions, so that when i iterate trough my table I can know what a certain table is, for example a “parameter_group”. To know what UI element to render etc…

With the class example i accomplished the same thing by checking if the type(xxx) were equal to a certain class.

So, basically the same thing. I cant decide which one is better. The table one is more standard lua, but the classes are nice…

Another advantage of using classes is that you can add method to them, and use polymorphism (aka function overloading) instead of iterating through the table and checking the type. Also, using an OO paradigm in Lua is pretty standard, the Renoise API just added a few convenient features (like the “class” keyword), but everything else is in the language.

Hmm, not really following you there :-/