Hi Peter: I guess you fill up the wavetable so quickly that the glitch is small enough to be filtered out. I certainly agree 100% with the larger 768 wavetable. What I was wondering was if it would be even better if it was filled using lookups from a sine table that was itself 768 samples, and not the default audio library one of 256.
I worked with AVR MCUs for about 15 years, and knew them "down to the metal". But, even being able to do assembly language coding, I knew they weren't fast enough to do what these teensys do.
I agree with you on the fixed phase relationship of Hammond- I guess you could never achieve that in software. Each of the 3 layshafts running the tonewheels had a spring clutch though, and there is a bit of randomness associated with slippage from this. Also, there was a bit of signal leakage between adjacent tonewheels (like in a piano) that gave a variation in the sound.
Yes- the library "chorus" block is described as a multi-voice unison. Actually though, the library code implements "n" taps on a delay line, but there is no modulation of those taps. There needs to be some modulation for it to work- ideally a random modulation, but a sine/triangle will work. When you listen to the lib. chorus, you can hear the sound is a bit different, but not chorus. And, if I recall correctly, I couldn't see anything happening on my 'scope, apart from a difference in the shape of the sine wave.
Re the offset. I still have a problem understanding this. Upon entry to the routine, you are filling a small part the delay line with 128 new samples. The whole delay line- as a circular buffer, will have a continuous representation of the input waveform, EXCEPT at the "write incoming sample to delay line" pointer location, where a discontinuity will exist. In my routine (which was "lifted" from the flanger routine) , the sine(or triangle) modulated pointer has a fixed offset from the latter pointer, added to it. So, whether you are adding or subtracting (using the triangle), you still are offsetting this pointer away from the "write incoming sample to delay line pointer" by a fixed amount (I use 1/8 of the delay line length). If not, you are reading in samples (for processing in the rest of the routine), from an area in which this discontinuity lies. This shows up as a faint click at the vibrato rate in my routine if I do not incorporate this offset. I must say I haven't studied your code carefully enough to see how your code gets around this issue.
I just did an analysis of the waveforms generated by the Native Instruments B4 VST plug-in. My Moto multichannel digital mixer has built in 'scope and FFT routines, which I must admit I never needed or used much til now.
It turns out that the B4 waveforms are NOT pure sinewaves anywhere across the keyboard! I used the 16' stop only, and looked at each note. Here are a few examples: (I only put in the dB labels for the 1st line)
Lowest C (folded over from C1) Fund +3dB 2H -12dB 3H -30 dB
D (" ) Fund +2 1.5H -36 2H -12 3H -36
E Fund +2 1 1/3H -36 1 2/3H -36 2H -12
F# 2/3H -36 Fund +1 1 1/3H -36 2H -16
C1 Fund +8 1 1/2H -33 2H -5 3H -24
D#1 2/3H -36 Fund +8 1 1/3H -30 1 2/3 -32 2H -6 3H -38
G#1 2/3H -36 F +12 1 1/3H -33 1 2/3H -36 2H -8 4H -36 16H -36
This is just a small sample, but the waveform harmonics vary all the way up the keyboard. and nowhere, among the 16' notes, are they even close to a pure sine wave. Some of the notes I measured have 5 or more subharmonic "spurs". This explains why the B4 sounds a lot richer than my simulation program! Native Instruments is a big, professional German company and I am assuming that their engineering/programming team must have sampled each tone wheel, and the VST must be mixing the individual tonewheel waveforms for each stop on any given note.
So, it seems that to do this "right", one would need to pre-generate 91 "accurate" wave tables, pick the proper one(s) for a given note, and mix them together at ratios dictated by the settings of the drawbars. Even with your longer 768 16-bit tables, there would be enough SRAM in the new Teensy 3.6 to hold them all. And its MCU, overclocked at 240 MHz, could handle the processing easily, I expect. But, it would be a big programming job.
The foldback issue was easy to handle the way I do things, but would be harder to do in your method.
Thanks for the link- lots of good info there. I thought that the 9 drawbar busses terminated in a low value resistor chain, acting like a rough potentiometer But, I see it is a multi-tap transformer instead. So, my advice to Sweetbb is a bit off, but the methods I proposed are still correct, assuming the transformer is stripped off.
Re: Leslie- That is the holy grail of organ effects
. I have thought a LOT about this myself. Basically, I figured that you would need 1 teensy for the hammond organ sound generation itself. That output, as an I2S signal, could go into the I2S port of a second teensy, for the Leslie effect. For the Leslie, you need at least vibrato for the horn Doppler shift, a variable bandpass filter to simulate the accentuation of the high frequencies as the horn faces you. For the drum, I think that you only need vibrato, and maybe some amplitude modulation (tremolo).Plus, you need to have a filter to implement the cross-over network ahead of the speakers.
For a digital guitar amp/effects box project I built, I've done all of these things to implement various effects, directly from the audio library (except for vibrato for which we both have our own routines). But, for a Leslie they must all be synched, and I haven't had to do that yet. That is where your enhanced programming skills re the audio library, would come in handy.
You mentioned "grit", from using the drive control on the Hammond to overdrive the Leslie preamp. Overdrive is an effect that would have been nice on my digital guitar amp project, but I hadn't made the effort to come up with an algorithm that could do it nicely. But, I did use the auto gain control function in the SGTL5000 codec's DAP, on the Audio adapter, to get soft compression, but its not quite the same.
I chose to get two Teensy3.5s from Paul's Kickstarter campaign, because of the 5V tolerance of the 3.5s. But now I wish I had picked the 2X faster T3.6s !
It is really great to discuss this topic with you- I admire your C programming skills ( and Paul is a real pro!). My career was as a hardware guy with some MCU programming. I used Visual Basic on PC and Bascom/AVR Basic for all of my AVR MCU projects til a year ago. Then, I switched to Arduino, to take advantage of its huge user base/driver libraries. So, I've switched to "C", but not as skilled as you on it yet! Plus, the ARM chips are really complicated. I like reading datasheets, but 2000+ pages is a lot!
Best regards.