Striving For 3D

This week I made some progress towards towards coding 3D rendering!

I remember when I was in my early teens and a bit bored on holidays at my grandparents, trying to code an image of a road with 1-point perspective. I asked my grandfather to show me how to load the version of BASIC he had on his ancient Amstrad PC (it was GW-BASIC).

Back then, I didn’t get the basic idea of 3D perspective, but it isn’t actually very difficult: if objects are in a space in front of you where X is across, Y up and Z forward (and you are at 0, 0, 0), dividing their X and Y coordinates by the Z coordinate will create the necessary distortion.

(It seems that, typically, a small number is added to the Z component first to reduce the strength of the distortion, otherwise things get madly stretched off screen when the Z approaches zero. I bumped into that problem when making my Pink Sparks demo the other week.)

The real issue is that, to keep the code organised, manipulations of 3D data are best done using matrices. This way, a command can become data. Instead of running some code for each manipulation (such as rotating or resizing a shape), you have one piece of code that obeys a data representation of the desired command. This data is a transformation matrix.

You can then conveniently store these commands, for example the operations “Rotate by 30 degrees around the X axis, mirror in a plane with the same orientation as the X-Z plane but 5 units above it, resize to 80% scale” could be represented as three 3×3 matrices.

If you use homogenous coordinates, which are like ordinary coordinates but containing an extra element by which all the others are divided, then the Z-divide for perspective correction can be represented by a matrix which copies the Z value into that extra, dividing element (typically called W).

But enough of my attempts at understanding linear algebra! Let’s talk implementation details.

As usual, I made my demos in JavaScript. Being able to trivially publish stuff on the web, and send no-hassle links to friends or relatives, makes this the most attractive choice.

However, I decided not to use WebGL, the graphics-card-accelerated renderer that now comes with all browsers. I’ve been having a good time with WebGL tutorials, but connecting up buffers and typed arrays introduces more places to make a mistake and lose time debugging. I’ll return to WebGL someday because the raw power, the basic idea of shader language, and the depth-buffer and texture manipulation capabilities all attract me deeply. But for now there was, again, a clear best option: HTML5 Canvas.

This is a graphics API with higher-level features such as line-drawing commands – precisely what I wanted for my demos!

The first one I made demonstrated linear transformations in two dimensions. As you can see if you click here, these all operate around the origin (the centre point where the two axes meet), or to put it another way they preserve the origin. I used setInterval(..) to make the animation – not a good choice as we’ll see in a sec.

Then, I made a demo of affine transformations – a larger category which includes the linear transformations, as well as translations (i.e. just moving shapes around with no distortion) and mixtures of linear transforms and translations. To show the way that affine transformations can occur around any point, I added some quick interactivity to let the user set the centre point and choose a transformation. I also used matrix multiplication to iteratively apply the same transformation to my shape.

Affine transformations -area-preserving squash, in this case, which incidentally describes hyperbolic curves.

Around here I started thinking of possibilities for game graphics:

  • a stick person who squashes a bit before and after jumping
  • a stick person who leans back before and at the end of a run (wind-up and breaking), done with a shear transformation
  • explosions setting off shockwaves that pass through numerous characters on a the screen, squashing them in its direction as it does so
  • interactive objects that cause the player character to change size, Alice In Wonderland-style

(I was definitely channeling some old Flash games from my teens… stickdeath.com, anyone? I think that was the URL.)

I’ll get back to these ideas in a second to discuss what I think would actually be the hard part about making them…

My final demo was in actual 3D. Still working off Greg Tavarre’s nice WebGL tutorials (though NOT following his convention for ordering matrix elements in a 1D array), I implemented homogenous coordinates and a Z-divide. My first attempt had an annoying error in the Y-axis. Turned out everything was working, I had just put my transformation matrices in the wrong order so the up and down bobbing was happening after perspective had been applied!

That’s what it looks like! Click here to see it hosted on my site.

If you look at the working demo, you may see the star seemingly spinning the wrong way, despite the perspective cues, a classic illusion. I think this is just a general fault of wireframe graphics.

BTW The animation here is handled with the preferred modern JS technique requestAnimationFrame(..).

All this demo-making begs the question: could anything here become reusable software?

The matrix stuff is eminently reusable. To make it convenient, I would need to make an engine or interface allowing a programmer to load geometrical data, transform it and display it, through well-documented, user-friendly functions, while hiding inner workings.

So the last thing I did this week was some design work on a personal 3D library. Eventually this should be in WebGL, but to test the design I might do it in Canvas and maybe just with wireframes. The crucial point is that geometry exists in all these different spaces before it’s fully processed:

  • object space, that is, vertexes positioned relative to the centre of the object they represent
  • world space, so now that object is positioned in a world
  • camera space, now the world is spun around to face the camera
  • screen space, now anything visible is referred to by the position it takes up on the screen (in this case, the rectangular Canvas on a webpage)

All of these have potential for interesting experimentation. What exactly defines an object is an open question – can an object be composed of others, and in what ways might those sub-objects be transformed? Once in camera space, what are the possibilities for fish-eye effects or non-Euclidean geometry? And of course screen space is the traditional domain of the visual artist, the flat sheet.

Well that’s some big talk on the back of a spinning star. Baby steps though!

7 Days

Last Monday I decided I would work on a different coding-related skill each day, for a week. These days I’m familiar enough with my own brain to know that swapping subject areas and deep-diving into topics suit my attentional style. Because motivation can be hard to come by when jobhunting and self-studying during pandemic restrictions, I thought I’d stimulate myself with novelty. It might even help me get psyched up to work on longer-term ambitions, like releasing my ritual Android app Candle Shrine, and also making a portfolio website.

Day 1 – C

On Monday I worked on C programming – an area I haven’t touched since 1999, ha! Yes as a kid I did a summer course which touched on some C. Anyhow, the aim was to set up the compiler and get console input and output. I used a build of Tiny C Compiler nabbed from the Tiny C Games bundle. My project is a simulation of life as experienced by our family cat, Goldie. Actually I’m pretty pleased with this, my sister played it through and enjoyed it. I was inspired by Robert Yang’s concept of “local level design“- a design aesthetic celebrating small-scale social meanings rather than top-down formalism. (This suited me because I don’t yet know enough C to write anything other than this ladder of if statements. Still, it works!)

Day 2 – Linux

The next mini-project was Linux shell commands. I used VirtualBox to dip my toes in -it lets you run any distro on emulated hardware, from a Windows desktop. It nearly locked up on my a couple of times, but in fairness my computer was running two OSes at once so I forgave it. It never fully crashed.

I’d hoped to get into shell scripting, which is the power user technique of saving listings of shell commands (a shell being a console for directly running programs or OS utilities, etc. – like the ol’ Command Prompt in Windows) as text files to be invoked as, effectively, little programs.

But all I had time for was to learn about 20 standard shell commands. However, I really liked this stuff. I can see why there’s a stereotype that devs use Linux. It’s rather satisfying to install stuff, edit files, and set up the file system via typed commands and not all that intimidating either.

