First post so forgive me if I’m asking in the wrong place/way.
Background: I’m trying to use an Arduino to monitor a low frequency tach signal, and have made good progress, but I’d like to have a way of comparing the data it is returning with the actual input signal. It struck me that a Nyquist plugin should be able to do this, but i’m just starting to make sense of the language and would be grateful for any pointers you can give.
specifics: i have recorded several short mono tach signals. the signal is basically a sawtooth pulse followed by a short silence, with variable amplitude and frequency depending on the speed of the rotation. the stats i would like to obtain are:
the maximum frequency (shortest number of samples between zero crossings?),
the sample number (time) of this point,
the minimum frequency and
time of this point.
Frequencies range from approx 10Hz to 100Hz and the recordings are relatively short: between 1 and 3 seconds.
Ideally i would like to apply the analysis across the whole recording but i can narrow the selection to sections if necessary.
thanks for any suggestions or pointers to other posts
but probably a better way to “filter” the signal is to resample it to a low frequency by taking the average amplitude of every, say 20, samples. This will effectively be a 1100Hz low-pass filter (the bandwidth at 44100 H is 22050 Hz, so at 1/20th of the sample rate the bandwidth will be 1102.5 Hz). It also reduces the amount of data to be processed to 1/20th of the original, so should be quicker and more efficient.
Note that the size of the “STEP” determines the precision. Smaller values will give higher precision, but you may get some false hits due to noise, and the amount of data (hence the size of the data array) will increase). I don’t recall what the max size is for SND-FETCH-ARRAY, but it is at least 1 million.
From a quick test, the limit appears to be a little over 1 million samples. Much more than that and Nyquist will crash, which will probably take Audacity down with it.
“Conditioning” the signal allows us to deal with jitter around zero between the pulses. Alternatively you could handle the jitter when you process the data array.
How are you getting on with this?
I had a play while my computer was busy doing another task, and wrote a bit more code that may have some useful features for you:
The code:
;; Looks for the signal crossing this amplitude value.
;; Increase if necessary to avoid false triggers
(setf v-offset 0.05)
;; Conditioning Filter frequency.
;; Reduce this if necessary to avoid false triggers.
;; Set to 0 to turn this off.
(setf filt 8000)
;; Time offset to calibrate detected zero crossing
;; points with waveform. Negative values move the
;; detected times (labels) to the left.
(setf t-offset -0.00001)
(let* ((sig (if (> filt 0)
(lowpass2 *track* filt)
*track*))
(ln (truncate len))
(data (snd-fetch-array sig ln ln))
(labels ())
(oldval -1)
(prev -1)
(maxhz -1)
(minhz 99999999)
(debug-text ""))
(do* ((val (aref data 0)(aref data count))
(count 0 (1+ count)))
((= count ln))
(when (and (> oldval v-offset)(<= val v-offset))
(let* ((time (+ (/ (- count 1) *sound-srate*))
t-offset)
(cps (/ (- time prev)))
(rpm (* cps 60))
(text (format nil "~a Hz" cps)))
(cond
((< prev 0)
(setf debug-text
(format nil "First impulse at ~a s." time))
(push (list time debug-text) labels)
(setf debug-text (strcat debug-text "\n\n")))
(t
(push (list time text) labels)
(setf maxhz (max maxhz cps))
(setf minhz (min minhz cps))
(setf debug-text
(format nil "~aTime: ~a s. \tSpeed: ~a rpm \t~a Hz~%"
debug-text time rpm cps))))
(setf prev time)))
(setf oldval val))
(format t "Maximum speed is ~a Hz.~%Minimum speed = ~a Hz.~%~%~a"
maxhz minhz debug-text)
labels)
Apply in the Nyquist Prompt effect using the “Debug” button:
The output from the Debug window:
Maximum speed is 42.8988 Hz.
Minimum speed = 41.8009 Hz.
First impulse at 0.0113152 s.
Time: 0.0346259 s. Speed: 2573.93 rpm 42.8988 Hz
Time: 0.0579365 s. Speed: 2573.93 rpm 42.8988 Hz
Time: 0.0812472 s. Speed: 2573.93 rpm 42.8988 Hz
Time: 0.104671 s. Speed: 2561.47 rpm 42.6912 Hz
Time: 0.128186 s. Speed: 2551.59 rpm 42.5265 Hz
Time: 0.151723 s. Speed: 2549.13 rpm 42.4855 Hz
Time: 0.175351 s. Speed: 2539.35 rpm 42.3225 Hz
Time: 0.19907 s. Speed: 2529.64 rpm 42.1606 Hz
Time: 0.222789 s. Speed: 2529.64 rpm 42.1606 Hz
Time: 0.246621 s. Speed: 2517.6 rpm 41.96 Hz
Time: 0.270544 s. Speed: 2508.06 rpm 41.8009 Hz
Time: 0.294467 s. Speed: 2508.06 rpm 41.8009 Hz
The main output is tab delimited, so it should be quite easy to import the data into a spreadsheet if you want.