Songwriting in the A.I. Age

I’m a member of the 12 Song Challenge community, a bunch of people all over the world who help support each other in the art and craft of writing songs for use in our local churches. It’s run by the people at Resound Worship, and I’ve found it to be a wonderful source of inspiration, friendship, and challenge.

Literally a challenge. Each month a songwriting challenge is set, based on a broad theme such as “Songs from the book of Acts” or “Happy Songs”. In November 2024 we were challenged to write songs with the assistance of “Artificial Intelligence”.

Hmm.

I have two problems with this.

I Don’t Believe A.I. Means What You Think It Means

While there’s a lively ongoing debate about what Artificial Intelligence (A.I.) even is, the term is incredibly popular at the moment. However, half the words in it (i.e. “intelligence”) are – at best – misleading. A.I. proper covers a wide range of computer-based systems, but most of the time on The Tnternet people use it to refer to systems that generate stuff from prompts – images, text, audio, or even – as we shall see – music. My gut feeling is A.I. has become popular as a term because a more specific term – for example A.G.S.P.O. (“Artifical Generation of Statisically Probable Outcomes”) – isn’t as easy to say.

The Cloud Is On The Ground

Second, people interact with A.I. systems through websites, often whimsically designed. It’s fun! Easy! And all in The Cloud. Except the cloud isn’t some abstract idea. It is real data centres, running real computers, containing real graphics processors, which require real energy to run, and real water to cool. The explosion in the popularity of A.I. tools – so much so that GPU manufacturer Nvidea became the world’s most valuable company in June 2024.

This reality is a problem. First, there is the mining of materials to produce the chips needed. Secondly, the emissions produced during the manufacture of these chips. Third, the emissions produced by the data centres themselves while running A.I. workloads. And fourthly, the use of water to cool these cips which run very hot. All of that is a problem because at the time we need to drasically reduce manufacturing, consumption, and emissions to help limit the man-made rise in global temperatures, we’re running gleefully into an A.I. future. And for what? Will the price that future generations pay be considered worth it?

Gerry McGovern has been writing about this stuff for years.

So, what do we do?

There’s no putting the A.I. genie back in the bottle. As A.I. tools become more prevalent I hope that more efficient ways are found to generate the energy and perform the cooling required. But I’m not hopeful that will happen fast enough to make a difference to the rapidy rising global temperature.

As Gerry McGovern [almost] says: we don’t have an [energy] production problem, we have an [energy] consumption problem.

The A.I. Challenge

With all that said, I had a songwriting challenge to do. Rather than boycott the entire thing (which was an option I considered) I wanted to use A.I. but keep my use of it to a minimum. I’d heard before that these tools work best when incorporated as part of a human-driven workflow.

As I’ve always found lyrics more challenging than music, I thought I’d start there.

Using ChatGPT for lyrics

I had already decided I wanted to write a song about the wisdom of God being infinetely better than the wisdom of man. Partly because I wasn’t aware of any songs specifically about that, but mostly because I wanted to make a small protest. So my initial prompt for ChatGPT was:

Write a modern worship song about the wisdom of god compared with the wisdom of man. Include descriptions of wisdom as being a voice crying out. Include the idea of wisdom being patient and gentle.

The response from ChatGPT was predictably naff, but was a starting point:

Title: The Voice of Wisdom

Verse 1
In the stillness, I can hear,
A gentle whisper drawing near.
The wisdom of the world so loud,
But Yours, O Lord, it stands unbowed.

Chorus
Wisdom, crying out in the night,
Patient and gentle, guiding with light.
While the shadows of man may sway,
Your truth, O God, will lead the way.

Verse 2
In the clamor, I find my peace,
Your voice, my heart, it will release.
The fleeting thoughts of human pride,
Fade away when You abide.

Chorus
Wisdom, crying out in the night,
Patient and gentle, guiding with light.
While the shadows of man may sway,
Your truth, O God, will lead the way.

Bridge
So I’ll lean on Your understanding,
In the quiet, Your grace expanding.
Teach me patience, teach me grace,
To find my strength in Your embrace.

Chorus
Wisdom, crying out in the night,
Patient and gentle, guiding with light.
While the shadows of man may sway,
Your truth, O God, will lead the way.

Outro
In every choice, in every sigh,
I’ll follow Your voice, I’ll lift my eyes.
For the wisdom of man may come and go,
But Your steadfast love will always grow.

I felt it could do better, so said:

Amend the song to include references about God’s ways being higher than human ways, and his understanding far beyond ours. Use analogies from nature.

And I got this:

Title: The Voice of Wisdom

Verse 1
In the stillness, I can hear,
A gentle whisper drawing near.
The wisdom of the world so loud,
But Yours, O Lord, it stands unbowed.

