Blog

PART 6A – MORE REFACTORING

Last time I said “a couple of things” needed my attention, and getting the code base inside the correct workflow was just one of them. Now that was done I could “refactor” the code base proper. “Refactoring” is a term from OO programming(well it became popular there) and really all it means is going back round the code restructuring and putting stuff in the best place for re-use and if you’re lucky improved performance as well as being more extensible and maintainable(just one place to fix each problem as it arrives).

Again there’s no real visible win here, so it can get ignored in favour of “nice-new-shiny-stuff”. But as getting everything into the correct workflow(again!) hadn’t been as unpleasant or time consuming as I’d feared I decided to take a run through the code to refactor stuff.

One part of the code base that had grown a LOT was the “note playing” – which needed to account for a whole raft of stuff like repeats, random, reverse, formant stuff etc. etc. So I dragged it all out into a callable function (called unimaginatively  “play_a_note”). It made the code more readable and very slightly improved performance(I think). But whilst coding it I noticed an opportunity to fix another of the “potential problems”.

I have some very odd loops in the test set, including some that seem to start in the wrong place, by which I mean most loops start with a kick drum “on the 1”, but some of these seemed to be offset by one or more beats: so they seemed to start “on the 2”  – which was often a hi hat, or “on the 3”- which was a snare. Why the person who recorded these loops decided to do that I have no idea but hey – all creativity is good right?  I identified a way to get Slice to “shuffle” every pad sound(slice) either forwards or backwards, so the end user could move/shuffle slice sounds across all 32 pads – so they would have an easy “fix” if they wanted it. So I added some controls in the loop section to do just that. And another “potential issue” was no more, as well as offering yet more loop-manipulation options. But was it all getting “too much”? Would users be intimidated by all the stuff you could now do?

 

Here’s a screen shot with the shuffle controls underneath the Loop grid:

part2_new_uioff

 

 

 

 

Here’s what faces me each day(yeah really, 13K lines of code…)

really_13376_lines_of_code

 

PART 6 – REFACTORING

Well that all looked like a bit of a success then, nice new UI, clicking/bumping noises tamed, handling pad sounds nicely, some pleasing new sound design features, ready to release!

Well not quite. There’s always beta testing to do, and even before I got there I knew there were a couple of things I still wanted to do (really – there ALWAYS is “another couple of things” – when will I learn?).

Here at Channel Robot (making it sound like there’s more than just me here full time…) we (really just me…) use a code generation facility, called “KSP Workbench”. I wrote this about 6-12 months ago. It takes files from Skinman (a UI design tool), reads them and builds KSP source code that (in theory) compiles out of the box. It’s a MASSIVE help, often halving, or better, my effort to get something done. Sadly Slice had started life long before KSP Workbench so it wasn’t set up to work this way. But I’d bitten the bullet early in Slice V4 and remodelled it in Skinman and KSP Workbench. But, again unfortunately, somehow at the end of Slice v4 it had started to play up badly(the only piece of code that ever has thankfully – and in retrospect all my own fault), so given the pressure of time and delivery dates I had reverted to hand-coding only. I knew if this new version was going to be supportable at all I needed to get it back inside the proper workflow. So it was time to push the code I had built back into a shape that KSP Workbench would understand, and to update the Skinman files for the new things I’d put in.

This sort of thing is always a hard decision, because in the end it’s an unknown amount of work for “no-new-functionality”, but I did it anyway. It turned out to be not nearly as bad as I thought, and inside a few days I had the code base working with the design-code generate-customise workflow that worked for me. A win then – but one only I would really ever see. With luck the downstream effects would show up as faster time to develop new stuff, and fix mistakes – – hopefully.

Here’s what KSP Workbench looks like when its finished a build….see how interesting it is being a developer:

kspworkbench_example

PART 5 – FADE-IN TO FORMANT

So driving to work I realised I should have removed Fade-in and replaced THAT with Envelope. Duh! But as I was where I was (driving the hour to work) I thought about what else I could do with the space currently occupied by the now clearly redundant Fade-In control. In Formation, a product I built with Zero-G, I used two copies of the same wav data (keeping downloads and memory usage lower), but put one of these sets of wav data in a “Formant-based” group and mixed it in to add new and interesting sounds, perhaps I could do this with each loop group?

So after a little wrangling of groups and working out how I could make this work using note-offsets(really its just technical guff here.. feel free to ignore.) Fade-in(F) became Formant(F)…. and it really worked. Interesting new sounds kept showing up – especially in the drum loops, an area I’d expected not much of interest there – it just shows what I know about sound design – nearly nothing. Yeah really really original and nice. I am pretty pleased with this. I’m also trying hard to not remember this was a result of a mistake I’d made earlier.

I think this really makes Slice into a completely different animal, suddenly its as much a loop/sound design tool as it is a loop playback engine, and it’s the second product in a row where applying Formant processing has added a whole new dimension(Formation was the first). So two things 1. I think I’m giving away a BIG secret here – I cant see why other developers wouldn’t start doing this straight away, and 2. I’m running the risk of Channel Robot becoming “those Formant guys”, but thinking about this I guess there are worse reputations to get.

