I was born with something not quite like perfect pitch, but when something is even slightly off tune it caused physical discomfort for me.

My cs department had a cool project class where you built what was basically a raspberry pi with a microcontroller by hand, and you had to use the dumb speaker and controller to make your own music firmware to produce notes. the challenge involved, was basically, the processor’s clock wasnt fine grained enough to produce perfect notes. I wanted to make a simon says toy but the notes were off. I approached my professor with my problem and he said I could cheat the processor clock in a clever way to get what i wanted and it was such a “oh wow computers are magic” to me, i got the notes i wanted. disappointingly the TA grader wasnt that impressed but that proff ended up offering me a job before I graduated.

> I was born with something not quite like perfect pitch, but when something is even slightly off tune it caused physical discomfort for me.

Define off tune? 12 TET? Just intonation? Bohlen-Pierce (56 TET) ?

The "in tune" notes are as much a function of culture as physics.

> The "in tune" notes are as much a function of culture as physics.

Huh? Pitch ratios are not a social construct, it's just arithmetic.

There's definitely some physical underpinnings--most music systems have the concept of an octave which maps nicely onto frequency-doubling, for example. But there's also culture: For a purely Western example, even-tempering is in tune, but you'll hear different "beat patterns" for a given interval than with an instrument tuned for music in just one key.

And the choice of which ratios "sound good" is cultural, to some extent.

Do say more! What was the problem with the clock, more exactly? I believe you, I've had issues caused by clock skew and CAN bus for example, when you have a small error that is amplified on beach bit enough time, errors add up and you eventually get out of synch.

But in the case if sound, I would have expected the skew to be less of a problem. Also surprised how the orof instantly know. It took me a while to figure out. How did you fix it? Cool story!

One simplistic way is to successively add a small constant to a large integer, and generate the waveform from the most significant bits. A "cent," which is 1/100 of a semitone, is a factor of about 580 parts per million, so you can work out the precision needed for the constant. On a microcontroller, you can control the timing with a PWM, which runs independently of the processor and its timing foibles.

Proof is left as an exercise to the student. ;-)

> On a microcontroller, you can control the timing with a PWM, which runs independently of the processor and its timing foibles.

That is not really true. You usually have a couple of clock sources on a MCU, but the clock gets propagated down the clock tree and the source, and most of the times, the PWM has the same source clock as the CPU. Indeed, I think if you're before the PLL the clock is more accurate as in you get less jitter but the overall drift is the same. You might have distinct clock sources but you need a specific hw and a specific configuration.

Is it enough to have an audible effect? We’re not talking cesium clock levels of stability here. Now my curiosity is piqued, I have to figure out a way to measure this.

I've been doing audio software for 25-30 years. I have no idea what sort of synthesis you'd be doing where the processor clock played any roll at all. Waveform synthesis is normally done in buffers (8 to 8192 samples), and the "clocking" to convert the sample stream into an analog waveform is done by the audio interface/DAC, not the CPU. If you were basically implementing a DAC, then yes, the clock would matter a lot ... is/was that the issue?

You've not done it long enough to have worked with machine language programs that used instruction timing to click a speaker.

This worked well in 1980's microcomputers which used an accurate, crystal oscillator clock. IC's like the MOS6502 or Intel 8086 don't have built-in clocking. The boards were large and costly enough to afford a clock; and often it was dual purposed. E.g. in Apple II machines, the master oscillator clock from which the NTSC colorburst clock was derived also supplied the CPU clock.

These processors had no caches, so instructions executed with predictable timing. Every data access or instruction fetch was a real cycle on the bus, taking the same time every time.

Code that arranged not to be interrupted could generate precise signals.

Some microcomputers used software loops to drive serial lines, lacking a UART chip for that. You could do that well enough to communicate up to around 1200 baud.

As in the Manic Miner soundtrack on the ZX Spectrum: https://cirrusretro.com/listen/5333-manic-miner-zx-spectrum (warning: loud and annoying!)

> you built what was basically a raspberry pi with a microcontroller by hand, and you had to use the dumb speaker and controller to make your own music firmware to produce notes

This sounds like they were most likely bit banging square waves into a speaker directly via a GPIO on a microcontroller (or maybe using a PWM output if they were fancy about it). In that case, the audio frequency will be derived directly from the microcontroller's clock speed, and the tolerance of an internal oscillator on a microcontroller can be as bad as 10%.

yes it was this