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…
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.
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:
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:
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>
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.
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…)
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:
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.