Day 3 – Pink Sparks

See it in action here

This one was fun. I made a 3D particle demo – a spinning cube made of flying pink sparks. My focus here was to prove I could make a simple particle system, which indeed wasn’t hard, cribbing off Jonas Wagner’s Chaotic Particles and leveraging the extremely handy Canvas feature in HTML5. I also wanted to do 3D perspective, which was hard. However here I used the simplest possible version, a bare z-divide where x and y coordinates are divided by distance from the viewer. The proper way to do this involves matrices and transforms, but I’m not there yet.

If I get back to this the two things I’ll do are change it to defining line-shaped sources of sparks rather than point-shaped, and make some nicer data than a cube, like say a chunky letter ‘K’. This wouldn’t be particularly hard. Making a display of my initial fits with my interest in what I call ceremonial coding which I believe will be an emerging cultural field in years to come. As life goes online, we’re already finding the need to program and design software for celebrations and community rituals – an example being my graduation from my computer science course, which is being held on Zoom. I am certain that techniques from game design and aesthetics from digital culture will be important to create spiritual meanings and affirmations of identity on computers. My upcoming ritual app for Android phones expresses this conviction.

Again, Robert Yang’s post is very close to the spirit of this: “What if we made small levels or games as gifts, as tokens, as mementos?”

Day 4 – Huffman Coding

I hit a roadblock on Thursday. Huffman coding compresses text, by taking advantage of the fact that certain symbols (for example, ‘z’) occur far less often than others. To make a Java app implementing this was a meaty challenge, requiring binary buffer manipulations, a binary tree, sorting and file I/O. Still should have been achievable – but I let myself down by not rigorously figuring out the data representations at the start. This meant I threw away work, for example figuring out how to flatten the tree into an array and save that to disk, only to twig that the naive representation I’d used created a file far bigger than the original text file.

Though I was working from a textbook with an understandable description of the Huffman coding technique, that was nowhere near enough. I still needed to design my program and I failed to.

So I ran out of motivation as poor design decisions kept bubbling up. This was a stinger and a reminder that no project is too small to require the pencil-and-paper stage. On the plus side, I did implement a tree with saving and loading to disk, plus text analysis.

Hopefully I can reuse these if I come back to this. It’s a fun challenge, particularly the raw binary stuff and the tree flattening (although I don’t know yet if I want to store the tree in my compressed file, I think probably just the symbol table needed to restore the original.)

Day 5 – WebGL Black Triangle

In the spirit of Jay Barnson’s Black Triangles – though I’m sure it’s a million times easier these days!

Now this was pure fun. I used a tutorial to learn how to display graphics on a webpage using WebGL. I… frankly love the feel of OpenGL Shader Language. The idea of using a harshly constrained programming language to express some low-level color or geometry calculations, which is then compiled and run on your graphics card so you can feed it astronomical amounts of data for ultra-fast processing, is so satisfying. (Actually, especially the compilation process, and the narkiness of the parser where for example 1 is different to 1.0… it feels like you’ve loaded a weapon when you’ve successfully compiled at last.) I love graphical magic, but previously have been doing it at several removes, using wrappers on wrappers like Processing. I will definitely be doing more of this.

Day 6 – RESTful API

Another failure! I wanted to make a RESTful API demo as a bullet point on my CV, and host it for free on Heroku. But although I did some good revision on API design, when I got into implementation I totally got tangled up in trying to get libraries to work. Blehh!

I wanted my system to be standards-compliant so I tried using libraries that’d let me use JSON:API instead of raw JSON, which some people say is not good for APIs as it has no standard way to include hyperlinks which are, in fairness, central to the concept of REST (i.e. that instead of the client knowing to use certain hardcoded URLs, each response from the API includes fresh hyperlinks that the client can choose to follow).

But I got stuck when the examples for the library I chose wouldn’t compile because they required a new version of a build tool, Gradle, and despite trying some things off forums my IDE failed repeatedly to automatically install this.

They don’t call it “dependency heaven“!

If I get back to this I’ll use the build tooling I had working already for school projects. Life’s too short!

I wonder if the area of web services – so essential, stolid, bland – might be a natural home for rather pedantic personalities. The type who would make a typology of all things and publish it as a web standard. In any case, wading through some comments and blog posts and Wikipedia pages gave me a stronger understanding of state in web services than I had before.

Day 7 – Pathfinding in JS

Like the previous one, this project spun off into piles of research. But it’s all valuable stuff, I revised a lot of CSS and particularly the grid system, and got deep into JavaScript using this quite good book.

My plan was to implement a classic pathfinding algorithm, Dijkstra’s algorithm. But I wanted to have it so a little monster would chase your cursor around elements on a webpage! Well, as usual, I should’ve thought this through more. The fact is, web page elements are not intended to be processed as 2D shapes. HTML is semantic – web content is structured and manipulated as elements like paragraphs, headings, links that have meaningful relationships in the context of the document itself – with the final presentation of these elements done on the fly according to the user’s needs.

Anyway… my point is, I had to compromise to get this going. My original vision was of words arrayed around the page randomly, at different sizes, with a monster sprite threading his way around them.

My solution doesn’t have the words, just boring blocks, and though I think I could do words at a fixed size, having splashy words in different size could be quite a hassle.

As you can see, the paths go through diagonal choke points, something to fix

Nor did I get around to the monster although I have the sprite for when I do:

Heheheheheh.

But the thing that worked well for this mini-project was: web standards! In particular, I made the excellent decision not to hack CSS positioning from JS, but instead take the time to revise the CSS Grid system. Which, as you might imagine from the name, was actually perfect for this use case. Those numbered cells above are arranged by Grid.

Conclusion

That was fun. I might even do it again!

Madlib Beatmaking Wisdom

HEAT – put it on while you read

I listened to this sweet mix of Madlib beats recently, and was reminded of my firm conviction that he is the greatest beatmaker. Maybe not the greatest living DJ in the sense of all-round hip hop artist, I’d hand that to DJ Premier for his epochal work with Gang Starr (deepest and best hip hop act of all time, for my money) and for making my no. 1 track of all time. Madlib doesn’t aim that high artistically, I think. But his stuff is the funkiest of all.

I had to turn up the mix to neighbour-bothering levels numerous times. It’s that good. So here are some notes I took for myself to try improve my own hip hop beats – a form I’ve been dabbling in for many years. Hope you find something you like.

Madlib excels with pickups. If you don’t know that term, it generically means a melody that enters a few beats before the perceived top of the musical form. However, I use it specifically to describe the funky structure wherein a line – melody, drum fill, vocal sound, whatever – leads the ear through a break to the downbeat. Think reggae drum rolls and jazz horn breaks. This kind of pickup provocatively holds onto or toys with the time/groove in the gap before a beat drop. I noticed that Madlib can use almost any kind of material in this role. Strings/vocal top layer mush, guitar or horn stabs, vocal snippets, anything.

(Something cool I noticed is that this use of chordal stabs/slices in particular as fills or pickups, can be ambiguously interpreted as both harmonic, a meaningful chord change, and as a passing dissonant sound.)

