ForkedKlang, experimental 4klang fork

category: code [glöplog]
Here's a modified version of 4klang I've been working on for the past few months. Basically it's a bunch of experimental changes on top of Gopher and pOWL's 4klang.

BB Image

ForkedKlang is based on 4klang 3.0.1, but I've "back-ported" some stuff from 4klang 3.1.1. The reason I chose 3.0.1 and not the newer version was that I had some 3.0.1 songs I wanted to improve, and because the newer version's project file wouldn't work straight away in Visual Studio 2008 Express. And because I felt that I didn't really want some of the new features in 3.1.1 like stereo oscillators.

I've used Visual Studio 2008 Express for development, and the YASM assembler which is able to create working debug symbols for the asm source.
As testing VST host I used Ableton Live 9.

If you're looking for a precompiled plugin DLL, it's in the source\ForkedKlangVSTi\win\Debug folder.

I made ForkedKlang, because there were things in 4klang I wanted to fix or add, and I wanted to do some fun coding and hacking. The whole thing is a big pile of hacks, and I've been learning 4klang's structure as I've gone.
There are bugs and incomplete features, so don't depend on ForkedKlang for your next release. Basically, if you encounter problems, you need to fix them yourself. :) I've tested it on my own songs and it's been working for me.

Particularly, the code produced by ForkedKlang is probably much larger than it has to be. I have mostly paid attention to just learning the code and adding features.

Some changes in version 3.0.3 alpha 1

GUI improvements:
- Holding down Shift key while clicking unit Up/Down buttons pushes up/down all units until the next free unit. Doesn't work in the Global instrument yet.
- Patch data is saved to the VST host as "chunk", so it's saved inside your project/song and you don't need to save your data to external .4kp files.
Note: ForkedKlang does not currently notify the host when patch data has changed! So in order to get the changes to save, you have to change something in the host.
- Auto Panic feature (enabled on Invalid Operation FPU status by default), which practically removes the need to press PANIC!
- Active voice counts and unit stack counts display in red color, which instrument/unit had the FPU status that triggered an Auto Panic. Not in the Global instrument yet.
- 48 instruments
- Per-instrument MIDI channel setting and note/velocity ranges for distributing notes to instruments
- "Map velocity to note" feature, so you can use different MIDI velocities for drums in your sequencer.
- When exporting 4klang.inc, a .4kp patch file is automatically saved with it.

New units and .asm player functionality:
- Swing feature for the exported asm player. Disable swing/groove from your sequencer while recording.
- New unit "Slew", which is basically a moving average filter, optionally squared. Uses the delay buffers to do its thing.
- New unit "Load From", which can load workspace variables that are normally unavailable, particularly oscillator phase.
- Conditional store mode in FSTx, which enables you to do oscillator sync. Load From the master oscillator's phase, and store in the slave oscillator's phase when it wraps.
- A minor speed-up feature for reuse already transformed values, so the player only transform the values the first time.

Probably many more things I just forgot about.

It's work-in-progress, and I have many things in mind for the future.

I won't promise to fix anyone's bugs or even study them, because I made the whole thing to have a fun project. But I figured that some of these new hacks I made might be useful and fun to other people, so I'm releasing it. Or if Gopher and pOWL happen to be interested in cross-porting the additions to 4klang. Especially saving the patch file automatically in the Ableton project feels like a big time-saver for me, just like the Auto Panic feature.
added on the 2018-02-10 18:04:33 by yzi yzi
Cool, especially the much-needed chunk saving/loading.
One GUI improvement I forgot
- You can select (go to) an instrument by clicking on its active voice count box in the lower right corner.
added on the 2018-02-10 20:58:39 by yzi yzi
Cool changes, particularly like the instrument names in the drop down, gets a bit annoying when you're getting close to finishing a tune and you want to clean up unused instruments. Although I'm not sure any 4k intro is gonna play fair with 48 instruments used. I'm also curious how you use 48 when there is only 16 midi channels?
added on the 2018-02-12 17:33:37 by djh0ffman djh0ffman
We managed to bring 4klang and 8klang beneath realtime performance with 32 instruments already while doing the remix of rise. ;) The loading screen at the beginning is, apart from accurately porting the original, only useful for buffering the music. Admittedly, we used a lot of stereo oscillators and 2x polyphony.

I can't imagine actually using 48 instruments °_°

That being said, it's very refreshing to see some of the UX improvements that have been pending for a long time. :)
added on the 2018-02-12 18:51:41 by xTr1m xTr1m
I thought it would be self-evident how to utilize more than 16 instruments by looking at that GUI screenshot. ;) Here are two ways you could use the new instrument channel, velocity and note range facilities:

Alternative A. Split/distribute MIDI notes to instruments by using velocity ranges:
BB Image

I think it's sometimes nice to be able to view and edit the notes of a chord as an actual chord, not as separate things on separate tracks. :)

