On Thursday, L— and I went to Gauthier Soho for a fancy dinner to celebrate our fifth year together. We went for the tasting menu with the wine pairing and … I’m never doing that again.
Not that it was bad! Quite the opposite: the food was extraordinary, and the wine varied, appropriate, and delicious. I ate very sparingly during the day so that I’d have room for all the courses, and that worked.
The problem was that there was just too much wine, in circumstances in which it’s hard to know how much you’re actually drinking. We both spent Friday in a very miserable and hungover state, and didn’t really feel properly normal until Saturday.
I’ll definitely eat there again, I just won’t choose the wine pairing.
While I was lying on the sofa on Friday feeling sorry for myself, weather happened. The storm blew down the fence on the left side of our garden. It was already decrepit, and our neighbour has been promising to fix it for months, so that’s OK. It gives him motivation to do it, and at least he doesn’t have to do it twice.
I went out into the garden to look at the damage. As I stood there, the wind picked up, and blew over the fence on the other side. It was impressive to watch: the wind snapped the posts off at the ankles in a single gust. The fence on that side is our responsibility, but I imagine there will be a bit of a rush on fencing supplies right now.
I did some more work on implementing oscillators for my Pipistrelle module. Before I started, I looked at some existing implementations, but couldn’t understand why they talked about phase so much. Instead, I thought I had found a clever wheeze: at the start of each cycle, I’d calculate the period in samples, based on the frequency, and iterate through until the end of one period, whereupon I’d look at the current desired frequency, adjust the period, and repeat.
In my defence, this does work pretty well at low frequencies. When the sample rate is tens of thousands of hertz, a waveform of a few hundred hertz can be reproduced reasonably accurately. But as the frequency increases, the number of samples per period becomes small enough that the inaccuracy is perceptible.
The solution is the technique that I hadn’t initially grasped: convert the desired frequency f into a fractional phase offset φ and advance through the waveform by this amount each sample. In my case, I have an angle θ that starts at zero and represents a position in the waveform between 0 and 1. I calculate φ from the frequency f and sample rate R:
φ = f / R
and increment θ at each sample:
θ = (θ + φ) mod 1
This is straightforward maths (especially if, as I am doing, you represent a full rotation as 1 rather than 2π), simpler and faster than my initial method, and has the advantage of being instantly responsive to changes. It’s also, crucially, capable of generating frequencies that aren’t a factor of the sample rate.
Sometimes, the best way to understand these things is to work through them yourself.
I also implemented a wavetable oscillator. It works well! Here’s a sample with it being modulated in two dimensions via LFOs:
I’ve tidied and opened the repository for the module but it needs a bit of work to be more welcoming.
I discovered PlatformIO, which provides a much nicer way to work with the Arduino platform than the clunky Arduino IDE with its weird build system. PlatformIO feels like it’s designed for people with programming experience.
I’ve always found Arduino frustrating. The common hardware abstraction is helpful, and there’s a huge range of useful libraries. And for some platforms, it’s pretty much the only development environment there is. However, it’s a bit of a perplexing development experience for someone with previous C or C++ knowledge, and its handling of libraries and insistence on recompiling everything all the time is infuriating.
I had heard of PlatformIO before, but thought that it was a VS Code-based IDE. That does exist, but it’s much more than that. There’s a command-line client that does everything I want: it lets me use the Arduino ecosystem without the Arduino IDE.
All my Pipistrelle code is now using PlatformIO’s build system, which
didn’t take much more than typing
pio project init --board seeed_xiao, moving
src/main.cpp, and setting up dependencies in a configuration
file. It feels a lot more reproducible.
I sold and shipped my Plinky synthesiser. I put myself on the waiting list early enough that I was able to grab one of the (only 200!) kits last year. They’ve been unavailable since, and the chip shortage means that they’re likely to remain unavailable for a long time.
It was fun to play with, but I didn’t really gel with it, so I thought this was a good time to let someone else have a go. I set what I thought was a fair price, more than I originally paid but slightly less than the last auction had completed on eBay, and much less than the comical amounts being asked by a couple of sellers on Reverb. No one likes scalpers!
I was aiming for a local sale, but ended up selling it via Gumtree (no commission) to a musician in Belgium, who wasn’t put off by the customs charges. I hope he gets good use from it.