Uncomfortable – a different approach to songwriting

Logic's arrange window for this song. Logic player tracks are in yellow, vocals in green, guitars in purple, orange and red. It also shows automation curves for various parameters, mostly volume/gain, but also some plugin enable/disable switches.

This song takes the perspective of a woman receiving unwanted attention at work, how this makes her feel uncomfortable, and how her friends support her in dealing with it. My intention is to draw attention to the fact that this happens too much, that we (men) should call out this behaviour, and help when we can. In addition to my small attempt at empathy, this is also something of a technical experiment in songwriting which is quite a departure for me. Hit play and keep reading!

Apple’s Logic Pro 11 added “session players”, virtual musicians that can decide what notes to play, and I thought I’d have a go at using them. There is a long history of generative virtual musicians, like the algorithmic “M” by Intelligent Music (released in 1987, before search engines existed…), and the pattern-based “Band in a box” (released in 1990, and still going!). Logic’s session players are very similar in style to the “drummer” tracks that were introduced in Logic Pro X in 2013 (I feel old!), and that I’ve used extensively, but add a melodic and harmonic layer. This means that they have to be told what chords to use, and so Logic Pro also added a “Chord track” to do exactly that. You can also have separate chord sequences for individual regions within a track so different players can play different chords at the same time, instead of all sharing the global set, but I’ve not used that here.

Now we come to a bigger problem: which chords to play? Logic has an overall key signature, and given that, it can suggest popular chord progressions for the chord track, like i-III-VI-VII, which it uses to pick chords from the current key. I tried messing around with different keys and progressions, and came up with something I liked (ending up in D minor). Then I thought I would try playing with time signatures, as (unlike me) these players don’t get confused by things that are not in 4/4, and ended up with a nice rolling pattern in 7/8, which is also slightly “uncomfortable” and off-balance, which I thought would go well with the theme of the song.

The built-in chord progressions are very limited, and unfortunately, so is my music theory. So I turned to Anthropic’s Claude LLM for some suggestions on how to continue my song:

A portion of a chat session with the Claude LLM, showing a request for a "happy" chord sequence to follow the verse, and it providing a suggestion, and describing why it chose those chords.
Claude prompt and response providing chorus and bridge chord progressions

I experimented with variations on this prompt, plugging the chords into Logic until I was happy with the result; you can see the same chord names appearing in the chord track:

A portion of Logic's arrangement and chord tracks for this song showing sections and chord names, such as Dm C Bb A7, etc
Logic’s chord track

It wouldn’t surprise me if Apple goes much further in this direction. With the local AI engine scheduled for macOS 15 and iOS 18, it would seem an obvious target. Music theory rules are far simpler and mathematical than written language, and thus a great candidate for a smaller (when compared to gigantic online models like Claude) learning engine to produce good results in a constrained, lower-resource local environment. The session players already achieve great results without any such AI engine.

I’m not going over the top with these players; I’m using one each of the bass and keyboard players, with very conventional electric bass and classic rock organ instruments, along with liberal use of their complexity, swing, humanisation, and simulation features. I think the bass in particular sounds great, really believable when it’s by itself, like at the very beginning.

A screen shot of a bass player instrument region and some of its settings including complexity, intensity, and controls for scale notes to use, octave range, phrasing, and fill settings. The top of the image shows a map of the notes it has generated for the current key and chord track.
A bass player instrument region and some of its settings

With all that done, I had a decent backing track, and it was time for lyrics and vocals.

Logic's arrange window for this song. Logic player tracks are in yellow, vocals in green, guitars in purple, orange and red. It also shows automation curves for various parameters, mostly volume/gain, but also some plugin enable/disable switches.
Logic’s arrange window for this song, also showing parameter automation

For years I’ve seen endless stories of women (especially in tech) being subjected to miserable, denigrating, sexist, misogynistic bullshit and unwanted attention. This is something I’ve never had to deal with myself (being a stereotypical cis, middle-aged white man), but I know it happens, and I wanted to do/say something positive that I might not have done/said otherwise. I’m not looking to usurp womens’ ability to stand up for themselves, just to show some empathy. To that end, my inexperience may have resulted in something overly naïve and optimistic, however, I didn’t want to write a negative or pessimistic song, and I doubt many want to listen to one either!

