Hi Dan,
I don’t know the process behaviour, but here I attached the upgrade to the 
STDFAUST functions.

best,
giuseppe

/* The Kansas City Standard (KCS) uses frequency shift keying to encode binary
   digits at 300 bps as an audio signal. This Faust module provides a KCS
   signal analyzer for the Casio FA-3 tape interface used with the early Casio
   Basic pocket computers from the 1980s, such as the Casio PB-100 and the
   FX-730P. You can find more info about the hardware of these PDA precursors
   at http://www.pisi.com.pl/piotr433. */

/* This got quite a bit more involved than I first made it out to be. Maybe
   that's also the reason why I couldn't find any ready-made solution on the
   net that would work with the noisy output signal produced by my Casio
   PB-100 calculator. Thanks are due to Jos Horsmeier for pointing out that
   autocorrelation might do the trick, which it actually did. :) */

// MODIFIED BY DAN NIGRIN December 2007
import("stdfaust.lib"); 
//import("math.lib");
//import("music.lib");

/* Here are a few threshold constants you might have to tinker with. The
   default values seem to work ok with the FA-3 interface, but YMMV. */

K0 = 0.1; // absolute threshold of noise gate
K1 = 0.3; // rectifier threshold (relative to max amplitude)

// DAN NIGRIN CHANGE
// K2       = 0.8; // rising edges of autocorrelation signal
// take out the constant, and make a variable
K2 = hslider("K2", 0.8, 0.5, 1.0, 0.01);

// DAN NIGRIN CHANGE
// K3       = 0.3; // falling edges of autocorrelation signal
// take out the constant, and make a variable
K3 = hslider("K3", 0.3, 0.1, 0.6, 0.01);

/* Maximum size of various delay lines; this must always be a power of 2 and
   larger than the window size n (see below). */

N = 1024;

/* Frequency of the 1-bit base tone (which is also the frequency of the
   lead-in tone). For standard KCS this is 2400 Hz, but the frequencies of the
   Casio FA-3 tape interface are slightly shifted because it uses a 32768Hz
   xtal as a reference, resulting in 32768Hz/14=2340Hz as logic 1. In any
   case, 8 cycles of this wave represent a 1 bit, while a 0 bit consists of 4
   cycles of half the frequency. The length of one symbol thus corresponds to
   SR*8/freq samples which is also used as the window size for the
   autocorrelation analysis. */

freq = hslider("freq", 2340, 1000, 5000, 1);
k = ma.SR/freq : ceil : int;    // period length (samples)
n = ma.SR*4/freq : ceil : int;  // symbol length (samples) - MODIFIED BY DAN 
NIGRIN FROM SR*8

/* Input gain in dB. Use this to make up for a weak input signal. Changes to
   this value will also trigger a recalibration of the signal envelop (see
   below). */

gain = ba.db2linear(hslider("gain", 0, -96, 96, 0.1));

/* 1 pole LP used to estimate the current signal strength. This unit is used
   to trigger processing as soon as the signal rises above a certain absolute
   threshold. */

env = abs : *(1-g) : + ~ *(g)
with {
    t = 0.1;            // attack/release time in seconds
    g = exp(-1/(ma.SR*t));  // corresponding gain factor
};

/* Determine the maximum amplitude used to compute the threshold for
   rectifying the signal. This gets recalibrated automagically when t=1 (which
   happens in the main program as soon as the signal rises above a certain
   threshold or the input gain is modified). */

maxenv(t) = *(1-t) : max ~ *(1-t);

/* Rectify a signal using a given threshold, and turn the rectified signal
   into a train of "trigger" pulses. */

rect(m,x) = x>=m;
trigger(x) = x>x';

/* Integrate a signal over a window with given length d. */

integrate(d,x) = x-de.delay(N,d,x) : + ~ _;

/* Sample-and-hold. Repeats last nonzero value of the input signal. */

samplehold(x) = rwtable(2, 0, x==0, x, 0);

/* Clock signal. Repeats last nonzero value of the input signal every d
   samples. */

clock(d,x) = rwtable(N, 0, x==0, x, (int : %(int(d)) : *(x==0)) ~ +(1));

/* Signal cleanup. This removes "nearby" double pulses (less than d samples
   away from each other) in the output signal. Only the second pulse of each
   such pair is kept. NOTE: Since a Faust program processes signals "on-line",
   i.e., it cannot look into the future, this unit delays the input signal by
   d samples. */

