What’s all this about ?
While using my Shruthi-1s extensively, I came up with some ideas how to make them better fit to my workflow.
Since the firmware can be modified, I’ve started to learn how the Shruthi-1 code works and tweaked it - to success.
The aim of this thread is to
- show how my custom firmware came about
- detail my changes (and archive them for generations to come, hehe)
- show others how firmware mods are possible, often with very little code changes
It’s a bit lengthy, but I’ll hope it gives you some insight.
Part of the story already has been discussed here:
(my god, that was 3 years ago …)
Do I have to be a programming expert ?
Well, not really.
I’ve had some programming lessons in various languages over the years, but mainly forgot all that stuff.
Nvertheless, a basic understanding of programming syntax, expecially object oriented, helps a lot. Those brackets can make you mad.
Other than that, read the code, read the commenting, trace the flow of variables, function calls etc.
Why v0.97?
Well, that’s the one I kinda stuck with.
Works well for me, so why change a running system.
I’m not sure how extensive the “minor bugfixes” in v0.98 are, but I haven’t had any troubly with v0.97 ever.
The thing about v1.01: it misses some key things I need in my scenario
- the performance page
- the sequencer rec mode
Why a custom firmware ?
There’s a certain way that I commonly use my Shruthi-1s.
In that usage scenario, some things can be done easily, some can be done only with a number of operations, which is unhandy in a live/jam situation, some can’t be done.
This is the usage scenario, and the “conflicts” I had with the original firmware:
- The Shruthi-1 plays mainly sequences => always have to set mode to “seq” after start-up
- clock slaved to a MIDIBox Sequencer or Ableton Live => always have to set tempo to "ext"after start-up
- a jam is running - quickly dial-up an already programmed patch&sequence => use “combo” mode, this is luckily an option within the software since v0.92, so no firmware change needed anymore
- quickly get it in tune it (i.e. in semitones) to what’s going on => tricky, could only be done by setting the Oscillators rng parameters, i.e. a lot of navigating a clicking around
- make the patch quickly tweakable => use the performance page, but it requires press and hold of S5, and I get impatient when jamming
- if, for whatever reason, the Shruthi-1 get out of sync, the MBSeq has a “re-sync” function, which sends a MIDI Start at the beginning of the next bar => the Shruthi wouldn’t react to that
- for going bonkers with the sequence, tweak the warp parameter and observe how it changes in the xOx-LED-Mode => can only be observed on performance page, so switching between sequencer and performance (long S5 hold)
This resulted in the following customisations:
C1: Sequence and External Tempo
Resulting from points 1) and 2)
=> have the Shruthi-1 always boot-up with sequencer mode “seq” and tempo set to “ext”
affected file: synthesis_engine.cc
changed:
static const prog_char init_sequence[][
[...]
SEQUENCER_MODE_STEP, 120, 0, WARP_NORMAL,
to:
SEQUENCER_MODE_RPS, 35, 0, WARP_NORMAL,
note: 35BPM is the parameter equivalent of “ext” inside the synthesis engine
C2: The Global Semitone Control
Resulting from point 4) and inspired by a similar control on the DSI Evolver:
=> implement a global control that changes the semitones of both oscillators to tweak the whole Shruthi to the desired key
For this, I hijacked the Octave control and turned it into a +/- 12 semitones control.
affected file 1: parameter_definitions.cc
changed:
// Keyboard and system settings
PRM_SYS_OCTAVE,
-2, +2
to:
// Keyboard and system settings
PRM_SYS_OCTAVE,
-12, +12
affected file 2: synthesis_engine.cc
changed:
range += engine.system_settings_.octave * 12;
to:
range += engine.system_settings_.octave;
C3: The Hardwired Semitone Control
Resulting from points 4) and 5)
=> get quicky to semitone control, i.e. not jumping into seq editing and back
For this, I hardwired the Octave (now Semitone) parameter to the first parameter of the performance page.
Advantage: the performance knobs are already reflected in the load/browse screen, very handy!
affected file editor.cc
changed:
uint8_t Editor::KnobIndexToParameterId(uint8_t knob_index)
if (current_page_ == PAGE_PERFORMANCE || current_page_ == PAGE_LOAD_SAVE) {
subpage_ = engine.mutable_patch()->assigned_parameters[knob_index].subpage;
return engine.mutable_patch()->assigned_parameters[knob_index].id;
}
to:
if (current_page_ == PAGE_PERFORMANCE || current_page_ == PAGE_LOAD_SAVE) {
subpage_ = engine.mutable_patch()->assigned_parameters[knob_index].subpage;
// if the first knob, i.e. knob_index 0 calls, tell it to use the Octave parameter
if (knob_index == 0) { return 44;
// 44 is the Octave parameter
} else {
return engine.mutable_patch()->assigned_parameters[knob_index].id;
}
C4: The Performance Page Shortcut
Resulting from point 5)
I already have the performance page knobs on the load/browse screen, but I can’t see which parameters are set-up.
Instead of press & hold S5 to get to the performance page
=> implement a shortcut from load/browse page to performance page
For this, I hijacked the encoder click function. It leads originally to “Compare”, but I rarely use that.
affected file editor.cc
changed:
void Editor::HandleLoadSaveClick() {
if (action_ == ACTION_LOAD) {
action_ = ACTION_COMPARE; RestoreEditBuffer();
to:
void Editor::HandleLoadSaveClick() {
if (action_ == ACTION_LOAD) {
editor_mode_ = EDITOR_MODE_PERFORMANCE;
JumpToPageGroup(GROUP_PERFORMANCE);
}
C5: The MIDI Re-Sync capability
Resulting from point 6)
=> if a MIDI Start is sent while the sequencer is running, re-start it at the beginning
affected file: voice_controller.h
changed:
static void Start() {
Reset();
active_ = 1;
}
to:
static void Start() {
if (active_) {
Stop(); }
Reset();
active_ = 1;
}
C6: The x0x LEDs Mode in Sequencer Menu
Resulting from point 7)
This was more a fun thing to see how the different warp modes affect the sequence being played back
=> change LED mode in sequencer menu to x0X
affected file: shruthi.cC
changed:
void UpdateLedsTask() {
[...]
if (editor.current_page() == PAGE_PERFORMANCE) {
// x0x-style chasing lights.
[...] }
to:
void UpdateLedsTask() {
[...]
if ( (editor.current_page() == PAGE_PERFORMANCE) || (editor.current_page() == PAGE_SEQ_ARPEGGIATOR) ) {
// x0x-style chasing lights.
[...] }
Conclusion
I’ve developed these mods over a larger timeframe, but in all cases, the implementatation was successful.
My Shruthi-1s run perfectly with that modified firmware and perfectly fit my (jamming) workflow.
Olivier provided some helpful comments for the earlier ones, merci beaucoup!
For the latter ones I finally wrapped my head around how the code works.
I can only encourage everybody interested in modding the Shruthi-1 to fire up a text editor and dive into the code.
Thanks for reading!
Update:
Here’s the code and firmware:
https://github.com/stuartm23/shruthi97_stumod3