To try to ensure that I wasn’t treading on anyone by doing this, I asked several women to read this and listen to the song before I promoted it anywhere. I received generally positive feedback, from “No red flags” and “…release it. It’s good”, “that’s really cool”, “love the voice”, “We like this”, “it’s a great song to have written. Raising awareness of these kinds of problems helps, [no matter who] raises them”, to understandable concerns about big AI’s inherently exploitative nature, and my presumption of speaking for women. Songs written from a different gender’s perspective are not at all unusual: almost everything by Abba was written by men from a woman’s perspective (and not all of it flattering!); Aerosmith’s “Don’t want to miss a thing” was written by a woman from a man’s. If I was using this song to be negative about women, or to displace someone else’s efforts, I would expect severe and justified pushback, but I’m not doing that, and I think the song has a good message regardless of who wrote it. In the other direction, I’ve not had any complaints from men about how my representation of their actions might be considered unfair – but I wasn’t expecting that anyway. Ultimately, it’s just a song, with a little empathy, and a big dose of technology.

The lyrics are a little cheesy in places (yes, Claude is very helpful for finding rhymes!), and I use “attention” too much, but I hope they do the job of conveying the discomfort of unwanted attention, and the relief when it goes away and you have a support network to fall back on. Some might dismiss this as “woke”, but they are likely the ones that this doesn’t happen to, and I didn’t write this song for them.

[Verse]
I’m minding my own business;
Maybe you should try that too.
Consider that maybe, just this one time,
it’s really not about you.

[Chorus]
I’m not seeking your attention,
just trying to get through my day.
You’re gonna make me uncomfortable
if you carry on this way.

[Verse]
With all this unwanted attention
I could be flattered some other time.
Your persistence won't change my mind;
the decision’s only mine

[Chorus]
I’m not seeking your attention,
just trying to get through my day.
You’re gonna make me uncomfortable
if you carry on this way.

Your inappropriate advances,
just confirm what I should’ve known:
You’re making me uncomfortable;
won’t you leave me alone?

[Break]

[Verse]
No, I don’t need your permission
to choose the people that I like.
My friends respect my life choices,
and support me day and night.

[Chorus]
Now I’ve avoided your attention
my friends say they can see
I’m feeling so much more comfortable
in their good company

For the vocals, I turned again to the still-astonishing Synthesizer V Studio Pro (SV) from Dreamtonics, with its excellent Solaria voice. I’ve written about SV before, if you’d like to know more about how SV works. One specific point that I’ve been asked about is that SV is not “AI” in the ChatGPT sense; its voice models are created from specific individuals who are paid and credited for their work, not by slurping monstrous quantities of stolen, uncredited, unpaid input and generating unethical approximations as most public LLMs do (and I recognise this includes Claude). It’s not a huge sample library like many virtual instruments, but a tuned algorithmic approach, more like what Pianoteq does for piano synthesis, though not going as far back to first principles. I don’t see any ethical issues with using synthetic voices created this way; artistic concerns are are a different matter, though so long as they continue to sing better than me, I will keep using them!

SV still has problems integrating with Logic – its tempo sync is hopeless, so I’ve had to stick to a fixed 100bpm. It lacks support for other time signatures, so bar numbers and loop points are never in sync when working in 7/8, and note placement involves a fair bit of trial and error. Despite all that, it’s still quite workable, and sounds great. I made a particular point of adding breath sounds, which really adds to the realism. I did the backing vocals with SV too, and for some reason I found them quite tricky this time, much more difficult than in my other songs, probably because this song is more complex than my others.

At this point I had a workable song, but it needed something more than a semi-automated backing track. I attempted to play some guitar parts myself, but I found the 7/8 timing difficult (I did find it’s easier counting 1-2-3-4, 1-2-3 than 1-2-3-4-5-6-7), and I’m no good at playing B♭ bar chords cleanly, so instead I found the amazing Wassim Rahmani on Fiverr.com and commissioned him to create rhythm and lead guitar tracks. He did a great job; there’s some lovely, liquid playing here, Clapton-ish in places, and he created a much more satisfying ending than I started with.

