Toronto, Ontario, Canada

Maximizing inharmonicity

2017-12-17

As I've said before, I'm interested in slow ambient drones - sounds that smoothly change their texture over a period of time without any sharp boundaries or beats. If you have something like this playing in the background, I want for it to never grab your attention, but when you occasionally do focus on it, you notice something different each time. In my " Totally tubular" posting last month, I talked a bit about making inharmonic bell sounds using a hardware modular synth. This week I've been playing with additive synthesis in the Csound software modular.

One idea I've been playing with is to maximize the inharmonicity of the sine-wave partials in a sound. As mentioned in the bell posting, there's a tendency for some kinds of natural sounds to be made up of partials that are all multiples of some fundamental frequency - and when they do fit this pattern, the partials are called "harmonics." When you play two notes together, both of them made up of harmonics this way, the partials will tend to coincide if the fundamental frequencies are in a small-integer relationship to each other. And when that happens, it's often the case that we consider the two notes to sound good together and to merge into a single harmonious sound.

For instance, playing notes with fundamentals in a 2:3 ratio means every second harmonic of one note will coincide with every third harmonic of the other - and those two notes will be in the musical relationship called a "perfect fifth," an interval so very consonant that standard guides on how to write counterpoint forbid using it too freely because it causes the voices to lose their separate identity. If I'm trying to build up a sound by additive synthesis of sine-wave partials and I want it to sound interestingly unlike what people expect of music, then maybe I want to make the partials as much not harmonic as possible. Assuming I can somehow define that in a rigorous enough way to actually know when I've achieved it.

Minimax Optimization

Suppose I've got two partials separated by an interval x measured in cents (1200 cents = 1 octave). If I want to measure how close x is to a small-integer ratio, I can compute a function something like this:

(math)

In words, working from the inside out: the "1200 log" business just converts the ratio p/q into cents. Subtracting that from x and taking the absolute value gives the answer to the question "How many cents away from a perfectly just p/q interval, is x?" (For instance, this is about 2 for the difference between a 12-EDO perfect fifth and a just perfect fifth.) Then 250/(p+q) is a measure of how much we consider p/q to be a "small" integer ratio; the bigger p and q are, the smaller that number. Subtracting the error from it, we get a measure of how harmonic x sounds with respect to the p/q interval in particular. And then the "max" operation says, find whichever p/q interval is worst (giving the highest score). A fun feature of this formula is that even though it asks for evaluating an infinite number of different p/q intervals, we can still calculate it in finite time! That is because the thing inside the "max" operation is never greater than 250/(p+q). If we write a loop that examines different p/q ratios in order of increasing (p+q), and keep track of the highest score we see, then as soon as 250/(p+q) gets to be less than the current maximum, we know we can never see any larger value and terminate.

Here's a plot of what this harmonicity function actually looks like:

plot of the harmonicity function

There's a big spike at zero; two notes that are the same frequency, are maximally harmonic. The next biggest spikes are at plus and minus 702 cents: notes a perfect fifth apart are very much in harmonic relation to each other. And so on. So this gives a plan for making a sound that is somehow as inharmonic as it could possibly be: we'll just choose a frequency for one partial, choose another to minimize the harmonicity function with respect to the first, choose a third to mimimize its harmonicity with both the previous partials (by summing the two values? by taking the max? or what?), and proceed like that until we have enough notes to make an interesting sound.

Well, it doesn't really work very well. First of all, as you can see from the plot, this is a terrible function to minimize! The biggest peaks are easy to spot, but the interesting part for making inharmonic sounds is down in the valleys between the peaks, where there are lots of tiny wiggles. Also, it's not clear that finding the globally minimum value is even all that interesting if you could do it, since all the tiny wiggles at the bottom of the chart are about at the same level anyway; you won't really hear differences in harmonicity between them. This does not really provide much guidance on where to choose the next note at a given stage. There's a general trend toward lower scores at the edges of the chart, but that just means that the simple algorithm of picking a new partial as inharmonic to the existing ones as possible, will be forced to the top and bottom of the pitch range much more often than sounds good.

When I tried to implement it in ECLiPSe-CLP I also ran into a bunch of technical annoyances with minimizing the value of a function that is itself defined as the maximum of another function. I ended up hacking together some code and then doing a lot of manual querying for every note to simulate the minimax operation that I hadn't been able to automate as well as I'd wanted. I added a bunch of fudge factors to guide it away from choosing the top and bottom of the pitch range all the time. And I did end up creating some sound, but I wasn't really satisfied with it. So here's the best chunk of audio I was able to generate from this inharmonicity measure, and a spectrogram, but I won't discuss it further in favour of going into other ideas.

