Schmitt trigger... Possible?

I’m using Audacity 2.1.2 on OpenSuSe.
I want to know if there is a way to “emulate” a Schmitt trigger…
Someone can point me in the right direction?

Audacity does not do real-time processing.
If you’re not wanting this for real-time use, then please describe in detail what you are wanting to do.

I don’t want to do it in real time.
See the attachments…
I need to have bottom wave look like the top wave…
I thought to Schmitt trigger… but also other solutions are welcome.

I think a gate could act as a Schmitt trigger. I’m not sure all gates are a real ST, but at least, some are.

But I’m wondering too what would be the use, as you can’t get the result out of Audacity. And as Steve wrote, Audacity doesn’t do real-time triggering, so the use would be even more limited.

For those not intimate with a Schmitt trigger, it’s a level switch with hysteresis. And hysteresis means it’ll switch from off to on at level X, but won’t immediately switch off if the level dips below X again. Like most thermostats and most other automated switches operate in real life.

That looks more like a comparator than a Schmitt trigger (
I also notice that the upper waveform has a slower rise time than fall time. Is that important to the design?
It would help if you described in detail what you are wanting to do. What’s the job? What’s the context?

From your drawing, a limiter would be closer.

So you basically want to create a sine with flat tops?

Wouldn’t a programmable signal generator program be easier?

And it would even be easier in hardware. Like two diodes…

These signals come from “computer tapes”.
They are analog, but I have to convert them to digital.
Square waves with, just to say, +0,5/-0,5 peaks where “sin” waves have “peaks”.
More precisely, from +0.2 up i can set the “+0,5” peak, and from -0.2 down i can set the “-0,5” peak.
the “+/-0,2” value it’s absolutely arbitrary…
This should make “square” a “sinus” or whatever wave…

Out of interest I wrote a little demo. This also uses the Nyquist Prompt effect

Firstly a “comparator”.
For this we will first generate 1 second 20 Hz sine tone, amplitude 0.8:

(abs-env (mult 0.8 (hzosc 20)))

The next bit of code reads 44100 samples from the selected track (our sine tone) and compares each sample to a value of 0.0. If the sample value is greater than 0, the output is +0.8, otherwise it is -0.8.

(setf ar (snd-fetch-array *track* 44100 44100))

(dotimes (i 44100 (snd-from-array 0 44100 ar))
  (let ((input (aref ar i)))
    (if (> input 0)
        (setf (aref ar i) 0.8)
        (setf (aref ar i) -0.8))))

The outout:
But what if we have a noisy signal?

  (sum (mult (hzosc 20) 0.5)(mult (noise) 0.1)))

Our comparator “jitters” as the waveform crosses 0.0 multiple times due to the noise:
and a zoomed in view:
So here we need a Schmitt trigger. In this case the output goes high when the input exceeds +0.2, and stays high until the input drops below -0.2.

(setf ar (snd-fetch-array *track* 44100 44100))

(setf output 0)
(dotimes (i 44100 (snd-from-array 0 44100 ar))
  (let ((input (aref ar i)))
      ((> input 0.2) (setf output 0.8))
      ((< input -0.2) (setf output -0.8)))
    (setf (aref ar i) output)))

So now the output from our “dirty” sine wave looks like this:

If the input is not too “noisy”, then a simple and fairly fast way is:

(clip (mult *track* ny:all) 0.5)

This will work on reasonably long tracks (should be OK with an hour long track) and will work with mono or stereo.
If you need the hysteresis of a Schmitt trigger, then something like my previous code could work as a starting point, but that code in it’s current form is only suitable for fairly short mono tracks.

Ok, thanks a lot guys!
Nyquist code by Steve works as well…
Just one thing: it seems to produce a trail… that i don’t want…
Is my mistake?

Ensure that you select only the audio that you wish to process. If the selection extends into “white space” beyond the end of the audio, then Nyquist will attempt to process that selected white space as if it is audio.

Do you know what modulation scheme was used to encode the data on these tapes? It sound like you may be attempting to emulate the original decoding hardware, but with the power of a modern computer at your disposal there may be far better methods available.

Also if you find programming in Nyqiest to be painful (and I certainly do), there are pretty extensive python signal processing libraries available.

Modulation scheme may vary from tape to tape and, sometimes, from program to program.
My pourpose is to read signals from these tapes, rebuilding the “square wave data” and convert it to a “digital version” of the tape.
I’still having troubles with Steve’s cose, because seems like it modify the lenght of the waves i’m using…
But, since i’m totally new to Nyquist… i’m still trying to understand where are my mistakes…

Do you know what computer/software created the tapes?

For some encoding schemes, eg the Commodore 64, DIY hardware solutions exist. That would make the tape transfer much simpler and more reliable. And it’s all just 74XX logic, so it doesn’t cost an arm and a leg.

Tape stretches and together with noise, it might make the data unreadable.

I don’t have a link to the hardware immediately, but if you’re the DIY kind and can handle a soldering iron, I could see if I can find it again, if it is still present on the web. IIRC it was a German site, but I seem to remember some sources in the UK too.

Thanks a lot Cyrano, i know there are hw dedicated solutions to dump tapes.
But i have some signals recorded via not dedicated HW that i want to preserve.

By now i understood that:

(setf ar (snd-fetch-array *track* 882000 44100))

(setf output 0)
(dotimes (i 882000 (snd-from-array 0 44100 ar))
  (let ((input (aref ar i)))
      ((> input 0.2) (setf output 0.8))
      ((< input -0.2) (setf output -0.8)))
    (setf (aref ar i) output)))

works 20 seconds of audio (at 44100 freq).
How can i elaborate full track/selection and not a fixed amount of samples?

If you could post a short sample of the type of audio that you want to convert, then that will give me a better idea for an appropriate solution.
Please post 5 or 6 seconds in WAV format. (see here for how to post an audio sample:

Here it is…

Ok, so that bit is pretty clearly FSK. Bits are either ~1800 Hz or ~3600 Hz.

You might want to apply a bit of equalization before attempting to decode them, the 3600 Hz part is about 10 dB down from the 1800Hz bit. Aside from that the signal looks pretty clean to me, a simple threshold should suffice to digitize it, and decoding into a bit stream shouldn’t be too hard either (but I would probably not try to do that programming bit in Nyquist.

As flynwill wrote, that appears to be FSK ( so turning those waveforms into square waves is the wrong approach. The two digital (binary) states (on/off or 1/0) are not represented by amplitude but by frequency. To “convert to digital” you need to detect the frequencies, then select one binary state (1 or zero) when one frequency is present and the other binary state for the other frequency.

As the signal is always either the higher frequency or the lower frequency, we only need to detect the higher (or lower) frequency, as the other binary state is “everything else”.

This code seems to work pretty well on the sample that you posted:

(setf threshold 0.08)  ;tweak this value as necessary

(let* ((sig (lowpass2 (snd-abs (highpass8 s 3000)) 3000))
       (sig (s-max (diff sig threshold) 0)))
  (clip (mult sig ny:all) 0.8))

Here’s a close-up of part of the waveform.
The first track shows the input (the file that you posted).
In the second track, the filtering in the code causes a delay, so the processed output is all a little to the right relative to the original.
The third track is a duplicate of the second track, but I’ve shifted it a little to the left (using the Time Shift tool) so that you can see how the “digital” output relates to the FSK input.