Tuesday, June 25, 2019

More complications, leading to a potential solution

This evening it occurred to me that varying the pitch of a note, while generating its phase from a multiple of the phase of a base tone, might result in artifacts. I'm not certain of this, and cannot yet articulate why I think it could happen, but it seems at least plausible.

A solution also occurred to me, which is to only use the base tone to generate the initial phase of the note, and from that point on track its phase independently. That thought lead to another complication; when you want the varying pitch to come to rest on a specific tone, the phase of the note may not align with a newly generated note of the same frequency.

I first thought about pacing the change in pitch so it would end up phase-aligned on the target frequency. This would work for scripted compositions, but in live performance it isn't possible to know what the target frequency will be until it happens.

So it seems as though a better solution would be to cross-fade from the sliding note to a newly generated note which is stable on the target frequency.

But, if this mechanism (independently tracking the phase of each note, after initiating it using the phase of the base frequency) is in place for notes with varying pitch, why not just use it for all notes, and not have to worry about whether they will remain at a constant pitch?

Applying this technique to all notes would mean that the base tone is only used to initiate new notes, which would mean precision is no longer an issue, so we can dispense with 80-bit floats!

[7/5/19: The thought that set this all in motion, that varying the pitch of a note while generating its phase from a multiple of the phase of a base tone might result in artifacts (noise), remains a matter of conjecture. I haven't yet hit upon a way of determining whether this is an actual concern. However, eliminating the need for 80-bit floats is sufficient motivation to proceed as though it were established fact.]

Wednesday, June 19, 2019

Ground-shifting changes

We've all had a couple weeks to assimilate all that was announced at WWDC, and those who surf the bleeding edge have been very busy getting up to speed and producing blog posts, newsletters, podcasts, and videos paving the way for the rest of us.

Just listing all of the resources already available would be a formidable task, so instead I'll just mention a couple of good starting points.

For anything related to the Swift programming language, the Swift.org website is the center of the universe. What you won't find there is much in the way of links to blogs, newsletters, podcasts, or YouTube channels relating even to Swift development.

That gaps is nicely filled by Dave Verwer's iOS Dev Directory, which does not include a link to this blog, nor should it!

I don't expect to have much to say here for a few months. In the meantime, you can catch me on Twitter at https://twitter.com/harmonicLattice.

Sunday, June 16, 2019

Navigating a larger problem space

On the same day as my most recent post here, I also began a thread on Twitter, in which I laid out the opportunities and constraints presented by various approaches to generating tones by multiplying the phase of a base tone by frequency ratios.

This took several hours, and I had to finish it the next morning, nevertheless, except for a minor glitch or two, I think I managed to get it straight, possibly for the first time.

Only generating tones that are all integer multiples of the base tone is significantly simpler, but taking that simple approach precludes the use of any musical practice involving pitch variation — bending, sliding, or vibrato.

For the purpose of producing a fuller sound, more like a physical instrument, the set of pure tones that are all integer multiples of the base tone is just too confining. Unfortunately, the alternative seems to be to use phases that continue to increase indefinitely, tracking them using high precision floating-point numbers to keep it working long enough to be usable. I keep thinking there must be a clever hack that would make this all unnecessary, but so far this has just lead me down rabbit holes.

The rabbit holes have become a problem because I cannot hold everything in that Twitter thread in my mind at once; I have to deal with it as I posted it there, in Tweet-sized bites, and have more than once lost track of one detail or another.

If you think of a cycle as being a circle, and phase as being an angle superimposed on that circle, or a position on its circumference, continuously increasing phases can be thought of as wrapping, winding, or coiling around that circle.

The need for high precision comes in because this approach involves multiplying the phase of the base tone by a frequency ratio that might have a value as high as 20,000, then discarding everything to the left of the decimal point, leaving only whatever significant figures were to the right of the decimal point. As that base tone phase increases, so too does the result of multiplying it by the frequency ratio, meaning there are fewer and fewer significant figures remaining on the right, and sooner or later insufficient precision to properly use it for the next step, conversion either into an index for a lookup table or directly into the magnitude of a sound wave for a particular sample, by means of an algorithm. Using higher-precision (80-bit) floating-point numbers buys time.

This inelegant approach grates on my sensibilities as a programmer, but, short of returning to only trying to produce tones that are integer multiples of the base tone, I haven't yet found any way around it.

Thursday, June 06, 2019

Cognitive paralysis: hopefully temporary

I'm presently doing a pretty good emulation of a robot that's got itself 'trapped' in a corner its programming is inadequate to escape. With any luck, this will pass, but I consider myself fortunate to have recognized the symptoms and desisted from digging myself even deeper into confusion.