MaxInharm Drone I

spectrogram of "MaxInharm Drone I"

A Side Trip to Mathmagic Land

The next idea is to try to set things up so we don't need to do a hairy computation. With a better understanding of the math involved, can we come up with some kind of easy formula that generates a set of frequencies guaranteed not to be multiples of any common fundamental?

For just two frequencies, it's easy: put them in an irrational ratio. If x and y are at a ratio of the square root of two (1.414...), for instance, then we know they cannot possibly have any harmonics in common because if they did it would imply that root-two is a rational number, which is not the case. So this sounds promising, especially when we consider that root-two is exactly half an octave and corresponds to the notorious tritone musical interval (the Devil in Music!) which is generally agreed to be very dissonant. As a matter of fact, any two notes on the standard 12-note system (other than those an integer number of octaves apart) will be in an irrational frequency ratio... which should already be a clue to what might go wrong with this plan.

It's not instantly obvious that this idea can scale to more than two notes. If we choose y to be 1.414... times x, and z to be 1.414... times y, then we have x and y profoundly inharmonic with each other, and y and z the same... but z is just twice x, an exact octave and quite harmonic.

The problem comes about because although the square root of two is irrational, it's in some important way not so very irrational. We need to use some other number that is more irrational, whatever that means, so that it won't turn back into a rational number after we multiply by it repeatedly. The most obvious thing to ask for is a so-called "transcendental" number; π is a famous example. These are numbers not the roots of polynomials with rational coefficients, which is sufficient to guarantee that if we start raising them to integer powers, none of the powers will be in rational proportion to one another.

But some of that deep number theory I'm trying to ignore has a rather startling consequence: the more irrational a number is (as measured in the way mathematicians usually do), the easier it is to approximate that number with an integer ratio! Using a transcendental number would mean that although we don't exactly hit any harmonic relations among our partial frequencies, we would nearly hit such relations more than necessary. Instead, it seems like we would want a number that is hard to approximate with rationals. It turns out that the Golden Ratio (ϕ, 1.618...) is in some sense a number that is maximally difficult to approximate with rationals, which indirectly implies that all its integer powers are also hard to approximate.

That gives a framework for an ambient drone. We just choose a bunch of partials in the form pϕq, where p is a rational number and q is an integer. Fade them in and out (at random, or according to some artistic plan) and just make sure never to have two playing at the same time with the same value of q, and we will be guaranteed never to have two partials with a harmonic relation nor even (in some complicated number theory sense) any two nearly harmonic to each other.

I played with the powers-of-Golden-Ratio idea a little, but ended up scrapping it without producing any finished music, because it has many of the same problems as the minimax optimization. Note that this formula allows p to be any rational number. There are very many of them - in particular, an infinite number arbitrarily close to any real number. Bearing in mind that ears and computers have limited frequency precision, this formula doesn't really place any constraints on frequencies that could be chosen. Any frequency, no matter how bad from an artistic point of view, is arbitrarily close to an infinite number of frequencies allowed by the formula and could be chosen to within our selected level of precision; no frequency is meaningfully ruled out, and the formula gives no guidance on how to choose among the allowed frequencies.

So we could get similar-quality results by purely picking frequencies at random within a selected range and doing no further processing; and if we introduce other rules to prefer some frequencies, those rules will become the main story, edging out the Golden Ratio. It might indeed be a reasonable way to write a piece of drone music, but it puts all this fancy math to waste.

Greatest Common Divisors

The third concept comes from stepping back and looking at priorities. From the minimax idea, we can learn that it may not be so useful or important to really find the most inharmonic frequency for a partial. Any frequency that is quite inharmonic will do. But we need to be able to process these frequencies computationally in a way that is easier than the minimax optimization I was trying to do. From the Golden Ratio idea, we can learn that it's important to be able to rule out frequencies in a meaningful way, and do something that takes into account ears' limited frequency resolution.