From this follows a more general principle: any sample, any instrument sound can and should be broken or undercut. (See my article on funky structures for more on undercutting.)

This makes me want to revise my comfortable habit of making a 4- or 8-bar loop, quite detailed and full, and then arranging it by basically muting and unmuting, maybe filtering or echoing, parts. Madlib eschews this techno type approach. His tracks are live-feeling and changeable, also quite unlike traditional hip hop like mid-90s DJ Premier or Lord Finesse productions. In those tracks, there’s some muting and breaks and cuts, but everything is based off a main verse groove (and perhaps a chorus change). By contrast, Madlib’s stuff turns and crawls like a beast.

Often this organic development lets an already existing sound flower and manifest its potential, e.g. from happening once every two beats to twice or letting in previously-filtered-out highs. Or switching octaves of a synth bass part here and there – very effective. This is about finding the right degree of saliency (a term I learned from an otherwise fairly boring composing book by Alan Belkin) – not smooth enough to be subconscious or background, but not jarring either. I’d like to learn how to hit that sweet spot.

Madlib’s beats are often pretty sophisticated harmonically – the root movements and chord changes from his source material emerge in the final product. I’m inspired to simply take more care with the chordal content of my samples and productions.

“Taking care” really sums up this music. Madlib never seems content to phone anything in. Every sample is present for a reason, never “just because” – even fundamentals like hats and snares are left out or drastically varied. Also, every sample, without exception, is so, so fat. Like, dripping from the speaker. It’s absolutely incredible.

That’s not achieved by narrowly honing in on perfect synth or EQ or compression settings like a techno producer. The fatness comes in wildly varying flavours e.g. from very subby, electro kicks/bass to earthy, turfy, crackling ones or quite distorted and processed, depending on what each beat needs.

This one’s a bit intangible, but Madlib’s tracks often seem to have a pregnant space. He can make you wait. These grooves are head-nodding yet sound like they haven’t fully kicked in, over long periods. This comes from space and the confidence to use it… and also making every element add to the funk.

Here are some specific things I want to try in my productions…

When using the classic hip hop technique of splitting sampled material into a bass layer and a top layer using filtering, don’t expect the bass layer to sound anything like a solo bassline. It’ll sound like a muffled version of the original sample with all its instruments, and that’s fine, it’s idiomatic. I used to think you had to try literally remove everything but the fundamentals of the bass notes, but this just results in a vague thrumming. That’s not the way!

Madlib has a distinct approach to the other side of the coin, the high frequencies: frequently his strings and vocals and chordal mush gleam hazily over the gritty, present beat. Perhaps some reverb on the top layer, and smart compression somewhere, contribute to this?

Actually, there’s a lot of woozy modulation in Madlib’s music (though it’s not formulaic like in your modern day chill hop/study beats electric piano sound) and I’m gonna grab a tape emulator to try get some wow and flutter and noise into my sounds.

Also there’s liberal use of loud and woofy synth bass, often with tasty (non-diatonic) note choices or chords. I think because I’m still in psychological recovery from quitting bass playing a year ago, I haven’t been focusing on basslines in my productions.

Well, that’s all I got. I would’ve liked to discuss the idea of “beatmaking” a bit – this cultural manifestation of the 2010s, pretty much, that markets aspects of hip hop culture as a hobby which now seems like it could take over much of music. (Especially in these awful, socially-distanced times.) And of course, there’s plenty of black culture stuff we could dig into, metaphors around music as sonic substance (“fatness”), the aesthetic of “taking care” and its gender coding (maternal energies in highly masculinist music), sexual metaphors around cutting, the groove, also the slave sublime (distorted voices, screams), manifesting/smuggling, and so on. But you can find those in any deeply funky music. I hope today’s narrow focus on techniques was worthwhile.

Thanks for reading.

Here’s another, possibly even better mix.

Golden Ratio Synthesis

I made a VST software instrument that uses the Golden Ratio to generate frequencies off a given note. You can download it here if you want to lash it into your music program and try it out. It’s unfinished though – more details below.

This didn’t come from any particular intention – it was a discovery I made while messing about in Synthedit many months ago. I was trying to make a normal additive synth where you mix the relative levels of each harmonic within a single note. But I found that if I took the frequency multipliers for the harmonics (which are normally just 1, 2, 3, 4 – so the second harmonic is twice the frequency of the first/root, the third is three times its frequency, fourth four times and so on) and raised them to a particular power around 0.6, a cool sound came out.

“Around 0.6” turned out to be 0.618034 – the “Conjugate Golden Ratio” (or one over the Golden Ratio).

Now it’s not possible to discover some “alternate harmonic series” because harmonics are a physical phenomenon: if you have a vibrating object with a fundamental frequency, whole-number multiples of that frequency can likely also form waves in it. So, each half of a guitar string vibrates one octave higher than the open string, and each third vibrates one fifth higher than that, and so on. Our sense of hearing subconsciously interprets the presence and tuning of harmonics as derived from physical properties: material and size and density. No other frequency series could have this same effect.

Nonetheless, the Golden Ratio seems more musical and harmonious than any other I could get by that exponentiating technique – actually it sounds like a jazzy chord. And it has what Gerhard Kubik calls “timbre-harmonic” aspects – like a Thelonious Monk chord, the harmony bleeds into the perceived timbre. My synth (on default settings) has a silky, bonky, dense timbre. (That territory between noise and harmony is where I like to be, musically. Check out the sounds I used for my drum programming experiment, for example.)

I could hear that it wasn’t in tune to equal tempered notes (nor to the non-equal tempered ratios found in the natural overtone series). But it was tuneful enough to sound concordant rather than discordant. If you download the synth and try the other ratios in the drop down menu you’ll hear the difference, I hope.

Here are the ratios: Golden Ratio conjugate on top, then normal harmonics, then the non-inverse Golden Ratio. You can see that the Golden Ratio conjugate results in a somewhat out of tune minor 11th chord – definitely jazzy! (The normal overtone series results in a dominant chord.)

Here are the ratios for exponents of: 1/Golden Ratio, 1, and the Golden Ratio

I whipped up some little riffs so you can hear the synth. It’s very digital-sounding, like additive synths generally are, and also reminiscent of the stacked, sometimes exotic overtones of FM synthesis at its icier end.

Note I didn’t sequence any chords in these – the “harmony” is from the voices of the synth. And there are no effects added.

I’ll evaluate the musical aspect at the end of this post. For now I want to discuss the synth-making software I used: Synthedit.

When I first started messing with production as a teen, the free synths I downloaded were mostly built in Synthedit. I soon got to know its characteristic signs – exuberant amateur graphics, slightly misplaced buttons and sliders due to the software’s drag-and-drop interface, and I guess a lack of quality. I remember one bass synth that was pitched way off A=440 – rank sloppiness. I used it anyway. The Flea, it was called.

Most freeware Synthedit VSTs were like that: knock-off bass synths or delay effects, easy and obvious stuff, frequently derided by snobs on forums.