After that I needed to mix and master, as usual trying to keep all these parts from treading on each other, dialling back the reverb to avoid muddiness, checking stereo spread, not going overboard on compression or levels. I used Logic’s new Mastering Assistant, which gives nice high-level control over global EQ and dynamics. I’ve previously used Logic’s mastering presets (a less sophisticated approach), and IK Media’s Ozone, but the assistant is easy to use and sounds great.

Logic’s Mastering Assistant at work

In all I’m pretty happy with this song. It’s got a good message, and is musically more ambitious than other things I’ve tried, thanks to some artificial assistance. It still feels like an engaging, creative process, but the balance has shifted slightly higher, towards directing and producing, and away from choosing or playing individual notes. I also see clear parallels between what I asked of Claude, and what Wassim did for me, and I’m not sure how I feel about that.

If you like this song, please consider supporting me by buying my albums on Bandcamp, and sharing links to my music on your socials.

The HTTP/3 Book

Today I published my first book, “The HTTP/3 Book”!

This book is the latest incarnation of things I’ve produced relating to HTTP/3. The first was a conference talk I first gave at ConFoo 2024 in Montreal. That went down pretty well, and I was asked to do the same talk at the International PHP Conference 2024 in Berlin. The room was so packed for that talk that they have asked me back to do the same task again at IPC Munich 2024 later this year!

S&S Media, the German company behind IPC, publishes lots of magazines for developers, and I was approached by their representative in Berlin about writing an article on this subject. So after a little negotiation (particularly about rights!), I sat down to turn my talk into an article. This was made quite easy given the framework I had from my talk, but I was pretty pleased and surprised to be able to crank out a decent 4,000 word article in a bit over 2 hours. It’s not been published yet, but I’ll amend this post when it has.

I’d enjoyed writing this article so I wondered about expanding it into a short book. Asking around on Mastodon suggested that the easiest way to go was self-publishing on Leanpub; I didn’t want to get pulled into writing some monster tome for a publisher.

It took about 2 days of writing, plus another day or so learning the ins and outs of the Markua markup format, tweaking, proofreading (thanks to my mum!), drawing diagrams, and building a site to demonstrate the difference in network activity across different HTTP versions.

A week on from my first thoughts of doing this, I’m very happy to find myself with a freshly published 54-page, 12,000-word book! I’ve of course publicised it across all my social media, but need to put a bit more effort into marketing, perhaps look into Leanpub’s translation services. Anyway, we will see how it goes, but it’s been a good experience so far.

Blue Team – The Song

In the world of penetration testing, as I’m often involved in with ROS, those taking on the role of attackers are referred to as the “red team”, and those defending as the “blue team”. Red team people are often regarded as the rock stars of INFOSEC, but one key difference is that red-teamers only have to succeed in their efforts once, whereas blue-teamers have to succeed every time. Unfortunately, when the blue team succeeds, nothing notable happens, so they don’t get much of the glory.

This song is a tribute to the unsung heroes of the blue team; Gotta keep out the bad guys, baby!

Unsurprisingly, the “gotta keep out the bad guys” line was about the first thing I thought of, and everything stemmed from that. There were lots of blue-teamy things I could have written about, but I preferred to keep it short. The string-bend bass riff was the first bit of music, then the funky guitar parts, though I ended up dialling them back a bit in favour of some chuggy rhythm guitar. As in my other tracks, I was keen to use Synthesizer V for vocals, and the backing vocals came out really well. I wrote the lead guitar solo, then thought a higher vocal part alongside it might work, and it was also a chance to have a dig at the red team; it’s my favourite bit of the song.

There are a lot of guitar parts overall (all played by me), and only some small pad and organ keyboards for backing. I was especially happy that I managed to pull off the more aggressive bass parts and the lead solo. As usual, the drums were all done with Logic’s Drummer instrument, which does a great job without getting drunk and falling asleep during rehearsals, and its excellent “follow” mode meant that the drums could match what I’d played on the bass, rather than being some disconnected pattern.

As usual, I’m not too happy with my vocals (PRs welcome!), but Logic’s Flex Pitch editor works enough magic to get the job done. This track could really do with someone that can get a bit more grungy in the verses, with a hint of Elvis for the chorus.

