New Tool (2.8): Guru

Guru is a Renoise tool for editing sounds on external hardware synthesizers via midi.

Guru provides a generic user interface for editing all the parameters of a synth. All parameters are midi assignable in Renoise, so they can be mapped to a midi controller.

The patches created using Guru can be saved as files, so you can save you own preset sounds and share with others.

Latest version:

Note! Updating will delete files that are not supplied with the tool, including synth definitions you are working on (that are not included with Guru yet), so make sure you backup you work first

Documentation:

2 Likes

hmm, what would it take to offer presets, for like, f.ex., alphajuno2? ;)

Yo! I plan to make some presets :-), just havenā€™t got the time. And if anyone makes a synth mapping I will include it with the tool, and offer it to download aside as well.

But itā€™s really really simple.

For Juno 2:

http://www.vintagesynth.com/roland/sysex.php

10 VCF Cutoff (0..7F) F0 41 36 00 23 20 01 10 00 F7  

The values in that table are hexadecimal, and you want it to be decimal. So go here: hexadecimal conversion, convert decimal to hexadecimal

10 = 16. 16 is the number.

  
return SynthDefinition {  
 name = "Roland Alpha Juno 1, 2 & MKS-50",  
 author = "Cornbeast [cornbeast@cornbeast.com]",  
 sysex_message_start = {0x41, 0x36, 0x00, 0x23, 0x20, 0x01},  
 Container {  
 name = "VCF",  
 Parameter {  
 id = "vcf_cutoff",  
 name = "VCF Cutoff",  
 number = 16  
 }  
 }  
}  
  

Cheers

Great. You put this together faster than I figured out how Ctrlr works. :)

Iā€™ll try to make a mapping for the DSI Tetra.

Getting an error message when installing:

ā€˜C:\Users\Dby\AppData\Roaming\Renoise\V2.8.0\Scripts\Tools\com.cornbeast.Guru.xrnxā€™ failed to load.

Please remove this tool or contact the author (Cornbeast [cornbeast@cornbeast.com]) for assistanceā€¦

cannot open C:\Users\Dby\AppData\Roaming\Renoise\V2.8.0\Scripts\Tools\com.cornbeast.Guru.xrnx/synthdefinitions/example_synth_def.lua: No such file or directory
stack traceback:
[C]: in function ā€˜dofileā€™
main.lua:61: in function ā€˜read_synth_definitionsā€™
main.lua:50: in function ā€˜initā€™
main.lua:88: in main chunk

Any suggestions on how I could map Oscillator shape in a nice way that donā€™t screw up MIDI mappings. Itā€™s one parameterā€¦ 0 = Osc off, 1 = Saw, 2 = Tri, 3 = Saw/Tri mixā€¦ and 4-103 Pulse wave, width 0 - 99. I usually just map a single slider, but it would be nice if there was five buttons and a slider for pulse widthā€¦ But Iā€™d still like to be able to map to one MIDI knob. Any ideas? Iā€™ll just make a single slider for now.

Hmm, looks like I got the path wrong. But it works for me on Win 7. What OS are you using?

Iā€™m on Vista 32-bit.

Hmm, tricky, but not impossible. Letā€™s figure something out.

One simple but ugly solution would be to have one knob with values 0,1,2,3 and a slider with values 0-100 and then add the ability to let one value sent be two values added to eachother. So, knob = 3 + slider = 50 = 53. But the ugly part is, if button = 2 and slider = 50 = 53, then it would not be Tri, but Pulse.

So, Iā€™m thinking about adding the ability to attach functions in the definitions, so that you can do your own logic for special cases. Still not sure how this would look, but something like this maybe:

  
Container {  
 Parameter {  
 id = "osc_waveform_switch",  
 number = 55,  
 items = {"Off,"Saw","Tri","S/T mix","Pulse"},  
 value_function = function(value){  
 if (value > 2) then  
 return value + some_way_to_reference_other_param_values("osc_waveform_slider")  
 end  
 return value  
 },  
 },  
 Parameter {  
 id = "osc_waveform_slider",  
 number = 55,  
 max_value = 100,  
 value_function = function(value){  
 if (some_way_to_reference_other_param_values("osc_waveform_switch") > 2)  
 return value + some_way_to_reference_other_param_values("osc_waveform_switch")  
 end  
 return some_way_to_reference_other_param_values("osc_waveform_switch")  
 },  
 }  
}  
  

Damn, and here I was thinking this tool would open up a window where a Guru could speak cryptically to me about how to finish my song. ;)

1 Like

Hmm, ok, if you have scripting enabled, please try to modify the path for the function that tries to load the file to have backslashes.

Here you see, its on line 58: http://code.google.com/p/stepbrother/source/browse/trunk/Guru%20xrnx/com.cornbeast.Guru.xrnx/main.lua

Sorry, this guru can only speak cryptically to other synths :wink:

This should do:

local folder_path = os.currentdir() .. "synthdefinitions"  

os.currentdir() will always return a path with a trailing slash on all platforms.

Amazing work, btw!

Roger that, will fix tonite.

Thanks!

Oh, and by the way, what security considerations are there to take into account here.

The code in a lua file read in and executed can do really malicious stuff, right? Or are there limitations for the tools?

Iā€™m thinking about maybe making online sharing of synth defs, maybe downloadable via the tool. If so, I need to manually approve all the submissions. Probably a good idead anyway, but Iā€™m just thinkingā€¦

Nice work! My waldorf microQ needs a new power supply, but if I get it to work Iā€™ll try to contribute a mapping for it.

Using setfenv, you can limit which lua functions are available to the definition files. If you set it to a table containing only your functions/classes, then I donā€™t think anything malicious is possible.

Very strange bug, after instal this script, rigth now dont work any funktuon in the prefernce when i clic select audio card roll, roll fast close and i do not select item. and dont work in the pattern selected area when I hold objects do not transfer.

osx 64 bit

I have made some progress, but I donā€™t understand what I should enter after ā€œsysex_message_start =ā€

I didnā€™t think I needed it since itā€™s all NRPN so far, but I get an error on startup:

.\class_synthdefinition.lua:11: SynthDefinition.sysex_message_start is missing  
stack traceback:  
 [C]: in function 'assert'  
 .\class_synthdefinition.lua:11: in function <.><br>
  [C]: in function 'SynthDefinition'<br>
  ....cornbeast.Guru.xrnx\/synthdefinitions/dsi_tetra.lua:1: in main chunk<br>
  [C]: in function 'dofile'<br>
  main.lua:61: in function 'read_synth_definitions'<br>
  main.lua:50: in function 'init'<br>
  main.lua:88: in main chunk<br>
<br>```

<br>
<br>
The DSI Tetra manual has this on sysex:<br>
<br>

```<br>Sysex Messages<br>
Universal System Exclusive Message (Device Inquiry)<br>
Status Description<br>
1111 0000 System Exclusive (SysEx)<br>
0111 1110 Non-realtime message<br>
0vvv vvvv If MIDI channel is set to 1-16, 0vvvvvvv must match (unless MIDI Channel<br>
= ALL); always responds if 0vvvvvvv = 0111 1111.<br>
0000 0110 Inquiry Message<br>
0000 0001 Inquiry Request<br>
1111 0111 End of Exclusive (EOX)<br>
Tetra responds with:<br>
Status Description<br>
1111 0000 System Exclusive (SysEx)<br>
0111 1110 Non-realtime message<br>
63<br>
0vvv vvvv If MIDI Channel = ALL, 0vvvvvvv = 0111 1111. Otherwise 0vvvvvvv =<br>
Channel Number 0-15.<br>
0000 0110 Inquiry Message<br>
0000 0010 Inquiry Reply<br>
0000 0001 DSI ID<br>
0010 0110 Tetra ID (Family LS)<br>
0000 0001 Family MS<br>
0000 0000 Family Member LS<br>
0000 0000 Family Member MS<br>
0jjj nnnn Main Software version: jjj ā€” Minor rev; nnnn ā€” Major rev<br>
0000 0000 Zero Byte<br>
0000 0000 Zero Byte<br>
1111 0111 End of Exclusive (EOX)<br>
<br>```

<br>
plus some about data dumps.<br>
<br>
And this might be related?<br>

```<br><br>
Packed Data Format<br>
Data is packed in 8 byte ā€œpacketsā€, with the MS bit stripped from 7 parameter<br>
bytes, and packed into an eighth byte, which is sent at the start of the 8 byte<br>
packet.<br>
Example:<br>
Input Data Packed MIDI data<br>
1 A7 A6 A5 A4 A3 A2 A1 A0 1 00 G7 F7 E7 D7 C7 B7 A7<br>
2 B7 B6 B5 B4 B3 B2 B1 B0 2 00 A6 A5 A4 A3 A2 A1 A0<br>
3 C7 C6 C5 C4 C3 C2 C1 C0 3 00 B6 B5 B4 B3 B2 B1 B0<br>
4 D7 D6 D5 D4 D3 D2 D1 D0 4 00 C6 C5 C4 C3 C2 C1 C0<br>
5 E7 E6 E5 E4 E3 E2 E1 E0 5 00 D6 D5 D4 D3 D2 D1 D0<br>
6 F7 F6 F5 F4 F3 F2 F1 F0 6 00 E6 E5 E4 E3 E2 E1 E0<br>
7 G7 G6 G5 G4 G3 G2 G1 G0 7 00 F6 F5 F4 F3 F2 F1 F0<br>
                            8 00 G6 G5 G4 G3 G2 G1 G0<br>