Synthedit enabled a flood of low-quality, imitative software synths by lowering the barrier to entry. Instead of coding C++, you could (and can today) just drag and drop components, add in other people’s custom components, and instantly see/hear the result in your DAW interfacing with your MIDI gear and other FX.

I was blown away when I first did this a couple of days ago. I clicked export, set some easy options, and then couldn’t find the exported file. Irritated, I went back to REAPER, my production software – and there was my synth just sitting there! And it worked! And nothing crashed!

Having studied programming for the last year, I know how hard it is to make software like that. The default mode of enthusiast-made nerdy software is to fail aggressively until you figure out some subtle, annoying configuration stuff.

So, today’s post is a celebration of a great tool, very much like the one I did about Processing. Once again, I want to emphasise how great it is that people make such programming tools for beginners, where the hard and horrid configuration stuff is done for you.

This is priceless. It can change culture, like Synthedit changed bedroom production culture and marked my adolescence.

Amazingly, the program is developed by a single man called Jeff McClintock. He is active on the forum and from reading a few of his posts I get an impression of someone who takes any user’s difficulty as a sign to improve the program. I really admire that. And it shows in the robustness of the app (even the old free version I’m using).

To make a synth, you drag connections between “modules” that provide a tiny bit of functionality or logic. It’s like wiring up a modular synth. The downside is that, if you already know how to code, it’s a drag having to do repetitive fixes or changes that in a programming language could be handled with a single line. Also, when a module you want isn’t available, you are forced to make silly workarounds, download third party stuff or change your idea. In Java or Python you could just do it yourself.

All told, I enjoyed the experience of making Golden (so I have baptised my synth). The best part is having impressively reliable access to powerful, mainstream standards: MIDI and VST. That made it a lot more fun than my previous synth which took in melodies as comma separated values and outputted raw audio data. It was brilliant to have all the capabilities of my DAW – clock/tempo, MIDI sequencing, parameter automation – talking to my little baby.

The drag-and-drop interface builder is also great. Once again, amazingly, McClintock hides all the donkey work of making interfaces, the boilerplate code and updating and events. You just put the slider where you want it, then it works. The downsides are being locked into standard interface elements unless you want to go much more advanced. So, I wanted to have one envelope take the values from another at the flick of a switch, but I couldn’t. (I’m sure it can be done, but I couldn’t find it easily online. In general, the documentation for Synthedit is weak, and online tutorials scanty. I think that’s due to the narrow niche served – people nerdy enough to make synths, but not nerdy enough to code.)

Although I had a great time with Synthedit, I’d like to keep learning and do this work in a procedural or OOP language next time.

Let’s finish. Do I think this Golden Ratio thing has musical value? Yes, and I would like to use it soon in a hip hop beat or tracker music production. (It could also serve as root material for spectral composition, I strongly suspect.) Is my synth very good as is? No, the envelopes don’t work nicely for immediately consecutive notes (I should make it polyphonic to fix that) and I’m not happy with the use of….

Actually, I should quickly explain the synth’s features.

My beautiful interface, in resplendent “Default Blue”. I’m not even sure it’s possible to change skins without paying for the full version of Synthedit. Which is entirely fair – I got a lot out of this free version.

At the top are overall options: the choice of exponent, then various tuning knobs. “Exponent fine tuning” lets you alter the exponent, “Voice shift” is an interval cumulatively added to each voice, “Keyscaled flattening” is a hack-y tuning knob that applies more to higher notes. Use these to massage the microtonality into sitting better with other harmony/instruments.

Then there are two instances of the basic synth, as you can see, each with 8 voices you can mix. You can turn each one up or down with the little knob on its left end. You can also change its tone with the lowpass filter big knob.

The idea of the two synth engines in one was to be able to double voices at Golden Ratio intervals. Sorry if this only makes sense in my head, but I thought that these dank Golden Ratio sounds should be harmonised using their own kind of interval rather than standard fifths or thirds, so by selecting the interval in one synth instance’s drop-down box you can set it apart from the other by one of those intervals. Selecting “First overtone” with “Golden Ratio Conjugate” set in the Exponent menu will, therefore, displace the 8 voices of that synth instance upwards by a perfect fifth + 42 cents.

Finally, to create some simple motion within the sound, I use two ADSR envelopes for each engine and linearly interpolate between them. The bottom one directly affects the bottom voice, the top one the top voice (always voice 8 BTW – I wanted it to detect how many voices are in use but had to abandon it – one of those workarounds I was talking about) – and voices in between are blended between these two, unless you click the “Link Envelopes” switch in which case only the bottom envelope is used.

And each engine has an LFO which affects the exponent, and therefore has a greater effect on the higher voices.

… I can see why they say writing docs is hard! Hope you could withstand that raw brain dump.

As I was saying, this synth is rough, but hey I’ve seen rougher on KVR Audio so it’s a release.

I’ve been listening to SNES-era game soundtracks so I’m tempted to try make some dreamy, pretty melodies using Golden. I think it might also be good for some woozy house or hip hop.

If I was to develop the synth, the first thing to change would be the two envelopes idea – really it should be some more sophisticated morphing. I saw an additive synth where each voice had its own envelope but that’s too much clicking. Some intelligent system – interpolating but using a selection of curves rather than linear, or maybe something like setting percentages of each voice over time while overall amplitude is determined by a single envelope – would be nice.

It also badly needs some convenience stuff: overall volume and pitch, an octave select, polyphony.

I’m leaving Golden as a nice weekend project. I’ll come back when I have some chops in C++, I would think.

Well, thanks for reading if you made it this far. You get a “True Synth Nerd” badge! If you want to talk about the Golden Ratio or synths, get in touch 🙂 And don’t hesitate to try out the instrument.

Why Is Python Nice For Learners?

I’ve come back to Python a few times in the past year. Before September 2019 I’d never touched it (or any modern programming language, really). Right now I’m using it to build a 3D game level generator, and very much enjoying myself!

I feel I’m close enough to the start of the Python learning curve to give a personal perspective on why this language suits dabblers and students.

This is not a prospectus of Python’s features or design decisions – I don’t know enough to talk about those. Just a happy acknowledgement of what’s been making my life easier in the past couple of days.