Putting these together, I decided to explore a different inharmonicity constraint. Instead of requiring that no two frequencies be multiples of the same fundamental, let's require that all frequencies are multiples of a single fundamental, but choose one far enough below the audio range that people won't perceive it as a note. In practice, this means less than about 10Hz. People can hear physical sound down to about 30Hz, but can perceive implied fundamental frequencies a little lower, a fact exploited in some organ music. However, we'll require that no two partials can both be harmonic multiples of any common fundamental higher than the fixed base. In other words, all partials are integer multiples of the base frequency but the greatest common divisor (GCD) of any two of those integers is not allowed to be anything but 1.

For example, it would work to choose the multiples all to be different prime numbers - but there are also other ways to choose them and satisfy the constraint.

I wrote a Csound orchestra, which you can go read to see how it works if you want, that implements this idea. I set the base frequency to 7.83 Hz (for symbolic value - this is the lowest Schumann Resonance frequency) and put in an extra rule that any two partials must be at least three of these frequency increments apart. That is to get rid of low-frequency beats between nearby partials, which I find distracting. The idea is that in the "score" part of the Csound file, I specify notes corresponding to a partial playing for some length of time; but the notes don't specify particular frequencies. Instead, each note specifies a range of frequency multiples, along with its duration and amplitude. During Csound rendering (which in fact is fast enough it could probably be realtime, though I do it offline), when it hits one of those notes, my code will scan possible multiples in the allowed range, and compute their GCD with all other currently-playing notes. It'll choose uniformly at random from among the ones that obey the GCD=1 and "minimum distance to other notes at least 3" constraints.

For example, if frequency multiples 5 and 8 are playing and I ask for a note in the range 2 to 15, the evaluation would go: 2 is not allowed (common divisor 2 with 8), 3 to 7 are not allowed (too close to 5), 7 to 10 are not allowed (too close to 8), 11 is allowed, 12 is not allowed (common divisor 4 with 8), 13 is allowed, 14 is not allowed (common divisor 2 with 8), 15 is not allowed (common divisor 5 with 5). And then it would choose uniformly at random either 11 or 13, add the result to the set of currently playing notes, and until one of the three notes ends, any new notes would be checked against all three.

I drew a score by hand to plan out when I wanted to play different lengths and frequency-ranges of notes. It says "Euclid's" at the top because I'm using Euclid's Algorithm to compute the GCD. I ended up deciding not to use that name as part of the title of the piece.

score for "MaxInharm Drone II"

There was a fair bit of back-and-forth with the Csound renderer because on my first several tries, it got into situations where it couldn't choose a note. All the multiples within the range I'd asked for, were forbidden by various rules. So I kept trying different random seeds, expanding the ranges, in a few cases reducing the density of notes to request, and so on. You can see in the spectrogram (click to enlarge) that the result still sort of follows the plan in my hand-drawn score. Note the spectrogram has a linear frequency scale and my score is logarithmic (linear in perceived pitch), so the top of the spectrogram looks stretched relative to the score.

spectrogram of "maxinharm drone ii"

And here is what it sounds like.

MaxInharm Drone II

This isn't the last word on automatically generated drones. I don't like all parts of the piece, but at least some of them sound kind of the way I wanted. And it was an interesting project, at least. I hope some of the ideas here will be inspiring for readers.

A few other random things

Remember that December 17 - the day I'm posting this - is the last day to order from North Coast for shipping before I go off to visit my family for a few days. Orders placed after that will ship on or after December 28. I'm not actually gone the whole time; some safety buffer time is included at both ends.

On January 13, it is planned that I will be appearing at Frequency Freaks in Toronto to demo and talk about North Coast modules. If you're in or can easily travel to the city, you might like to come see that.

I had an idea for a nifty little module that would be easy and fast to get working (famous last words, I know) and I'm thinking of trying to develop it quickly as soon as I get back from my trip, with the hope that I could get a prototype working well enough to demo in mid-January. No official announcement yet, but here's a teaser of the schematic.

mystery module schematic

Some changes in my software configuration have made it appear that doing live-streaming video - which I had once planned to do, but then it seemed like I couldn't get it working - may actually be more of a possibility than I thought. So I'm toying with starting that up again in the new year. Would you watch a live stream from North Coast? What would you want to see in one?

Modular synthesis intro, part 2: Don't do it! || Modular synthesis intro, part 3: How to get started

MSK 014 Gracious Host

MSK 014 Gracious Host

US$240.55 including shipping

Anti-spam, fill in the blank: Coast Synthesis

Subscribe to our newsletter