Chorus
Wisdom, crying out in the night,
Patient and gentle, guiding with light.
Your ways are higher, like mountains soar,
Your understanding opens every door.

Verse 2
In the clamor, I find my peace,
Your voice, my heart, it will release.
As rivers flow beneath the sky,
Your wisdom, Lord, will never die.

Chorus
Wisdom, crying out in the night,
Patient and gentle, guiding with light.
Your ways are higher, like mountains soar,
Your understanding opens every door.

Bridge
So I’ll lean on Your understanding,
In the quiet, Your grace expanding.
Teach me patience, teach me grace,
To find my strength in Your embrace.

Chorus
Wisdom, crying out in the night,
Patient and gentle, guiding with light.
Your ways are higher, like mountains soar,
Your understanding opens every door.

Outro
In every choice, in every sigh,
I’ll follow Your voice, I’ll lift my eyes.
For the wisdom of man may come and go,
But Your steadfast love will always grow.

OK, better, but not quite there yet. I wanted to make it sound a little less formal and hymn-like, as many modern worship songs have a more fluid syllable structure. So I said:

Make the number of syllables for each line in the verse different.

But ChatGPT seemed to latch on to “number of syllables” and added those to the end of each line while making minimal changes:

Title: The Voice of Wisdom

Verse 1
In the stillness, I can hear, (8)
A gentle whisper drawing near. (8)
The world’s loud wisdom, oh so proud, (9)
Yet Yours, O Lord, stands unbowed. (7)

Chorus
Wisdom, crying out in the night, (8)
Patient and gentle, guiding with light. (9)
Your ways are higher, like mountains soar, (9)
Your understanding opens every door. (9)

Verse 2
In the clamor, I find my peace, (8)
Your voice, my heart, it will release. (8)
As rivers flow beneath the sky, (8)
Your wisdom, Lord, will never die. (7)

Chorus
Wisdom, crying out in the night, (8)
Patient and gentle, guiding with light. (9)
Your ways are higher, like mountains soar, (9)
Your understanding opens every door. (9)

Bridge
So I’ll lean on Your understanding, (9)
In the quiet, Your grace expanding. (9)
Teach me patience, teach me grace, (8)
To find my strength in Your embrace. (8)

Chorus
Wisdom, crying out in the night, (8)
Patient and gentle, guiding with light. (9)
Your ways are higher, like mountains soar, (9)
Your understanding opens every door. (9)

Outro
In every choice, in every sigh, (8)
I’ll follow Your voice, I’ll lift my eyes. (9)
For the wisdom of man may come and go, (10)
But Your steadfast love will always grow. (9)

I tried a couple more times, but ChatGPT wasn’t going to improve this, and my A.I. prompt skills are minimal, so I took the lyrics above and used them as a starting point. These are the lyrics I actually wrote, you can see the similarities with what ChatGPT generated.

Verse 1
When the inner voice is loud
And vain desires are shouting out
I think that I can do it all myself
After striving to the end
I find I’m at the start again
I know I need your wisdom and your help

Chorus
Your wisdom is calling
Your wisdom will guide us
Your words like a friend who walks close beside us
Your ways are far higher
Your love beyond measure
We’ll trust in your goodness forever

Verse 2
In the stillness I can hear
A gentle whisper drawing near
It speaks of love too vast to comprehend
In Your mercy I find peace
Your grace will bring my soul release
You know me better than I know myself

Bridge
So I’ll lean on Your understanding
Your ways are higher than I could imagine
Teach me patience, teach me grace
Help me always walk your ways

These lyrics aren’t going to win any awards (I told you I wasn’t good at them) but I have to admit I wouldn’t have got this far so quickly without a kick-start by ChatGPT. So maybe that’s something I can use in the future.

Using Suno for music

One of the most astounding pieces of technology I saw this year was Suno. This A.I. tool takes prompts – you can select musical styles or other prompts, and optionally give it lyrics – and it will generate music, with vocals. The recording quality is pretty terrible, but you do get a fully-produced track. Guitars, drums, bass, keyboards, synths, melodic bits, vocal, the lot. Pretty incredible.

So, I posted my lyrics in, along with the prompt:

Contemporary worship, medium tempo, big build, compressed piano, toms, male vocal

And after a few seconds wait I got this:

Actually, I got two songs – Suno always gives you two options. This was the one I liked better, but interestingly, the verse sounds like it’s ripped off a song by David Brackenbury (another 12 Song Challenger). That’s either a huge coincidence, or there’s something really freaky going on.

The melody isn’t great, there are some things I’d change immediately, and the chords are too predictable for me. But as a start, this is really good.

Conclusions

Clearly this A.I. stuff is amazing technology. And as a tool to give me a creative kick-start it seems very useful. I still have serious reservations about the ecological impact of A.I., but I do think I’ll start to use ChatGPT (or a similar text generation tool) to help me with lyric writing.