I’ll compare it to Java, the language I know best, which is also probably the closest to a standard for Year 1 of comp sci courses.

  1. The look
    Instead of the curly brackets of C, C++, Java and other much-used languages, Python uses the amount of tabs at the start of a line to determine what “block” that line belongs to (and also the colon at the end of any line that declares a new block). There’s something reassuringly basic and solid about that, to a newbie. You don’t need to learn the little skill of counting brackets (nor do you need to use semicolons) while discounting whitespace. Instead, how it looks in your editor tells you what’s going on directly.
  2. Simple string manipulation
    Python’s elementary text manipulations are simpler than Java’s. When you’re starting out, I think that helps keep your mind on the actual task. For example, getting input from the console in Java generally requires creating a “Scanner” – a powerful bit of software for carving up and selectively serving text from an incoming stream. Those capabilities are irrelevant for basic text input. So students end up depending on something whose quirks and abilities they don’t understand. Including some unintuitive behaviour that I’ve seen even experts admit is confounding.
    Also on this point, Python requires you to convert all number types to strings explicitly, when printing them. Which can be annoying. However, this arguably makes the underlying reality clearer than performing the same conversions invisibly as Java does.
  3. It doesn’t force Object Oriented Programming
    We’re getting close to the topic of many boring flame wars on which paradigm is better, but let’s keep this to an inoffensive point: Python affords procedural, functional or OOP styles of programming. So if you have experience of either, you can start from there. And if you don’t, you’ll be saved the laborious and ritualistic aspects of standard Java style: private member variables, getters and setters, etc. – until you’re ready.
  4. Those data structures
    I first read about Python in Jay Barnson‘s delightful old piece, which I have returned to many times since, “How To Build A Game In A Week From Scratch With No Budget”. In it, he eulogises its list and dictionary data structures. And he’s damn right, they’re great. Instead of wrapping data in near-pointless objects – a practice so widespread in the Java world it has its own name, “anemic objects” – you’ll find yourself creating, stacking and passing around these built-in structures, as I’ve done pretty much throughout my level generator app.
  5. It’s mellowed by age
    This one cuts both ways. You can find articles on Medium arguing that Python is past its peak, and getting less fashionable or even relevant by the year. Yet, the advantages include having plenty of 3rd-party libraries (though TBH I haven’t dipped into these yet) and also a smoothing away of rough edges. For example, Python 3.x (available since 2008) has what’s called “new-style classes” that allow for conveniences such as property annotations, getting info on a class or method at runtime… I actually don’t understand that stuff yet, but the point is, whereas a few versions ago I would’ve had to use a special syntax to get “new-style classes”, now that happens automatically. One less thing to think about.
  6. You don’t have to split files
    Another really small thing that nonetheless will be felt by newbies: Python scripts can have multiple classes, or none, in one file (called a “module”). Whereas even a minor task in Java might push you to make a few classes, and so have to save a few different files.

The end result of all these things together is: even if you’re not very good at it yet, solving problems in Python feels fast. I don’t myself have the depth of understanding to explain this one. But ever since I first tried a maths problem or scripting text templates with it, I was pleased by that feeling of getting things done.

BTW, I wouldn’t call Python a “beginner language” in the same sense I applied to Processing a few posts back. Python doesn’t have every interaction carefully shepherded so as to hide complexity. Nor does it provide a simplifying framework for graphics or what-not. It’s a full-featured language (although with a favoured domain of data analytics, science, scripting, and stuff like that, for sure).

Last thing. For some reason, I pronounce Python as PIE-THON, rather than PIE-thn. Does anyone else out there do this? Let me know I’m not alone.

Eleven Favourite Quotes from “Permacomputing”

Apologies for the clickbait format, which is hardly in keeping with the concepts I’ve been absorbing from Ville-Matias “Viznut” Heikkilä’s remarkable recent article. Think of it not as a push for attention on an ephemeral feed, but respectfully memorialising another’s inspiring vision here on my own site.

Today I will summarise some of that piece’s most remarkable insights for you. I’ll react to quotes, picked for their awesomeness, in turn.

(My WordPress stats suggest that most visitors are here for the jazz content. If that’s you, you are most welcome to stick to that stuff. But consider reading on to ponder alternative visions of the internet and entertainment technology that makes this very blog possible.)

BTW, Viznut is not writing in his first language, and uses “would” where “should” might be more idiomatic, when discussing idealistic futures.

Let’s go!

1. Computers have been failing their utopian expectations. Instead of amplifying the users’ intelligence, they rather amplify their stupidity. Instead of making it possible to scale down the resource requirements, the have instead become a major part of the problem. Instead of making the world more comprehensible, they rather add to its incomprehensibility.

Pessimistic, yet I agree. “Amplifying stupidity” is quite precisely what Twitter does, intentionally spreading wildfires of outrage through our nerves and networks. ICT is projected to take up between 8% and 20% of all energy worldwide by 2030. And incomprehensibility… Jesus. I feel so strongly about how non-technical folk (my parents, for a start) are made fearful and humiliated by corporate tech like antivirus software, operating systems, bank and telecoms billing, touchscreen interfaces, and so on. Yet technologists (I’m one myself) always blindly return to their comfort zone: abstractions, services, always-on internet, new languages and upgrades and frameworks. “Increased controllability and resource use.” And increased incomprehensibility, infantilisation and frustration for everyone else.

Am I being hypocritical? Totally. I depend on myriad frameworks and the seemingly-invisible, actually aggressively-corporate-sponsored development work that keeps big platforms, and our whole civilisation, going. The point is not to deny that but rather observe it and judge it from a dispassionate viewpoint, asking what do we really need, in the long term?

2. Permaculture trusts in human ingenuity in finding clever hacks for turning problems into solutions, competition into co-operation, waste into resources. Very much the same kind of creative thinking I appreciate in computer hacking.

So, Viznut turns to permaculture, a gardening philosophy. Actually, in my long list of article ideas for this site, is one about how my grandfather manages his large garden, despite being in his mid-80s. The point was that due to an inherent rightness in his methods and tools, and a humble reliance on nature to do the work, his garden is still productive and pleasant no matter how physically weak he gets. His work is opportunistic and adaptive. Son-in-law visiting? Make him sharpen my tools. Grandson loafing about the house? Get him to plant lettuces, or pull down vines. Can’t walk much? Put a trailer on the lawnmower. Even when sinking into decay, everything still works, just at a lower level. His old greenhouse, lean-tos and cages are merely waiting for when he has the energy to put one or the other to use.

What has that to do with staring at a screen and tapping away at a keyboard?

3. Any community that uses a technology should develop a deep relationship to it. Instead of being framed for specific applications, the technology would be allowed to freely connect and grow roots to all kinds of areas of human and non-human life.

Could technology – or one or a few specific, locally chosen technologies – fit into our lives like a well-stewarded garden? Like leaving a garden to grow in rain and sun, we would let it do what it’s good at. When resources were at hand we would apply them, if not we could wait. We could deploy it in new ways all the time, like using a garden for meals, sunbathing, athletics, meditation, crafting, cooking, drawing, retreat, nature watching and so on. Even with minimal maintenance it would function, while occasional bouts of serious group work would provide exercise, catharsis and new directions.

Dream on, Kevin.

But I’m basing these ideas off a real scene, as Viznut does with the demoscene. Since about 12 or 13 I’ve been interested in Quake modding, a scene in which enthusiasts create new levels, monster types, versions and toolchains for the first person shooter game, Quake (1996, id Software). There’s something more than a little amazing about how this online community has grown while nurturing a set of powerful, well-maintained software tools, and releasing hundreds of fun things to play. Which also provides a strong, common base for engineering experiments. All with no money changing hands!! Just people doing things out of pleasure and dedication, making the world better.

The DOOM community, based around a similar but earlier and simpler game, is if anything even more broadly creative and supportive.

I won’t go on – I think you get how I feel about this.