Here’s a bunch of loops, in an original 4-bar “as played by Slice” and 4-bar “as played by Slice with some formant processing  added in” to give you some flavour of what’s possible:

https://soundcloud.com/channelrobot/tesstformantdrumloop1

https://soundcloud.com/channelrobot/tesstformantdrumloop2

https://soundcloud.com/channelrobot/tesstformantbassloop1

https://soundcloud.com/channelrobot/tesstformantpadloop1

 

 

 

PART 4 – SLICE MANAGEMENT

OK so some UI changes in the bag, on to the second set of issues, “Slice Management”. I made sure I found a bunch of test loops that displayed the issues I was having, and added in some that didn’t as well as adding in some “non rhythmic” material, specifically some bass loops and some long running pad sounds (cinematic material you might call it). I wanted Slice to handle all these nicely.
I’d tried (historically) all sorts of things to fix this, and the last thing was to actually slice up every loop I was going to use into 32 different wav files, and to manually edit these to get them to work. This took a huge amount of time and effort even after I’d written a bunch of python code to automate a lot of it. The hand/eye/ear editing couldn’t, it seemed, be replaced.
So I’ve been thinking about it for a while and giving each played note (slice in this product) its own envelope seemed to be a potential way forwards. So this would mean a lot of envelopes, and they can be CPU expensive…so first thing was to see how badly envelopes would affect this. Turned out not so much as we were only keeping 12 loops in memory at any time. Next was each of these envelopes would need an on/off button and a set of controls(attack, hold, decay). Clearly one of the existing slice effect buttons was going to have to go…
Here I made a serendipitous mistake(see the next episode for why this is so). The obvious candidate here was the fade-in control, after all what’s envelope attack if not fade-in? But I chose Unison instead (Clearly I had some sort of “Brain-fade” here). Unison was sort-of-OK, but it really wasn’t adding much that the volume controls for a slice could do as well if not better. So Unison (U) got replaced by Envelope(E).
Now an earlier version of Slice had already included an envelope, and as soon as I added it back in I got all the nice things it used to have – you could shorten the playback length(Hold) and get a nice gating effect(really nice on snares), or lengthen the decay to make slices blur together – making those cinematic and bass loops work seamlessly. Shortening the hold also get rid of “bumps” at the end, and adjusting the attack helped with the clicks at the start too. It could be a little fiddly but once done for each loop it was fine – and remember now I have loop-specific settings for all 10 controls. So worst case I could hand-set the controls for those loops that were unfriendly citizens.

So I realise it’d be nice to hear these changes, so (with luck) here they are, first Orbiter plays a “normal” drum loop, then plays it again with the snares gated:

https://soundcloud.com/channelrobot/testorbitergatedsnares

Next Orbiter plays long evolving cinematic sound without envelope(there are slight clicks in the loop), next it plays the same loop but with envelopes deployed on each step to “smear” the sound to get the nice original sound back. Finally Orbiter plays the loop but uses the envelopes to give each slice a gated rhythmic feel.

https://soundcloud.com/channelrob…/testorbitercinematicsound

PART 3 – HELPING OUT

PART 3 – HELPING OUT
So UI work is sometimes referred to as “Look & Feel”, and most people spend ALL their time on look. Big mistake. Feel is actually much more important. So I wanted to make the instrument easier to use. I’ve been using it a lot, no surprises there, and spending a fair amount of time clicking on those 5 Sound and 5 Voice buttons, then changing values in their little pop up dialogs.
All this takes time, lots of time. So it seemed to me that a nice-to-have would be some control that would intelligently set the parameter values and the on/off states for these 10 buttons. So I implemented a dial for Sound and another for Voice that does just that – set to zero and all controls are off for that set (that was a god-send right there..), gradually increasing the dial increases the number of controls that are turned on and the “richness/complexity”? of their parameters, with some smarts for the effect/position combination – so for example repeats become more likely to happen the higher the dial and the number of repeats used also increase the higher the dial goes, with some randomness thrown in, and Repeats are more likely to show up on beat 1,5,9 etc.
Meanwhile in the background… I’d noticed that these Voice and Sound settings were pretty specific to a loop. Currently they’d been implemented as 12 different sets (one for each loop slot). I changed this to be specific to the named loop. What does this mean? Well… if you loaded a loop named (say) MyFirstLoop into slot 1, and then changed any of the 10 control sets in some way, these control settings were remembered by Slice as “applying to any loop in slot 1” so they would stayed the same no matter what loop you loaded into slot 1. In this new version Slice remembers the 10 sets for MyFirstLoop and every other loop in the product, then reloads that set up when you reload MyFirstLoop. I also realised that I needed a quick and easy way to copy entire set-ups between loops. So I also implemented an Alt-click on the Voice and Sound buttons to copy the current Voice and Sound sets, and Shift-click to paste these sets into another loop.
Once that was done it was obvious to do the same thing not only for entire sets of controls but just for the controls in a single pad, so Alt-Click the pad and its settings are copied, Shift-Click on another pad and those settings are pasted into the pad. These sorts of additions are never really obvious – and never show up in any marketing or sales material, but they are the sort of things that make using a product MUCH more enjoyable – they don’t add sales, but they do add loyal users, and as one of those users I get to benefit as well as feeling dis-proportionally happy about doing them. No idea why.

