## Nyquist frequency divider feedback not working

Using Nyquist scripts in Audacity.
Forum rules
If you require help using Audacity, please post on the forum board relevant to your operating system:
Windows
Mac OS X
GNU/Linux and Unix-like
steve
Posts: 49033
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

### Re: Nyquist frequency divider feedback not working

OK, I see what you are wanting to do, and it's quite tricky in Nyquist. See this section of the Nyquist manual: http://www.cs.cmu.edu/~rbd/doc/nyquist/part6.html#49
Of course, if all you wanted was the 8kHz sine wave, then in practical code you would just write hzosc(8000) [ or in LISP syntax, (hzosc 8000) ]

zeropoint
Posts: 7
Joined: Sat May 19, 2018 4:12 am
Operating System: Windows 7

### Re: Nyquist frequency divider feedback not working

Here's a block diagram of the Faust code in my previous post:

In the application this code is used in, a Hilbert clipper is normally used to hard limit the signal without causing harmonic distortion or aliasing. That wasn't done here because it would complicate the code.

In this basic example, taking the output from the filter directly works better, as it reduces aliasing on the output caused by the harmonic distortion of the simplified limiter (a peak clipper) that has been used.

Code: Select all

import("stdfaust.lib");
process = d;

dither = no.noise * ba.db2linear(-300); //dither at -300dB is adequate for 64 bit systems
a = os.oscp(16000,0); //16kHz sinewave input test signal
d = (a * (_ + dither):fi.bandpass(2,7950,8050)) ~ limit:_; //frequency divider by mixing
limit(x) = x*(0.5/max(abs(x),0.1)); //simple limiter to avoid massive filter overload
Here's the block diagram of this code:

Can Nyquist do this? What function would allow this type of recursion?

zeropoint
Posts: 7
Joined: Sat May 19, 2018 4:12 am
Operating System: Windows 7

### Re: Nyquist frequency divider feedback not working

Thanks for the link Steve. I have read those pages before, but I will study them more closely.

I am amazed how difficult it is in Nyquist to get one previous output sample to feed back into a function input! Maybe this needs to be addressed in a future release?

This code is to be part of a high performance AM synchronous demodulator. It uses a squaring loop to allow carrier recovery from the modulation sidebands even during carrier fades. But a squaring loop doubles the carrier frequency, so a divide by two is needed. This routine seems to be the simplest and cleanest way to precisely divide a frequency by two in DSP.

Faust code for all this is working quite well, but it would be useful to be able to process recorded IQ files from SDR receivers faster than real-time. Faust code can be compiled into VST plugins, but there seems to be a problem getting them to run in Audacity under Windows. Hence my interest in Nyquist...

steve
Posts: 49033
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

### Re: Nyquist frequency divider feedback not working

zeropoint wrote: I am amazed how difficult it is in Nyquist to get one previous output sample to feed back into a function input! Maybe this needs to be addressed in a future release?
The issue is that you are needing to create a new DSP block that incorporates a mixer and limiter into the inner loop of a a bandpass filter. Because Nyquist in an interpreted language, looping through samples is expensive, which is why Nyquist's DSP blocks are written in C.

In Faust, DSP blocks are created by defining the algorithm in an algorithmic language, and then compiling that algorithm into low level code (such as C or C++). This is the main purpose of Faust.

In Nyquist you can do the same. The algorithm can be defined as an ALG definition, then compiled into C code https://www.cs.cmu.edu/~rbd/doc/nyquist/part17.html#210
This is not the main purpose of Nyquist, and is much less convenient to do than in Faust, but it can be done.

It is perfectly possible to create low distortion hard limiting, using Nyquist's built-in DSP (no need to create new DSP blocks). https://github.com/audacity/audacity/bl ... limiter.ny
However, you don't want to do that. You specifically want to create a DSP in the way that you do in Faust, which while possible, is not easy in Nyquist.
Why do you want to use Nyquist for this, when it is so much easier in Faust?

In Nyquist, the easiest way to create new DSP blocks is as Lisp objects. See DSP in Lisp. This is considered to be an "advanced topic" for Nyquist programming.

zeropoint
Posts: 7
Joined: Sat May 19, 2018 4:12 am
Operating System: Windows 7

### Re: Nyquist frequency divider feedback not working

steve wrote:Why do you want to use Nyquist for this, when it is so much easier in Faust?
My previous post answers that question:
zeropoint wrote:Faust code for all this is working quite well, but it would be useful to be able to process recorded IQ files from SDR receivers faster than real-time. Faust code can be compiled into VST plugins, but there seems to be a problem getting them to run in Audacity under Windows. Hence my interest in Nyquist...
It seems the way Nyquist processes audio isn't compatible with writing routines that require a feedback path, unless you can compile your own routines as extensions.

If only Audacity offered Faust support! That would enable very powerful processing routines to be easily written.

Perhaps I should abandon Nyquist and focus on getting Faust VSTs to work in Audacity...

Faust is very good, but it's execution options are a bit limited. In Windows the Faust VSTs compiled using the online tools won't load in Audacity, so the Faust code can only be executed in real time - using the online Faust tools, in FaustLive, or compiled into Webassembly and running in a browser. These methods can't operate directly on files, which means additional software might be needed for routing audio to and from the applications, and there can be audio dropouts due to other resource demands on the PC. It also means the code always runs in real-time, so a 1 hour file takes 1 hour to process.

steve