4. At times of low energy, both hardware and software would prefer to scale down…. At these time, people would prefer to do something else than interact with computers.

This is where the radicalism comes in. Viznut doesn’t believe our current civilisation can continue. His is a worldview directly in opposition to values we absorb in school, college courses, news, and so on. (For example, in my one-year computer science course, it was absolutely unquestioned that e.g. ever-increasing virtualisation and cloud storage, or working in a monopolistic platform giant, were desirable things.) None of my close friends, who work in engineering or finance, would find it digestible. I haven’t read up myself on degrowth ideologies although I did learn a lot from the fearsomely knowledgeable Dutchman Kris De Decker who runs Low Tech Magazine. But the highly unpalatable idea is that we’ll all have to stop depending on things we’re used to: unlimited flashy content, new phones and personal gadgets, and quite a lot more; because they take too much energy which ruins the planet.

5. People would be aware of where their data is physically located and prefer to have local copies of anything they consider important.

There are countless ways, most of them still undiscovered, to make low and moderate data complexities look good…. For extreme realism, perfection, detail and sharpness, people would prefer to look at nature.

My quick take on this is I don’t know. I don’t know if Viznut is right. However, my intuition says yes, it is healthier to check out some bark patterns, dewdrops and butterflies in your local park, than clicking through 1080p videos on YT. And that yes, something doesn’t add up when Google offers to host gigs and gigs of my data forever on a server for free, even though it would be a notable responsibility and an effort if I resolved to keep it safe on a disc at home.

(Y’know, on that seemingly facetious point about going outside: I think that could be the unexpected philosophical realisation from our constant exposure to high-quality computer graphics – yes, we human beings like looking at realistic, crisp, crunchy visuals… and they’re all around us, all day long, lit by the sun for our convenience.)

More broadly: maybe the saturation of network bandwidth and processor power that now surrounds us is neither necessary nor desirable? Maybe this thing that we’ve had for the last ten years and not in the preceding ten millenia isn’t yet being used right. Maybe we don’t benefit enough from guaranteed industrial strength computing and data streaming at our fingertips day and night, to justify the environmental cost.

6. Integrated circuit fabrication requires large amounts of energy, highly refined machinery and poisonous substances. Because of this sacrifice, the resulting microchips should be treasured like gems or rare exotic spices.

A great way of putting it! The demoscene that Viznut came from is all about getting the utmost from old technology and systems instead of relying on Moore’s Law. So he has come up with a sound justification for this aesthetic interest, which can often otherwise relapse into mere nostalgia. He’s careful not to tie himself to “junk fetishism” as an end in itself.

7. The space of technological possibilities is not a road or even a tree: new inventions do not require “going forward” or “branching on the top” but can often be made from even quite “primitive” elements.

And here’s a justification for playing with old tech, from the point of view of innovation. It does make sense. Again, what I like about Viznut’s writing is the confident, autodidactic, outsider’s perspective. From there I can look at computing, whether enterprise systems or game modding or web content management, quite afresh.

8. Computer systems should make their own inner workings as observable as possible.

Another lofty ideal. I am strongly, instinctively behind this one. In all the software I’ve coded, I came back to real-time feedback as a tool again and again. Observing changes in a feedback loop suits my short attention span. In my computer science course, I most enjoyed the sensation of tunneling into the depths of a system and making them comprehensible and useful. Even a routine backend database like I made for my e-commerce project gives me this pleasurable feeling.

My site (made for a college project) plucking content from a backend database.

9. Any community that uses computers would have the ability to create its own software.

I interpret this not as a call for us all to be hackers, or teaching “kids to code”. Rather I think it’s a call for a smooth continuum of complexity to be available, from newbie use to full control of building the software. For example, I would say Excel formulas, Access pivot tables, and any kind of macros are an absolutely legit place to start programming. Same with game modding, or shell scripting, LaTeX, whatever. (This philosophy developed from ideas from the lovely, now-defunct blog by James Hague.)

The tricky part is for each level of complexity to bleed naturally into the next, tempting the learner to try new things.

This is where gated platforms, whether that’s FB posts or software on the cloud, can be the enemy of creativity. I’ve discussed that issue before.

10. The ideal wieldiness [of a program] may be compared to that of a musical instrument. The user would develop a muscle-memory-level grasp of the program features, which would make the program work like an extension of the user’s body (regardless of the type of input hardware).

Not much to say to that, except that most of the programs we use day to day haven’t reached that standard.

11. Artificial intellects should not be thought about as competing against humans in human-like terms. Their greatest value is that they are different from human minds and thus able to expand the intellectual diversity of the world.

Viznut’s interest in AI was perhaps the most disconcerting part of his article and the one that changed my outlook the most.

For the last few years I’ve viewed AI as a tech buzzword whose visible manifestations (neural upscaling, Google DeepMind, GPT-3) are distinguished by aesthetic hideousness. And as you might gather, fear underlies that dismissal. I found the thought of AI disturbing.

Viznut gave me a different view. While emphasising the computational expense of training machine-learning systems, he mostly views AI as a welcome new type of entity for us to exist with. Criticising it for being inhuman isn’t saying anything. Rather it can be judged by how well it helps us humans to survive. Pragmatic, yet (in a nice change from how we started this piece) optimistic stuff!

Thanks for reading!

[Cover image is nabbed from Kris De Decker’s astounding Low Tech Magazine website. Do yourself a favour!]

Inspired by “Permacomputing”

I read Viznut’s piece on “Permacomputing” last night and got all fired up. We do live in an age of unparalleled waste of computing resources. He is far from the first to discuss this – I recall Fabien Sanglard‘s and Derek Sivers’ polemics – but Viznut has the uncompromisingly ecological and long-term vision to contextualise and channel the typical hacker’s anger at wasted CPU cycles.

Viznut a.k.a. Ville-Matias Heikkilä.

That made me think of my recent graphics-heavy work, using large resolutions and high-level frameworks; and of the kind of work I see myself doing long term: “coding ceremonial space, presence, substance and light”.

My recent work….

Frankly, I felt indulgent. I think Viznut is right: our civilisation needs to make drastic adjustments to save itself from ecological collapse. And although those changes are gonna be harder than a few well-intentioned Westerners turning to gardening, common sense and intuition and aesthetics and the environmental statistics suggest that permaculture and related ideologies – emphasising resilience, adaptation, local conditions and lowered resource use – may hold more solutions than our current dependence on growth.

When I read Viznut’s weighty opinions I wanted to do some work in the vein of his competition-winning computationally minimal art. Work that uses no more computing power than needed for the goal at hand.

Viznut and his ilk are so much more learned than I am, as coders. They specialise in low-level hardware hacking, an esoteric and difficult topic. However, one skill of theirs is more generally applicable yet fits precisely in the permacomputing ideology. As Viznut puts it, “Optimization/refactoring is vitally important and should take place on all levels of abstraction.”

So I’ll get technical now and chat about how I optimised my most recent learning project: “Iridesce”, a raycaster!

(In case you don’t know what raycasting is, it’s an old and simple way of rendering a maze from a first-person perspective. Windows 95 used it in an iconic screensaver, and it featured in 90s games, most famously Wolfenstein 3D.)