This explains why it takes 293 MIDI bytes to transmit 256 Program data bytes.<br>
<br>```

</.>

Agwwfff midi is the worst mess Iā€™ve ever seen. But we will get trough this.

Try setting mode to NRPN and see if this works:

  
Parameter{  
 id = "filter-frequency",  
 name = "Filter frequency",  
 type = "nrpn",  
 number = 215,  
 max_value = 164  
}  
  

See manual section under NRPN / Program Parameter Data for more parameter numbers / values

But you need to uncomment line 21 in class_parameter.lua :slight_smile:

And youā€™re right sysex start should not be needed there, just enter anything for the time beingā€¦

Ok, I just copied the line from the example file, and now it opens. Looks ok. Lets see if I can get it to communicate with the Tetra.

I have been defining all NRPNā€™s.

I donā€™t understand what I need to uncomment, sorry. :huh:

This is what I got so far:

  
return SynthDefinition {  
 name = "DSI Tetra",  
 author = "DBY",  
 sysex_message_start = {0x41, 0x36, 0x00, 0x21, 0x20, 0x01},  
 Container {  
 name = "DSI Tetra",  
 style = "panel",   
 Container {  
 name = "OSC",  
 Container {  
 name = "OSC 1",  
 Parameter {  
 id = "osc_1_freq",  
 name = "Frequency",  
 type = "nrpn",  
 number = 0,  
 max_value = 120  
 },  
 Parameter {  
 id = "osc_1_freq_fine",  
 name = "Fine Tune",  
 type = "nrpn",  
 number = 1,  
 max_value = 100,  
 default_value = 50  
 },  
 Parameter {  
 id = "osc_1_shape",  
 name = "Shape",  
 type = "nrpn",  
 number = 2,  
 max_value = 103  
 },  
 Parameter {  
 id = "osc_1_glide",  
 name = "Glide",  
 type = "nrpn",  
 number = 3,  
 max_value = 127  
 },  
 Parameter {  
 id = "osc_1_key",  
 name = "Key Track",  
 type = "nrpn",  
 number = 4,  
 items = {"Off","On"},  
 max_value = 1  
 },  
 Parameter {  
 id = "sub_osc_1",  
 name = "Sub OSC",  
 type = "nrpn",  
 number = 5,  
 max_value = 127  
 }  
 },  
  
 Container {  
 name = "OSC 2",  
 Parameter {  
 id = "osc_2_freq",  
 name = "Frequency",  
 type = "nrpn",  
 number = 6,  
 max_value = 120  
 },  
 Parameter {  
 id = "osc_2_freq_fine",  
 name = "Fine Tune",  
 type = "nrpn",  
 number = 7,  
 max_value = 100,  
 default_value = 50  
 },  
 Parameter {  
 id = "osc_2_shape",  
 name = "Shape",  
 type = "nrpn",  
 number = 8,  
 max_value = 103  
 },  
 Parameter {  
 id = "osc_2_glide",  
 name = "Glide",  
 type = "nrpn",  
 number = 9,  
 max_value = 127  
 },  
 Parameter {  
 id = "osc_2_key",  
 name = "Key Track",  
 type = "nrpn",  
 number = 10,  
 items = {"Off","On"},  
 max_value = 1  
 },  
 Parameter {  
 id = "sub_osc_2",  
 name = "Sub OSC",  
 type = "nrpn",  
 number = 11,  
 max_value = 127  
 }  
 },  
 Parameter {  
 id = "osc_hard_sync",  
 name = "Hard Sync",  
 type = "nrpn",  
 number = 12,  
 items = {"Off","On"},  
 max_value = 1  
 },  
 Parameter {  
 id = "glide_mode",  
 name = "Glide Mode",  
 type = "nrpn",  
 number = 13,  
 items = {"Fixed Rate","Fixed Rate Auto","Fixed Time","Fixed Time Auto"},  
 max_value = 3  
 },  
 Parameter {  
 id = "osc_slop",  
 name = "OSC Slop",  
 type = "nrpn",  
 number = 14,  
 max_value = 5  
 },  
 Parameter {  
 id = "pitch_range",  
 name = "Pitch Bend Range",  
 type = "nrpn",  
 number = 15,  
 max_value = 12  
 },  
 Parameter {  
 id = "osc_mix",  
 name = "OSC 1-2 Mix",  
 type = "nrpn",  
 number = 16,  
 max_value = 127,  
 default_value = 64  
 },  
 Parameter {  
 id = "noise_level",  
 name = "Noise Level",  
 type = "nrpn",  
 number = 17,  
 max_value = 127  
 },  
 Parameter {  
 id = "feedback_volume",  
 name = "Feedback Volume",  
 type = "nrpn",  
 number = 18,  
 max_value = 127  
 },  
 Parameter {  
 id = "feedback_gain",  
 name = "Feedback Gain",  
 type = "nrpn",  
 number = 19,  
 max_value = 127  
 }  
 }  
 }  
}  
  

I have set max values, but the sliders still go to 16383.
There is some sort of communication, the sound is changed but not the way itā€™s supposed to.