Before, the synth was hardwired with a band-limited saw wave. I’ve removed this restriction by allowing users to pass a table filled with information about the harmonic spectra. For each overtone, the table stores three bits of information, in this order: frequency ratio, amplitude and phase. For example, the following two lists represent the data for a 3 tone band-limited saw wave and square wave:
1, 1, 0, 2, 0.5, 0, 3, 0.333, 0 ; saw
1, 1, 0, 3, 0.333, 0, 5, 0.2, 0 ; square
Typing all of this is tedious, so I went ahead and created a handful of GEN Instruments to create and fill tables automatically for the saw, square and triangle. I’ll do one for the buzz wave and one that mimics GEN10 down the road. Though my examples are harmonic in nature, the design also allows for inharmonic overtones.
I made one other upgrade, which technically isn’t an upgrade to the synth, and is probably more of a proof-in-concept. In the previous example, I use a table filled with noise for the EQ of the acoustic body. This works really well, though it lacks the resonant peaks and dips one would expect from a real instrument. I created a GEN Instrument, GEN_Multiply, that takes two tables, multiplies their content (with interpolation if necessary), and produces a new table. So now I can create a table with envelope-like shapes to simulate peaks and dips, and multiple that with a noise table, producing a resonant noise table.
Download: add_synth_upgrade.csd
u-p-g-r-a-y-e-d-d
One aspect of this design that I’m wondering about is the idea the body filter. In general for the body of an instrument it has fixed filtering properties so that if lower notes may have more harmonics present and higher notes have less harmonics present. I usually do this kind of thing in an always-on instrument with a filter as the it’s like having a resonant body which is always-on.
The body filter/transfer function is currently fixed. The bowed string-like sound is more or less created by 2048 points of micro peaks and dips. I’m still experimenting with the curve of the body transfer function, but let’s keep it simple and pretend it’s linear. Any oscillator with a frequency of 11025, will access the middle value of the body transfer function. It would not matter if that particular tone is the fundamental, or the 112th harmonic, it will still be multiplied by that middle value. The end result is very much like running audio through a subtractive fixed filter bank.
The saw sound source in today’s csd only uses 32 bands, so that I may render in real-time. A small tweak the the line “i $GEN_Saw 0 1 500 32″ could turn that 32 into 320. At which point, the lower notes will have more harmonics than the high ones. There is currently an arbitrary cutoff so that if the frequency of the current tone is greater than 16000, the next would-be recursed tone is not spawned.
Does this address you curiosity? Am I making sense? This is the first time I’m explaining it, so my answer may not yet be fit for human consumption. :) If not, let me know and I’ll refine my answer.
That makes sense and I mentioned it as I didn’t quite see this happening in the CSD when I first took a quick look and didn’t quite hear it in the CSD when rendering. Sounds like I just missed it when I read the code the first time. Thanks!
No problem. My example could have been much more audibly clear. I just uploaded a new example that will hopefully clarify things, even if the curve of the body transfer function is way off.
http://www.thumbuki.com/TheCsoundBlog/add_synth_upgrade_comment.csd
It plays through once without additional body shaping, and then again once with table 302. The single 1 represents the only peak. I’ve also bumped up the number of bands in the saw to 100.