My raycaster is written in JavaScript and so runs in a browser. Try it now if you like!

I used the profiling tool available in my browser, Slimjet (a clone of Google Chrome). This gives an indication of how much CPU time is spent on various aspects of running your site’s frontend code.

The pie chart at the bottom right shows the breakdown.

How did it go? Long story short, I was able to reduce 68% CPU usage to 20%! The things that worked were:

  • Lookup tables – so, instead of calculating the rainbow colour function 400 times per frame, I save all possible values of it into an array and access that instead. This was the biggest single saving and is a pretty classic technique, whenever you have more memory than CPU available. I was also already using a lookup table for the angles of the raycaster.
  • Using the HTML5 Canvas graphics API properly, in particular the ImageData objects which I was using to manipulate raw pixel data. Originally, from a vestigial memory of how raycasters are traditionally done, I was working with one-pixel-wide strips of data for every single segment of wall. This was entirely unnecessary and I saved a lot of CPU time by switching to a single large ImageData object covering the whole canvas. Incidentally, this necessitated some manual byte offset calculations, which felt pleasingly close to low-level.

And what didn’t have much effect:

  • Tidying up to remove nested if statements and repeated checkings of the same condition. This improved the legibility of the program but I don’t think it did much for performance.
  • Removing at least a dozen multiplications from loops. (Taking stuff out of inner loops is another classic optimisation approach.) I really thought this would make a difference, but I couldn’t see it in the stats.

So… the conclusion is pretty clear. Modern computers are stupidly fast at arithmetic. Manual low-level cleaning up doesn’t seem to change much. I’ll still do it for elegance. And I expect I’ll start seeing the performance benefits as I get better at implementing algorithms and doing my own profiling and benchmarking.

But more important than removing those multiplications and ifs, was checking which external functions are taking up time. Using the profiler I could spot that my colour calculations as well as the ImageData manipulations were actually taking up the most time. In both cases there was no need to call the function 400x a frame and I got massive improvements by fixing that.

So that was fun. Am I any closer to sustainable computing? A tiny bit.

Calculating byte offsets is getting into the realm of pointer arithmetic, a skill needed when programming simpler and older machines – increasing the range of systems I could do useful work on.

I learned about profiling and I did some quite major optimising, if mostly by fixing previous poor decisions.

And I got some clarity about what values are important to me, and a good dose of idealism. I’ll keep Viznut’s ideas of communally stewarded, resourceful not resource-intensive, locally appropriate, and aesthetic computing close to my heart as I decide how to direct my energies in projects and job-hunting.

There are other of Viznut’s ideas that I could elucidate through my own practice. How about developing the communal appreciation and understanding of technology in my own family home? Or working on feedback and visualisation of complex system state (I love interactive and live feedback from running systems and that’s how I tackle a lot of coding problems). Or the classic yet delicious challenges familiar from the 80s and 90s: making impressive graphics on slow processors! Perhaps even finding styles and tricks so that the imperfections of low-fidelity enhance the aesthetic affect.

Anyhow. Thanks for reading!

On That Note

This blog was founded to promote study of black music. In the last months anti-racism has become unprecedentedly mainstream with the 2020 Black Lives Matter protests in the US and their global echoes. I support that cause and I’m glad to see this widespread shift in opinion affecting many organisations.

Closer to home, Irish people are channeling that energy into the End Direct Provision movement. Direct provision is a disgraceful, inhumane and wasteful system that deprives individuals and families seeking asylum in Ireland the right to work or cook their own food, for years on end.

The other anti-racism challenge for Ireland, from what I can see, is integrating immigrants, especially second-generation youth, at the community level.

I don’t play music or do musicological research anymore, but the respect I gained for black culture through both of those activities will always stay with me. I love black music so much, I could go on for days! And don’t get me started on the black philosophy, metaphysics, style and other wonders I glimpsed in the course of my old studies.

This blog stands for fairness for black people. How beautiful that will be when we get there, probably only song can express.

Thanks for reading Drum Chant!

The Tiniest Example

Here’s a learning technique I just discovered.

I was working on video rendering on Android devices – reading through and mashing together libraries and example code I found. The task as it’s currently structured has 6 main classes interacting:

  • An extractor to present encoded frames of video from a file
  • A decoder to decode each frame
  • An animator to keep this happening regularly and check if it’s time to show a new frame
  • A view which is the interface element the video will be shown in, and which I’m using as a convenient repository for all the other action (this seems to be pretty standard approach)
  • A renderer which talks to OpenGL, the rendering API

I’ve been bodging everything together in one prototyping/sketchpad project. My approach was to keep it just-about-functional for my one test case (displaying three overlaid alpha-blended video elements) as I swapped in and out components and ported bits from Java to Kotlin.

I definitely learnt a lot from that, but today I tried a different tack.

Instead of accomplishing a fairly complete task messily and crudely, I took the single component I wanted to understand and placed it in a blank, fresh project. Then I tested it!

A boring screenshot

I got the class, TimeAnimator, to report all salient variables to GUI elements. Like debug text but organised so I can see the situation at a glance.

I realised I couldn’t make it do what I thought it had been doing, which was fire events at a steady framerate equal to the video framerate (of 30fps).

I shuffled through variants of the class and learnt what they do.

After a bit, I realised none of them did what I wanted. I went back to the library I was studying and finally twigged that the controlling framerate/timing information came from the decoded video data, which was merely being checked (at a frequency much faster than the framerate) by the TimeAnimator, which is not meant to run anywhere near as slow as 30fps.

So far, so trivial. But I might have kept playing with the original code for ages without actually challenging my assumptions, distracted by all its moving parts and the fact that it looked somewhat like the final product I wanted.

I will definitely be reusing this technique of isolating the smallest component that I don’t understand, and “prickin’ it and frickin’ it” as my favourite rapper Guru might say.

Hope to be back here soon to discuss what this video functionality is actually for!

Synth Sins

Warm analogue it ain’t. I knew when I started coding my synth-sequencer, Foldy, a few months ago, that it’d be harshly digital and crude sounding. I was inspired by tracker software as well as by two old PC-only music programs, Drumsynth and Hammerhead (which were the basis of my beat-creating project last year).

I’m releasing it today and calling it version 1.0. It works, but some iffy design decisions mean I won’t keep developing it.

That said, the code quality is a step up from my last release, the experimental art tool MoiréTest. I was able to go back and make big changes in Foldy, without the whole thing crumbling, which is always a good sign.

For the rest of this post I’ll explain what the program does, then what questionable decisions I made and how I would do it again.

(To try it yourself, download Foldy.jar from here and double click on it. If that doesn’t work try the further instructions in the readme.)

Foldy takes in a musical sequence, which you can type into a box in the app window. Notes are numbered as MIDI notes, where A=440 is at 69, and notes range from 0 to 128, and separated by commas. A rest is -1.