[Intro]
Don’t break a sweat
from a constant threat.
We’ve got the tools to meet them
and firewall rules to defeat them.

[Verse]
We’ll take our time
to build our defences.
No need to be concerned,
we know the consequences.

They’re going to attack
our networking stack,
but we can keep them guessing as
their port scans come to nothing.

[Chorus]
Because, I’m on the blue team, baby,
we’ve got to always win.
Gotta keep out the bad guys,
can’t ever let them in.

Come join the blue team, baby,
we need your awesome skills.
Come watch that bad actor
try to guess my second factor.

[Solo]
Oooh red team stays outside,
don’t want you here.
Just go away
and don’t come back.
You’ve gotta find another way.

[Verse]
Alarm bells ring
from a tripwire’s string.
Logs tell a sad, sad story
of a search for a way in.

SOC screens flash
for a matching hash
We’ve seen this one before
and there’ll be many more

[Chorus]
That’s why I’m on the blue team, baby, (ooh yeah)
we’ve got to always win. (blue team, blue team)
Gotta keep out the bad guys, (ooh yeah, gotta keep out the bad guys baby)
can’t ever let them in.

Come join the blue team, baby,
we need your awesome skills.
Show your strength, let it shine,
help take those APTs offline

We’re on the blue team, (ooh yeah)
got to always win. (blue team, blue team)
Gotta keep out the bad guys, (ooh yeah, gotta keep out the bad guys baby)
can’t ever let them in.

We’re on the blue team, baby,
we’ve got to always win.
We’re the unsung heroes.
(gotta keep out the bad guys, baby)

If you like this song, please consider supporting me by buying my albums on Bandcamp, and sharing links to my music on your socials.

Laravel duplicate key error despite unique validation

In a Laravel API, it’s really common to create users with an endpoint like this in a user controller:

public function store(Request $request): UserResource|JsonResponse
{
    $validator = Validator::make(
        $request->all(),
        [
            'email' => 'required|string|max:255|email|unique:users',
            'name'  => 'required|string|max:255',
        ],
        [
            'email.unique' => 'That email address already has an account.',
        ]
    );
    if ($validator->fails()) {
        return response()->json(
            [
                'error'   => true,
                'message' => $validator->errors()->all(),
            ],
            Response::HTTP_UNPROCESSABLE_ENTITY
        );
    }
    $user = User::create(
        $request->only(
            [
                'email',
                'name',
            ]
        )
    );Code language: PHP (php)

There’s a problem here though – that unique validation on the email field is subject to a race condition. If two requests are received very close together, both can pass validation, but then the second one will fail with a duplicate key error on the User::create call. While that sounds unlikely, it happens for real sometimes, and you’ll see something like this in your web logs when it does:

192.168.0.1 - - [06/Oct/2023:07:08:54 +0000] "POST /users/ HTTP/2.0" 201 1276 "-" "okhttp/4.9.2"
192.168.0.1 - - [06/Oct/2023:07:08:55 +0000] "POST /users/ HTTP/2.0" 500 17841 "-" "okhttp/4.9.2"Code language: JavaScript (javascript)

The 201 response is a successful creation, but it’s followed a second later by a 500 failure for the duplicate request. The Laravel log will then contain one of these:

[2023-10-06 07:08:55] staging.ERROR: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'user@example.com'
 for key 'users.users_email_unique' (Connection: mysql, SQL: insert into `users` (`email`, `name`) values (user@example.com, Test)Code language: JavaScript (javascript)

To deal with that we can trap the creation error, and return an error response that looks the same as the validation error:

try {
    $user = User::create(
        $request->only(
            [
                'email',
                'name',
            ]
        )
    );
} catch (QueryException $e) {
    //1062 is the MySQL code for duplicate key
    if ($e->errorInfo[1] !== 1062) {
        //Rethrow anything except a duplicate key error
        throw $e;
    }
    return response()->json(
        [
            'error'   => true,
            'message' => 'That email address already has an account.',
        ],
        Response::HTTP_UNPROCESSABLE_ENTITY
    );
}Code language: PHP (php)

This way, as far as the client is concerned, it was a straightforward validation failure with an appropriate 422 error code, and we don’t get spurious 500s clogging up our error logs.