Chuck and the Time Code
Reading the Signal
First you need an ADC Unit Generator declared in Chuck to pull the values. Chuck is a work in progress, and as of this writing (200712) not all aspects of the ADC are implemented yet, including reading the last sample. To get around this, you can simply hook up a Gain and pull the last sample (gain.last) from this. Chuck (=>) the whole thing to a Blackhole so that the samples are pulled, but ultimately, end up nowhere, lost in oblivion, for all eternity.
Decoding the Signal for Speed
Here's where it starts to get messy. With a few functions, sporks, and shreds, we basically wait for a zero crossing, start a timer, and count the samples until the next zero crossing. This gives half the period of the sinusoid. If you are just trying to pull speed information, you can do this on one channel. The actual 'ZeroDistance' (distance between to Zero Crossings) is then used to divide the stable ZeroDistance value.
The stable value can be found by playing the record at normal speed, and getting the ZeroDistance. When this 'ideal' value is then divided by the actual ZeroDistance, the result is something that fluctuates around 1; 1 meaning the actual ZeroDistance is the same as the ideal/stable value, less than 1 meaning the actual value is MORE than the stable value (record is moving SLOWER), and more than 1 meaning the actual value is LESS than the stable value (record is moving FASTER).
Decoding the Signal for Direction
Here's where it starts to get VERY messy. During the first iteration of Chuck sporks and funcitons, I crashed miniAudicle more often than I made any real progress. A quick chat with my DSP teacher though (thanks Dave!) and I've got the formula to compare the left and right channels. For every sample (or you can do less, I'm just going for as much computation as possible), you take the Arctangent of the values on the left and right channel. This gives you a slope (moving up or down). By comparing the last two samples result of this, you will get a positive number or a negative number...one for moving forward and one for moving backward. At this point, convert that to a 1 or -1 and chuck that to your rate coefficient. Voila, very fast updating direction information.
Decoding the Signal for Absolute Position
Here's where I give up (for now). I'm not too sure on this, but I think the trick is to wait for the starting signal, read the 'bits' (conveyed via sine wave peak amplitude), and lookup which position this relates to. I don't know a good way to do this mathematically, and so far the only suggestions I've had are to make a table and just do it by hand; track out the signal. Not happening in the next 9 hours.
Filtering the Signal
I was having a lot of problems with the signal as the motor stopped and died out. The signal became very weak, and since I am looking for the zero crossings, I ended up getting A LOT of them and so the program would try to keep the rate to match up with the high number of Zero crossings. To fix this, I filtered the signal into a basic envelope (using a one pole filter called a 'leakey integrator'), and then checked if the envelope passed a certain threshold. If the envelope was below this threshold (mostly low signal), we just put a 0 to multiply our rate coefficient (remember for direction it was a 1 or -1). The parameters to adjust here are the threshold the envelope must cross, and the pole of the one pole filter (it will be very close to 1, like 0.999909 in my case.