(By the way, did you know that, incredibly annoyingly, there is no industry standard for numbering the octaves of MIDI notes? The frequencies are agreed on, but one manufacturer’s C3 is another’s C4… how sad. This doesn’t impact Foldy though, I just work from the frequencies.)

The speed that notes are played is altered using tempo and beat subdivision controls. All the other parameters in the window modify the sound of individual notes. Only one note can play at a time. This kept things a bit simpler though, with the Java Sound API, opening another output line or mixing two together wouldn’t be much harder.

I was going to include a choice of mathematical curves, possibly Bezier curves, for the amplitude envelope, out of a perverse desire to avoid the bog-standard Attack-Decay-Sustain-Release model, which is suited to a keyboard instrument where a note is attacked, held and released. I was thinking this synth could be more percussive, inspired by the basic sample-playback model of drum machines and trackers (a type of sampler software originally made for Amiga computers and associated with the demoscene).

Unfortunately I didn’t finish the Bezier stuff, but in any case it probably wasn’t suitable. (For one thing, Bezier curves can easily have two y values for one x value.) In fact, I didn’t do any extra envelope options, partly because envelopes typically drive filters or modulations, but these are not allowed by my architecture. If there’s an obvious v1.1 feature, extra envelope curves is it.

One feature that did make it in is “wave-folding”. To get more complex waveforms, I cut a sine wave at a certain amplitude, and invert anything above that amplitude. This can be done multiple times to add a lot of harmonics.

Adding harmonics to a sine wave by folding it at 1/2, then 1/4 amplitude

However, this is a restrictive technique with a distinctive grinding, mechanical sound. All we’re doing here is shaping a waveform which is then repeated exactly at the period of the note frequency. The ear instantly picks up the lack of complexity.

I remember when I was a teenager, having the following bright idea: if I can see that the recorded waveform from my bass consists of repeated bumps, can’t I just sample one of those and repeat it/change the speed of it to get any bass note I want?

Why, chap, it’s simply a bunch of bumps (by the way, don’t record bass in stereo like I did here)

This is the basic concept of wavetable synthesis. However, when done as simply as that, it sounds completely artificial, not at all like a bass guitar. The sound of any real instrument has complexities like propagating resonances, changes in pitch, string rattle and other distortions/energy loss.

(E.g. listen to the low note in this sampled bassline – it’s starts really sharp, then reverts to normal. That’s because plucking of a stringed instrument raises the pitch of the note momentarily, especially on an open string – I think this was an open E string on the original sampled recording, just it’s been pitched up here.)

Foldy has no capability for such modulations. I could try put them in, but here we come up against the compromises I made at the start.

Because I was afraid that rounding errors would mount up and give me grief, I decided to keep everything as whole numbers, taking advantage of the fact that digital audio ultimately is whole numbers: a series of amplitudes or “samples” each expressed as, for example a 16bit or “short” integer. (Most studios mix at 24bit these days, but say CD audio only goes up to 16bit precision.)

This informed the basis of the synth. Desired frequencies and tempos are approximated by a wavelength and a subdivision length expressed in whole samples. 44100 samples per second might seem fairly precise, but for musical pitches, it isn’t. So I found a compromise that bounded pitch error to about 20 cents:

Foldy tries to fit multiple wave cycles within a whole number of samples, for example 3 cycles in 401 samples. This gives a bit more precision, because the wavelength is 401/3 = 133.667 samples, in between the 133 and 134 wavelengths that are all I could get otherwise.

I then use these bits of audio, which I call “chunks”, and which could contain a single cycle or a handful of cycles, in the same way I was using single wave cycles originally. So every note would contain hundreds of them. Then I decided I could reuse this division to store amplitude envelopes – I gave each chunk a starting amplitude, and interpolated between these. (Of course, this is redundant at the moment because my overall envelopes are merely a linear interpolation from maximum to zero! But with a curved envelope, the result would be to store the curve within a few dozen or hundred points, with straight lines from point to point.)

Ugh… I don’t even want to write about it anymore. It wasn’t well conceived and caused me a lot of hassle. It precluded any of the more intriguing synthesis techniques I like, such as frequency modulation, because pitch in this system is fixed for each note (and imprecise).

Long story short, when I opened up the source code of Drumsynth recently, I realised that… it just uses floats and gets along fine. For modulation, it simply keeps track of phase as another float. I should’ve done that.

(That said, I think Drumsynth’s sound quality is far from pristine. This isn’t from rounding errors, I’m certain, but from not doing more complex stuff like supersampling. But, that’s out of my ability level right now anyway.)

Using floats, I still would have had trouble with the timing for the sequencer, probably… but that would have led me to the realisation that I was biting off too much!

It’s not a complete loss. I really enjoyed trying to calculate sine waves while sticking to integer arithmetic . I found out about Bhaskara‘s approximation, implemented it, and then found some really nice code using bitshifts to do a Taylor Series approximation of a sine wave. (I wish I had the chops to come up with it myself!)

Reading the source of Drumsynth also completely changed my approach to the GUI code. I originally had all of the classes that make up the synth – Note, Chunk, Sequence and so on – also be GUI elements by inheriting Java Swing component classes. I think I picked this up from some book or tutorial, but it’s obviously not good. It breaks the basic principle of decoupling.

Drumsynth blew my mind with its simplicity. There are no classes as it’s written in C, an imperative language. The synthesis is just one long function! I almost didn’t know you could do that, having spent a year studying Java and OOP. But given that the app is non-realtime (meaning that there is a third of a second pause to calculate the sound before you can hear it)… this is the sensible approach. Logically, it is one long straight task that we’re doing.

So I ripped out the GUI code from my main classes, and stuck it into one class called Control. Drumsynth’s GUI is even more decoupled: it’s written in a different language – a Visual Basic form that calls DLLs to access the synth functions!

(Yes, I know this is pretty out-of-date inspiration – heck Drumsynth even cheekily uses INI files for configuration though they were officially deprecated – but I think the lesson on directness and decoupling stands.)

My overall lessons from this project are:

  • Do normal stuff rather than trying to reinvent things.
  • Find exactly what draws you to a project and make that the focus. E.g. with this I would’ve been better off making something smaller and more conventional but which allowed me to try some unusual FM stuff.
  • Even though I’ve so, so much further to go, I kinda like low-level stuff. I mean, okay, nothing in Java is actually low-level, but still I was dealing with buffers, overflows, even endianness! Those are fun errors to fix.
  • Read other people’s code!

Even more generally, there’s a kind of tricky question here. This project showed me that it’d be a huge amount of work to approach the quality level of some of the audio programming frameworks out there such as JSFX, VST/Synthmaker, or JUCE. If I’m interested in actually programming synths for musical purposes, I should use one of those.

On the other hand, these are all coded in C or C++ (maybe with another abstraction layer such as EEL scripting language in the case of JSFX). If I really want to understand fundamentals, I should learn C.

But, it’s not very likely I’ll get a job doing high performance programming of that sort, considering the competition from those with as much enthusiasm as me for flash graphics or cool audio, but much more chops! I’m at peace with that – I quit music to get out of a profession that is flooded with enthusiasts.

Stuff to mull over.