I ran across a 2006 article by Chip Gracey called “Synthesizing Speech with the Propeller”, which describes how to perform speech synthesis on the Propeller chip.
Something that caught my attention was the resonator algorithm – it was based on a method I hadn’t run across before. Each resonator holds its state as a two-dimensional point (x, y). The resonators are placed in a cascade, and resonator n adds the point from resonator n-1 to its own point, and rotates the new point around the origin (0,0). The final output is the y value of the last resonator. Here’s what my version of the code looks like:
-- run through resonators
f1x, f1y = rotateAroundOrigin( f1Angle, pulse+f1x, f1y )
f2x, f2y = rotateAroundOrigin( f2Angle, f1x+f2x, f1y+f2y )
f3x, f3y = rotateAroundOrigin( f3Angle, f2x+f3x, f2y+f3y )
f4x, f4y = rotateAroundOrigin( f4Angle, f3x+f4x, f3y+f4y )
out = f4y
The angle is calculated as proportional to the frequency:
-- calculate angle steps for resonators
local f1Angle = f1 * 2 * math.pi / SAMPLE_RATE
local f2Angle = f2 * 2 * math.pi / SAMPLE_RATE
local f3Angle = f3 * 2 * math.pi / SAMPLE_RATE
local f4Angle = f4 * 2 * math.pi / SAMPLE_RATE
Each point is also scaled by a small decay.
I was able to get these resonators running in synSinger, but because there’s no control of the bandwidths, the output sounds tinny. So there doesn’t seem to be much value in exploring this option, unless someone can point out a flaw in my code.
In his article, Chip mentions that one alternative he considered was running an oscillator at each resonant frequency, and resetting the resonators at the start of the glottal pulse – exactly the same algorithm that Software Automatic Mouth initially used. (It’s better known as VOSIM). Chip ended not up using it because it had discontinuities and was low quality.
Here’s an example of Chip’s code singing: Singing Voice