Support

A conversation at work last week got me thinking about what we, as web developers and designers, mean when we talk about websites supporting certain browsers. I feel that the word ‘support’ is misunderstood, and has a number of meanings depending on the context in which it is used.

Does it work?

In my experience, people mostly use ‘support’ to describe in which browsers a website will work. However, ‘work’ isn’t an adequate word. Websites rarely do or don’t work in their entirety. Websites are complex collections of dozens, often hundreds of, different commands and API calls. Any mixture of them may or may not be available in a browser accessing the website, depending on the browser type and version. It’s rarely a binary situation where the site works or doesn’t work.

We need to take a more nuanced approach, and realise there are levels of ‘working’ that may or may not make a difference to the user of the website. Those users are the ones for whom the website exists, after all.

For example, many years ago when rounded corners were being introduced in CSS, some pragmatic web developers added the code for rounded corners to their CSS styles knowing that if a browser didn’t understand that code it would ignore it. The corners would be square, but no error would be thrown. Users, unless they were eagle-eyed and knew that the corners were meant to be round, wouldn’t even know the difference.

That was made possible because of the declarative nature of CSS. HTML works the same way – if a browser doesn’t understand a particular element it will render the contents of the tag as text and move on. No error will be thrown. Here’s an example of that flexibility:

<audio src="postman-pat-grime-remix.mp3">This will be displayed in browsers that don't understand the 'audio' element<audio>

JavaScript, on the other hand, doesn’t work like that; it’s imperative. This means that if the browser doesn’t understand a particular piece of JavaScript code it is beng asked to run, an error is thrown. That error may stop further JavaScript being executed on the page. So there’s a big difference in how developers should approach the use of CSS/HTML, and JavaScript. Nuance is the key.

This nuanced approach understands that not all functionality is created equal. For example, for some sites the ability to re-order a table of data instantly (i.e. without a trip to the server and back) is crucial to the functionality of the site. Or, perhaps a particular site absolutely cannot function without CSS grid layout. But these cases are, in my experience, rare. Most sites – not all, but most – require only basic functionality to work, even if they get nicer to use with additional ‘bells and whistles’.

We have to ask tough questions about what our bells and whistles are, and whether the bells and whistles we are adding to a site are really required: especially if they stop users of some browsers using that site.

Can we test it?

The other context people use the word ‘supports’ is when talking about which browsers we are going to test. This is a difficult subject, as we don’t have a hope of testing the huge range of combinations of browsers, operating systems, devices etc out there in ‘the wild’.

Here, we have to be pragmatic. We should look at the site statistics to determine the browsers, operating systems, and devices people are using. But we should bear in mind that if a particular browser or device doesn’t seem to be used much, it might be due to parts of the site not working well for those users – even if they want to use it!

We should also pay attention to global browser usage trends, particularly in the region or demographics our site is aimed at.

So, rather than asking what browsers we choose support, let’s ask what functionality do we need to use. We should make tough choices about the functionality our site actually needs – right the way down to code level; individual JavaScript API calls, CSS properties and values, HTML elements. Let’s remember there are often many ways to achieve a particular outcome, and that users just want to do the job for which they visited the website.

We’ll then find that, rather than just ‘supporting’ a narrow range of browsers, we allow users with a much wider range of browsers, operating systems, devices – yes, and assistive technologies – to use our sites. Accessibility for all is a fundamental principle of the web. Let’s not break it.

Bells and whistles are great, but if they get in the way of the user accomplishing their task then they are nothing but a waste of time and effort.

Mind the gap

Most modern software solutions consist of multiple layers or tiers. Each of these has responsibility for processing inputs and outputs in different ways. For web applications you’ll find a user interface, one oe more APIs which serve data, and probably multiple tiers handling data on the server.

These tiers can be completely separate, as in the case of a web UI and its API. Sometimes they are very closely tied together, for example data access and repository pattern layers in a single component. In all cases these tiers have to – and I realise how much I’m stating the obvious – communicate with each other. So they have to know how to communicate with each other.

Nothing ground-breaking there. But I’ve found that this is exactly where software projects can fail. There’s lots of thought and information gone into how each of the components work, but not so much thought gone into how they will communicate. Here’s an analogy:

Towbar fitted to the back of a car

The humble towbar. Doesn’t look much, does it? A curved bit of metal, with just enough of a shape to allow something to be fixed loosely to the end of it.

Yet this simple bit of technology is responsible for joining two huge components – a car and a caravan or trailer. In many cases the two components it joins are hugely expensive and complicated pieces of machinery – but this simple hook of metal means they can work together.

It’s not glamorous or highly technical, but the specification of this hook had to be known to both of the components it was joining. Without a known and agreed specification there was little hope of successful communication between the components.