Alternative B. Split/distribute MIDI notes to instruments by using note pitch ranges:
BB Image

I think 16 MIDI channels is plenty. :) You don't have to use more instruments than you need. The instrument places are there only for the VST instrument, by the way. In the asm player you only get what you actually used. I put 48 instruments there as a proof-of-concept and to make sure I don't run out of instruments, if I come up with some nifty things to do with them in the future. I haven't even used 16 in any song yet, because my humble old i5 is already choking.
added on the 2018-02-12 19:20:08 by yzi yzi
Here's how to use the "Map Vl->Nt" feature for mapping velocities to notes

BB Image

And this is what it sounds like.

There's only one instrument that makes sound, and that's mapped to the F3 note. The notes below are for a control instrument, which modulates the sound-generating instrument's envelope values and filter resonance.

I don't know if that makes sense to anyone, but I thought it was a nice experiment to try and make a single generic drum instrument that's kick, snare and hi-hat at the same time. That's how a drummer could think about himself and his set of instruments, IMO, to get a more holistic and glued-together feel of playing. (Another way is to think of it as a whole bunch of separate individual instruments, each with its own "part", like in a marching band or in latin music with clave, conga, surdo, etc.)
added on the 2018-02-12 19:53:43 by yzi yzi
There's a bug in ForkedKlang 3.0.3 alpha 1: if your synth has an unused instrument with a Slew unit, then the 4klang.inc exporting gets messed up with counting delay length array index numbers and generates a nonsensical DELAY parameter, which crashes the asm player's audio rendering.
While waiting for the next alpha version to come out, either remove the unused instrument or the Slew unit in it, or utilize the instrument by feeding it some notes.

Btw, coming up in the next version: CPU time usage metering.
BB Image
added on the 2018-02-17 22:20:36 by yzi yzi
Ha! That's pretty frikin slick yzi! Amazing how obvious it is when someone explains it with pics from my fave daw. I'll give that a whirl when I get a chance.
added on the 2018-02-18 01:43:49 by djh0ffman djh0ffman
Sorry for spamming, but I'll post small updates on things I'm working on, if someone happens to have some related ideas or comments.

Minor user-interface improvements coming up in the next release:
BB Image

I added a float value display for the unit parameter values so that it shows the non-transformed data byte and the effective float value the data byte ends up being after go4kTransformValues() and case-by-case adjustments, adding 0.5, multiplying by 2 or by 128.0 etc.

A slightly bigger thing I'm working on is higher polyphony, selectable per-instrument voice limits and per-instrument unison voices, currently with max 8 voices. For utilizing the unison voices there's a new Load Index unit type, which allows loading the current voice's index number, which can be scaled and offset. To do common unison effects, you can store the scaled voice index to e.g. oscillator detune and panning. Currently what's missing is "some" details on the asm player side. I was struggling a bit with the value ranges of the index numbers after scaling and offsetting, that's why I added the display texts.

I've been thinking of adding a Monitor unit type, which would show an oscilloscope and textual monitoring of what's going on in the FPU stack's topmost 1-2 numbers, because quite often I'm unsure of what the values are if there seem to be overloads and weird things. One possibility would be to redirect the two topmost numbers from the Monitor unit to extra outputs 3-4 of the VST plugin, so you could use any VST scope/metering plugin. I guess it should be possible to get more than 2 outputs working relatively easily.

It's interesting how some people, particularly Noby, can get such great interesting sounds, I think by primarily tweaking and listening. But I'm more like, I must know what numbers there are and if the schematic is "right".
added on the 2018-03-03 19:57:16 by yzi yzi
yzi: you might be interested in this, so you can actually fork from it (or backport stuff)

added on the 2018-04-02 02:47:31 by gopher gopher
Thanks. I won't be able to make a proper fork, because I've made so many changes all over the place, and when starting the "project" I made the choice of not even using Git at all, to free myself from thinking about external communication as much as possible. After I've got the unisono voice feature fully working, I'll put ForkedKlang up on GitHub or something.

Great to see that you made a glitch unit, that was one of the things on my list of ideas to try at some point. Another slightly related idea a wavetable oscillator which utilizes the delay buffers in some way. Wavetable data would be either recorded as audio from inside the synth, or baked as data in the .inc file. It could be a nice addition for bigger intros, and the custom stored data could work in many roles when fed into whatever unit's modulation that anyone can think of.

Some more of my ideas to do:
- Meta units that manipulate the internal control variables regarding the "instrument data stream". I'm doing something like that for the unisono feature, like "set instrument max voices to N", but it could be used also for re-using common instrument data for multiple instruments, fully or partially.
- Dismantling the "output to instrument's sample value buffer" + "accumulate/collect from all instruments sample value buffers" unit system, and replacing it with a more generic "bus" type thing, where instruments would work as buses or "group channels".
added on the 2018-04-02 13:40:15 by yzi yzi