PART 2 – UI CLEAN UP

PART 2 UI CLEAN UP
So I started with the UI clean up. I had some ideas and simplifying was the main aim. Slice is a loop tool, sure it does a LOT to the loops but loops are what it uses, so I moved the loop selection to position 1A (top left) of the UI and shuffled everyone to the right. In terms of workflow it felt right. Next was those “in slice” buttons, there are 5 displayed under each slice pad at any time. I managed to get the buttons integrated into the pads themselvesso they didn’t look like they were floating about in space waiting for a bus…, this had the added advantage of the pads being bigger – sure you couldn’t press the pad that was “under” the 5 buttons but it looked nicer.
Then of course it was a simple realisation(and letting go of it) that allowed me to change the rule for displaying these 5 buttons. In Version 4 of Slice you EITHER had the Voice buttons on display OR the Sound buttons. I changed that rule to: EITHER the Voice buttons OR the Sound buttons OR NEITHER. So if you are not working with Sound or Voice than they are hidden and the UI looks a lot simpler, AND there’s more pad space to press…
Finally whilst doing all this I managed to work out a kind-of design pattern for the UI. This is a simple set of rules for background section definitions, and ALL buttons are dark when off and light when on etc. Skinman design attached.

part2_new_ui

PART 1 – CHECKING IN WITH REALITY

Part 1 – CHECKING IN WITH REALITY
OK, so first to be brutally honest about the reality facing me on day 1 of development. As some of you may know I have a product(currently) called Slice. It’s been called “Grid Machine – Slice” and “GM-Slice” in the past, but the last version I released (in the second half of this year) was essentially version 4 of Slice. So I’ve been working on a loop/slicing tool called “Slice” for over 8 years now.
Frankly sales of this version have been terrible. This was the first time I’d not used one of the distributors to sell a product, but I had a pretty good email list so I thought it might be good to give it a home-site approach. Silly me. A handful of sales only, and I mean a handful – not even double digits.
Those 8+ years of effort have meant that the product has a LOT of functionality, and every beta tester and every demo producer who has worked with the product has been really really nice about how good it is. So some logical part of my brain should have said “well its just a distribution issue” and caved-in and gone with Kontakt Hub or similar. Of course I’m a developer so some other part of my brain rejected that idea in favour of “well its just not got the right/enough functionality or the right UI, I can fix that myself!”
Yeah, delusional, so possibly silly me, we have yet to see. I may eventually go with one or more of the distributors, but as I haven’t reached the “Great! functionally done!” in the developer part of my brain then it’s not released and we don’t know.
You know what? This feels weird, I feel like this is the marketing personality writing this, and the developer personality who doing the work – split personalities already…and they are not listening to each other!…..grief.
So the developer in me wants to tweak a couple of things at least. One is the UI – Slice has had progressively improving UI’s but even the latest looked busy – It’d be nice to clean that up even further. There should be an image attached of the design layout of the existing UI so you can see where I started. Also there’s a long-standing issue when you slice loops. Slice is mainly used for drum loops, and if the loop isn’t precisely played/recorded in time then some slices have issues. For example if the beat is played early then Slice will “miss” some part of the start of the beat, and worse include the start of the next beat at the end of the slice, giving either little clicks and bumps when playing slices out of order. Now these are infrequent and can be good, but it’d be nice to work out how to optionally remove them…. so off we go.

aswas

 

Kontakt Developer Diary

Part 0 – DIARY OF A PRODUCT BUILD
So I’ve been doing a bit of a strange thing lately… I’ve been observing myself, well more specifically watching myself build iterations of Kontakt instruments. Building instruments is (for me at least) a long series of small incremental steps, some work out and get to stay in the end product some don’t. But I started to try and define a set of guidelines for myself about when(and if) to work on a feature I think up. Should I add things in straight away? Wait a bit until I have a clean(er) plate, and I’ve done more thinking? When? As part of this process I realised that (for me at least) it might be useful to document the build out process for one or more instruments, so I can see whats working and what might not be.
I don’t have an all new product to use right now as my guinea pig, but I do have the next version of an existing product(Slice), so I decided to use that. Now like many things (and here already is an admission) I got the idea for doing this after I’d started building the next version of Slice, sigh. So yes it may have been better to start day 1 with this (huh) “diary”, but I didn’t have the idea at the ideal time so I’ll do a few weeks of backtracking here, and try to be as honest as possible about what went on. Look for “Part 1 – REALITY” where I look at the situation I was/am faced with..in the next week.