Let’s translate that to software. Imagine you’re on a team who need to deliver a web app. The web app must call an API to get some data crucial to the app. The API is being built by a different team, over who you have no control. An architect may put together a diagram explaining when the components should communicate:

Example sequence diagram showing a client app, API, and business rules serverBut without the how this is little use to the development team. The how is the actual specification of those request and response messages – what gets sent, what gets returned.

This detail is crucial and must be discussed and agreed early in the project. This detail is the system. Without known, agreed specifications for all of the communication points between the different components you’re in grave danger of building a bunch of cogs which don’t quite work together.

The specification of those messages allows a number of important things to be discussed and checked-off:

  • What data do I need to send?
    • What is optional? What is required?
    • What are the bounds of the data? Are there any value contraints?
  • What data do I get back?
    • Is everything there that I need?
    • What are the bounds of the data? Are there any value contraints?
    • Are there values which I need to translate in any way?
  • What about errors?
    • What possible error response could I get?
    • What if no response is returned?
    • Is there a timeout I need to cater for?
  • Is this even right?
    • Does this request even need to be made? Am I requesting data I already have?
    • Is there a more efficient or robus mechanism to do the same thing?

These things make the difference between a system which is deployed riddled with potential runtime bugs, and one which you have prepared for as many scenarios as possible.

OK, how do we agree on and document this specification so everyone is on the same page? Or at least, in the same book.

(Thanks to Craig Milner for that last line. He took it further: “I’ve known teams who were not just not on the same page, they weren’t even in the same library.”)

I think there’s a lack of what I’m going to call “3D software architecture documentation”, or at least I’m not aware of any. What I mean is documents which, like the sequence diagram above which shows two axes, also allow the viewer to go deeper into more detail. Imagine if you could click any of those request/response arrows and view the specification for that message. Then click “back” and go back to the more zoomed-out level.

I guess what I’m describing is a web page. Yes, I’ve just invented links. Go me!

And the specification for messages? That’s easy: for REST APIs (which a lot of the time is what we’re talking about) you should use OpenAPI – a standard for describing APIs.

This is what I used when defining the API for a large automotive data company. I wrote the specification for the API using OpenAPI, it could then be “navigated” using an OpenAPI viewer, and discussed by the team before we built anything. Once a part of the API was built we could then compare the output with the original spec.

Sometimes, pragmatic changes had to be made so the real API was slightly different to the specification – these changes were always discussed during development. But more often than not, because adequate thought had gone into a high-enough resolution specification, the developers knew exactly what to build.

This approach is “design-first API development” as you design what the API is going to look like up-front before you break ground writing any code. This same approach can be used for different types of components – GraphQL APIs, SOAP, even code-level interfaces.

So the takeaway here is to spend some time early in a project to talk about and document how components will communicate. That’s the detail which can make or break a solution.

This is starting to get silly

It’s been a while since I made any LEGO office equipment. I had to fix that.

I found my desk getting cluttered with a few bits I always had hanging round:

  • Pens and pencils
  • Headphones
  • Short USB cables (for charging my phone etc)
  • Couple of small backup drives
  • USB memory sticks
  • USB adapters
  • Capo (I play a bit of guitar)
  • Plectrums. Should that be plectra?

All necessary, all needed at my fingertips, but messy to leave lying around. So I built a desk tidy.

My LEGO desk tidy

It’s got a place for everything, and everything in its place. Somewhere to put my plectrums/plectra.

Plectrum holder in my LEGO desk tidy

A pot on top for USB memory sticks and adapters, and any other small knick-knacks.

Small box of bits in my LEGO desk tidy

Cable hooks on each side. I decided against a more complicated system to store cables as … well, it’s not needed.

Cable hooks on my LEGO desk tidy

Round the back is a bracket for my capo. There are actually two brackets, not that I have two capo (capi?) but I needed the unit to be symmetrical.

Capo bracket on my LEGO desk tidy

And there are two caddies for storing the backup drives. I’ve also got an eraser in there, too.

Backup drive storage in my LEGO desk tidy

This was a fun little project to build! But I need to stop, as my wife is starting to think I’m strange. Or rather, stranger than she already thought I was.

More LEGO office equipment

Oops, I did it again.

The arrival of another laptop meant I had a requirement for another laptop stand. Yes, of course I made it out of LEGO!

LEGO laptop stand number 2

I decided on a simpler design this time, with no attempts at making it adjustable.

Side view of my LEGO laptop stand

I also made the cable tidy smaller and more integrated.

A laptop stand made of LEGO

And finished it off by adding a few mini figs, including Spiderman.

Some LEGO minifigs guarding my LEGO laptop stand

I have to say I really enjoyed this, and am trying to think of other office equipment I can make out of LEGO. Any ideas?