cleanup(d,x) = (1-v)*de.delay(N, d, x)
with {
    u = integrate(d, abs(x))>1;
    v = trigger(1-u);
};

/* The main program. The input is the mono signal x0 to be analyzed. The main
   output is the y1 signal. A single-sample +1 pulse means a binary 1, a -1
   pulse a binary 0. In between the symbol pulses the y1 signal is 0. */

/* For illustrative and debugging purposes we also output the preamplified
   input signal, the gate signal (useful to sense when a transmission starts
   and stops), the rectified input signal and the rectified autocorrelation
   signal. Essentially, the latter is the rectified autocorrelation of the
   rectified input signal which is then sampled at the symbol rate to
   construct the output signal. Some complications arise, though, because the
   detected 0 and 1 bit pulses are not fully in sync and the symbol length
   rounded to samples is not fully accurate either. This is taken care of by a
   final "cleanup" phase in which any resulting spurious double pulses are
   removed from the output signal. */

process(x0) = attach(x1, e : hbargraph("maximum", 0, 1)), g1, r1, s1, y1
with {
    /* Apply input gain. */

    x = x0*gain;

    /* Noise gate. */

    g = env(x)>K0;

    /* Rectified input signal, with pulses of length k for each period of
       the input signal. This is done by detecting the rising edges during
       the first half of the signal period. */

    e = maxenv((g>g')|(gain!=gain'), x);
    r = integrate(k, trigger(rect(K1*e,x)*g)) : min(1);

    /* Autocorrelation of the rectified input signal. Note that the
       rectified signal looks more like 1-1-1-1-... for 1-bits, whereas
       0-bits look more like 1-0-1-0-..., where each 0 or 1 represents one
       base frequency period of k samples here. Hence the 1-bit signal's
       autocorrelation for a delta of k samples will be close to 1,
       whereas the 0-bit signal produces an autocorrelation close to 0. */

    a = integrate(n, r*de.delay(N, k, r))/n;

    /* Lead bits corresponding to rising and falling edges of the
       autocorrelation signal (1 = 1 bit, -1 = 0 bit). */

    b = g*(trigger(a>=K2)-trigger(a<=K3));

    /* Clock signal (pulses at symbol rate, triggered by lead bits). */

    c = g*(clock(n, b>0)-clock(n, b<0));

    /* Sample-and-hold of the lead bits, yielding the rectified
       autocorrelation signal. */

    s = g*samplehold(b);

    /* The preliminary output signal, which is obtained from the rectified
       autocorrelation signal by sampling at the pulses given by the clock
       signal. In effect, this repeats the lead bits at the symbol rate. */

    y = (c>0)*(s>0)-(c<0)*(s<0);

    /* Finally clean up the output signal to remove any spurious double
       pulses which are less than n2 = half the period away from each
       other. Note that this delays the signal by n2 samples, so we apply
       a corresponding delay to the other output signals as well. */

    n2 = int(n/2);
    y1 = cleanup(n2, y);
    x1 = de.delay(N, n2, x);
    g1 = de.delay(N, n2, g);
    r1 = de.delay(N, n2, r);
    s1 = de.delay(N, n2, s);
};

 

> On 16 May 2021, at 04:21, Dan Nigrin <d...@defectiverecords.com> wrote:
> 
> Hello list,
> 
> New to the list.  I've been using some old (circa 2007) Faust code, 
> originally developed by Albert Graef, and modified slightly by me, in one of 
> my Max creations.  I compiled the Faust code into a Max external.
> 
> I've recently been trying to update my Max application to 64 bit, so I 
> recompiled the Faust code (using the online IDE) to create a 64 bit Max 
> external.  That worked fine (with one minor tweak that Stephane Letz helped 
> me with), but now the external is not behaving correctly.
> 
> I am NOT a Faust expert (or even basic user really), so I'm looking at this 
> with newbie eyes.  When I look online at "current" Faust, it seems that most 
> of the libraries have now been included in "stdfaust.lib", and so as I look 
> at my old code, I'm wondering if I need to update the calls to functions from 
> those older libraries (music.lib and math.lib) to the current ones?  I assume 
> math.lib maps to the current maths.lib, but what about music.lib?
> 
> Thanks for any assistance in advance, I greatly appreciate it!
> 
> -Dan


_______________________________________________
Faudiostream-users mailing list
Faudiostream-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/faudiostream-users

Reply via email to