kopia lustrzana https://github.com/f4exb/sdrangel
				
				
				
			WDSP: added ANB and NOB blocks (noise blanker)
							rodzic
							
								
									74cc488383
								
							
						
					
					
						commit
						02a73de41b
					
				| 
						 | 
				
			
			@ -5,6 +5,7 @@ set(wdsp_SOURCES
 | 
			
		|||
    amd.cpp
 | 
			
		||||
    ammod.cpp
 | 
			
		||||
    amsq.cpp
 | 
			
		||||
    anb.cpp
 | 
			
		||||
    anf.cpp
 | 
			
		||||
    anr.cpp
 | 
			
		||||
    bandpass.cpp
 | 
			
		||||
| 
						 | 
				
			
			@ -34,6 +35,7 @@ set(wdsp_SOURCES
 | 
			
		|||
    meter.cpp
 | 
			
		||||
    meterlog10.cpp
 | 
			
		||||
    nbp.cpp
 | 
			
		||||
    nob.cpp
 | 
			
		||||
    osctrl.cpp
 | 
			
		||||
    patchpanel.cpp
 | 
			
		||||
    resample.cpp
 | 
			
		||||
| 
						 | 
				
			
			@ -54,6 +56,7 @@ set(wdsp_HEADERS
 | 
			
		|||
    amd.hpp
 | 
			
		||||
    ammod.hpp
 | 
			
		||||
    amsq.hpp
 | 
			
		||||
    anb.hpp
 | 
			
		||||
    anf.hpp
 | 
			
		||||
    anr.hpp
 | 
			
		||||
    bandpass.hpp
 | 
			
		||||
| 
						 | 
				
			
			@ -85,6 +88,7 @@ set(wdsp_HEADERS
 | 
			
		|||
    meter.hpp
 | 
			
		||||
    meterlog10.hpp
 | 
			
		||||
    nbp.hpp
 | 
			
		||||
    nob.hpp
 | 
			
		||||
    osctrl.hpp
 | 
			
		||||
    patchpanel.hpp
 | 
			
		||||
    resample.hpp
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										58
									
								
								wdsp/RXA.cpp
								
								
								
								
							
							
						
						
									
										58
									
								
								wdsp/RXA.cpp
								
								
								
								
							| 
						 | 
				
			
			@ -52,6 +52,8 @@ warren@wpratt.com
 | 
			
		|||
#include "iir.hpp"
 | 
			
		||||
#include "firmin.hpp"
 | 
			
		||||
#include "wcpAGC.hpp"
 | 
			
		||||
#include "anb.hpp"
 | 
			
		||||
#include "nob.hpp"
 | 
			
		||||
 | 
			
		||||
namespace WDSP {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -85,6 +87,36 @@ RXA* RXA::create_rxa (
 | 
			
		|||
    rxa->midbuff = new float[2 * rxa->dsp_size  * 2]; // (float *) malloc0 (2 * ch.dsp_size    * sizeof (complex));
 | 
			
		||||
    memset(rxa->meter, 0, sizeof(float)*RXA_METERTYPE_LAST);
 | 
			
		||||
 | 
			
		||||
    // Noise blanker (ANB or "NB")
 | 
			
		||||
    rxa->anb.p = ANB::create_anb(
 | 
			
		||||
        0, // run
 | 
			
		||||
        rxa->dsp_insize,                        // input buffer size
 | 
			
		||||
        rxa->inbuff,                            // pointer to input buffer
 | 
			
		||||
        rxa->inbuff,                            // pointer to output buffer
 | 
			
		||||
        rxa->in_rate,                           // samplerate
 | 
			
		||||
        0.0001,                                 // tau
 | 
			
		||||
        0.0001,                                 // hang time
 | 
			
		||||
        0.0001,                                 // advance time
 | 
			
		||||
        0.05,                                   // back tau
 | 
			
		||||
        30.0                                    // thershold
 | 
			
		||||
    );
 | 
			
		||||
    // Noise blanker (NOB or "NB2")
 | 
			
		||||
    rxa->nob.p = NOB::create_nob(
 | 
			
		||||
        0, // run
 | 
			
		||||
        rxa->dsp_insize,                        // input buffer size
 | 
			
		||||
        rxa->inbuff,                            // pointer to input buffer
 | 
			
		||||
        rxa->inbuff,                            // pointer to output buffer
 | 
			
		||||
        rxa->in_rate,                           // samplerate
 | 
			
		||||
        0,                                      // mode (zero)
 | 
			
		||||
        0.0001,                                 // advance slew time
 | 
			
		||||
        0.0001,                                 // advance time
 | 
			
		||||
        0.0001,                                 // hang slew time
 | 
			
		||||
        0.0001,                                 // hang time
 | 
			
		||||
        0.025,                                  // max_imp_seq_time:
 | 
			
		||||
        0.05,                                   // back tau
 | 
			
		||||
        30
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // Ftequency shifter - shift to select a slice of spectrum
 | 
			
		||||
    rxa->shift.p = SHIFT::create_shift (
 | 
			
		||||
        1,                                      // run
 | 
			
		||||
| 
						 | 
				
			
			@ -571,6 +603,8 @@ void RXA::destroy_rxa (RXA *rxa)
 | 
			
		|||
    GEN::destroy_gen (rxa->gen0.p);
 | 
			
		||||
    RESAMPLE::destroy_resample (rxa->rsmpin.p);
 | 
			
		||||
    SHIFT::destroy_shift (rxa->shift.p);
 | 
			
		||||
    ANB::destroy_anb(rxa->anb.p);
 | 
			
		||||
    NOB::destroy_nob(rxa->nob.p);
 | 
			
		||||
    delete[] (rxa->midbuff);
 | 
			
		||||
    delete[] (rxa->outbuff);
 | 
			
		||||
    delete[] (rxa->inbuff);
 | 
			
		||||
| 
						 | 
				
			
			@ -609,10 +643,14 @@ void RXA::flush_rxa (RXA *rxa)
 | 
			
		|||
    SSQL::flush_ssql (rxa->ssql.p);
 | 
			
		||||
    PANEL::flush_panel (rxa->panel.p);
 | 
			
		||||
    RESAMPLE::flush_resample (rxa->rsmpout.p);
 | 
			
		||||
    ANB::flush_anb (rxa->anb.p);
 | 
			
		||||
    NOB::flush_nob(rxa->nob.p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RXA::xrxa (RXA *rxa)
 | 
			
		||||
{
 | 
			
		||||
    ANB::xanb (rxa->anb.p);
 | 
			
		||||
    NOB::xnob (rxa->nob.p);
 | 
			
		||||
    SHIFT::xshift (rxa->shift.p);
 | 
			
		||||
    RESAMPLE::xresample (rxa->rsmpin.p);
 | 
			
		||||
    GEN::xgen (rxa->gen0.p);
 | 
			
		||||
| 
						 | 
				
			
			@ -661,6 +699,14 @@ void RXA::setInputSamplerate (RXA *rxa, int in_rate)
 | 
			
		|||
    // buffers
 | 
			
		||||
    delete[] (rxa->inbuff);
 | 
			
		||||
    rxa->inbuff = new float[1 * rxa->dsp_insize  * 2]; // (float *)malloc0(1 * ch.dsp_insize  * sizeof(complex));
 | 
			
		||||
    // anb
 | 
			
		||||
    ANB::setBuffers_anb(rxa->anb.p, rxa->inbuff, rxa->inbuff);
 | 
			
		||||
    ANB::setSize_anb(rxa->anb.p, rxa->dsp_insize);
 | 
			
		||||
    ANB::setSamplerate_anb(rxa->anb.p, rxa->in_rate);
 | 
			
		||||
    // nob
 | 
			
		||||
    NOB::setBuffers_nob(rxa->nob.p, rxa->inbuff, rxa->inbuff);
 | 
			
		||||
    NOB::setSize_nob(rxa->nob.p, rxa->dsp_insize);
 | 
			
		||||
    NOB::setSamplerate_nob(rxa->nob.p, rxa->in_rate);
 | 
			
		||||
    // shift
 | 
			
		||||
    SHIFT::setBuffers_shift (rxa->shift.p, rxa->inbuff, rxa->inbuff);
 | 
			
		||||
    SHIFT::setSize_shift (rxa->shift.p, rxa->dsp_insize);
 | 
			
		||||
| 
						 | 
				
			
			@ -708,6 +754,12 @@ void RXA::setDSPSamplerate (RXA *rxa, int dsp_rate)
 | 
			
		|||
    rxa->inbuff = new float[1 * rxa->dsp_insize  * 2]; // (float *)malloc0(1 * rxa->dsp_insize  * sizeof(complex));
 | 
			
		||||
    delete[] (rxa->outbuff);
 | 
			
		||||
    rxa->outbuff = new float[1 * rxa->dsp_outsize * 2]; // (float *)malloc0(1 * rxa->dsp_outsize * sizeof(complex));
 | 
			
		||||
    // anb
 | 
			
		||||
    ANB::setBuffers_anb (rxa->anb.p, rxa->inbuff, rxa->inbuff);
 | 
			
		||||
    ANB::setSize_anb(rxa->anb.p, rxa->dsp_insize);
 | 
			
		||||
    // nob
 | 
			
		||||
    NOB::setBuffers_nob(rxa->nob.p, rxa->inbuff, rxa->inbuff);
 | 
			
		||||
    NOB::setSize_nob(rxa->nob.p, rxa->dsp_insize);
 | 
			
		||||
    // shift
 | 
			
		||||
    SHIFT::setBuffers_shift (rxa->shift.p, rxa->inbuff, rxa->inbuff);
 | 
			
		||||
    SHIFT::setSize_shift (rxa->shift.p, rxa->dsp_insize);
 | 
			
		||||
| 
						 | 
				
			
			@ -767,6 +819,12 @@ void RXA::setDSPBuffsize (RXA *rxa, int dsp_size)
 | 
			
		|||
    rxa->midbuff = new float[2 * rxa->dsp_size * 2]; // (float *)malloc0(2 * rxa->dsp_size * sizeof(complex));
 | 
			
		||||
    delete[] (rxa->outbuff);
 | 
			
		||||
    rxa->outbuff = new float[1 * rxa->dsp_outsize * 2]; // (float *)malloc0(1 * rxa->dsp_outsize * sizeof(complex));
 | 
			
		||||
    // anb
 | 
			
		||||
    ANB::setBuffers_anb (rxa->anb.p, rxa->inbuff, rxa->inbuff);
 | 
			
		||||
    ANB::setSize_anb (rxa->anb.p, rxa->dsp_insize);
 | 
			
		||||
    // nob
 | 
			
		||||
    NOB::setBuffers_nob(rxa->nob.p, rxa->inbuff, rxa->inbuff);
 | 
			
		||||
    NOB::setSize_nob(rxa->nob.p, rxa->dsp_insize);
 | 
			
		||||
    // shift
 | 
			
		||||
    SHIFT::setBuffers_shift (rxa->shift.p, rxa->inbuff, rxa->inbuff);
 | 
			
		||||
    SHIFT::setSize_shift (rxa->shift.p, rxa->dsp_insize);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										10
									
								
								wdsp/RXA.hpp
								
								
								
								
							
							
						
						
									
										10
									
								
								wdsp/RXA.hpp
								
								
								
								
							| 
						 | 
				
			
			@ -63,6 +63,8 @@ class PANEL;
 | 
			
		|||
class SIPHON;
 | 
			
		||||
class CBL;
 | 
			
		||||
class SSQL;
 | 
			
		||||
class ANB;
 | 
			
		||||
class NOB;
 | 
			
		||||
class BufferProbe;
 | 
			
		||||
 | 
			
		||||
class WDSP_API RXA : public Unit
 | 
			
		||||
| 
						 | 
				
			
			@ -203,6 +205,14 @@ public:
 | 
			
		|||
    {
 | 
			
		||||
        SSQL *p;
 | 
			
		||||
    } ssql;
 | 
			
		||||
    struct
 | 
			
		||||
    {
 | 
			
		||||
        ANB *p;
 | 
			
		||||
    } anb;
 | 
			
		||||
    struct
 | 
			
		||||
    {
 | 
			
		||||
        NOB *p;
 | 
			
		||||
    } nob;
 | 
			
		||||
 | 
			
		||||
    static RXA* create_rxa (
 | 
			
		||||
        int in_rate,                // input samplerate
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,282 @@
 | 
			
		|||
/*  anb.h
 | 
			
		||||
 | 
			
		||||
This file is part of a program that implements a Software-Defined Radio.
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2013, 2014 Warren Pratt, NR0V
 | 
			
		||||
Copyright (C) 2024 Edouard Griffiths, F4EXB Adapted to SDRangel
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or
 | 
			
		||||
modify it under the terms of the GNU General Public License
 | 
			
		||||
as published by the Free Software Foundation; either version 2
 | 
			
		||||
of the License, or (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program; if not, write to the Free Software
 | 
			
		||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 | 
			
		||||
 | 
			
		||||
The author can be reached by email at
 | 
			
		||||
 | 
			
		||||
warren@wpratt.com
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "comm.hpp"
 | 
			
		||||
#include "anb.hpp"
 | 
			
		||||
#include "RXA.hpp"
 | 
			
		||||
 | 
			
		||||
#define MAX_TAU         (0.002)     // maximum transition time, signal<->zero
 | 
			
		||||
#define MAX_ADVTIME     (0.002)     // maximum deadtime (zero output) in advance of detected noise
 | 
			
		||||
#define MAX_SAMPLERATE  (1536000)
 | 
			
		||||
 | 
			
		||||
namespace WDSP {
 | 
			
		||||
 | 
			
		||||
void ANB::initBlanker(ANB *a)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    a->trans_count = (int)(a->tau * a->samplerate);
 | 
			
		||||
    if (a->trans_count < 2) a->trans_count = 2;
 | 
			
		||||
    a->hang_count = (int)(a->hangtime * a->samplerate);
 | 
			
		||||
    a->adv_count = (int)(a->advtime * a->samplerate);
 | 
			
		||||
    a->count = 0;
 | 
			
		||||
    a->in_idx = a->trans_count + a->adv_count;
 | 
			
		||||
    a->out_idx = 0;
 | 
			
		||||
    a->coef = PI / a->trans_count;
 | 
			
		||||
    a->state = 0;
 | 
			
		||||
    a->avg = 1.0;
 | 
			
		||||
    a->power = 1.0;
 | 
			
		||||
    a->backmult = exp(-1.0 / (a->samplerate * a->backtau));
 | 
			
		||||
    a->ombackmult = 1.0 - a->backmult;
 | 
			
		||||
    for (i = 0; i <= a->trans_count; i++)
 | 
			
		||||
        a->wave[i] = 0.5 * cos(i * a->coef);
 | 
			
		||||
    memset(a->dline, 0, a->dline_size * sizeof(wcomplex));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ANB* ANB::create_anb  (
 | 
			
		||||
    int run,
 | 
			
		||||
    int buffsize,
 | 
			
		||||
    float* in,
 | 
			
		||||
    float* out,
 | 
			
		||||
    double samplerate,
 | 
			
		||||
    double tau,
 | 
			
		||||
    double hangtime,
 | 
			
		||||
    double advtime,
 | 
			
		||||
    double backtau,
 | 
			
		||||
    double threshold
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
    ANB *a;
 | 
			
		||||
    a = new ANB;
 | 
			
		||||
    a->run = run;
 | 
			
		||||
    a->buffsize = buffsize;
 | 
			
		||||
    a->in = in;
 | 
			
		||||
    a->out = out;
 | 
			
		||||
    a->samplerate = samplerate;
 | 
			
		||||
    a->tau = tau;
 | 
			
		||||
    a->hangtime = hangtime;
 | 
			
		||||
    a->advtime = advtime;
 | 
			
		||||
    a->backtau = backtau;
 | 
			
		||||
    a->threshold = threshold;
 | 
			
		||||
    a->wave = new float[((int)(MAX_SAMPLERATE * MAX_TAU) + 1)];
 | 
			
		||||
    a->dline_size = (int)((MAX_TAU + MAX_ADVTIME) * MAX_SAMPLERATE) + 1;
 | 
			
		||||
    a->dline = new float[a->dline_size * 2];
 | 
			
		||||
    initBlanker(a);
 | 
			
		||||
    a->legacy = new float[2048 * 2];  /////////////// legacy interface - remove
 | 
			
		||||
    return a;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ANB::destroy_anb (ANB *a)
 | 
			
		||||
{
 | 
			
		||||
    delete[] (a->legacy);                                                                                      /////////////// legacy interface - remove
 | 
			
		||||
    delete[] (a->dline);
 | 
			
		||||
    delete[] (a->wave);
 | 
			
		||||
    delete (a);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ANB::flush_anb (ANB *a)
 | 
			
		||||
{
 | 
			
		||||
    a->cs_update.lock();
 | 
			
		||||
    initBlanker (a);
 | 
			
		||||
    a->cs_update.unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ANB::xanb (ANB *a)
 | 
			
		||||
{
 | 
			
		||||
    double scale;
 | 
			
		||||
    double mag;
 | 
			
		||||
    int i;
 | 
			
		||||
    if (a->run)
 | 
			
		||||
    {
 | 
			
		||||
        a->cs_update.lock();
 | 
			
		||||
        for (i = 0; i < a->buffsize; i++)
 | 
			
		||||
        {
 | 
			
		||||
            mag = sqrt(a->in[2 * i + 0] * a->in[2 * i + 0] + a->in[2 * i + 1] * a->in[2 * i + 1]);
 | 
			
		||||
            a->avg = a->backmult * a->avg + a->ombackmult * mag;
 | 
			
		||||
            a->dline[2 * a->in_idx + 0] = a->in[2 * i + 0];
 | 
			
		||||
            a->dline[2 * a->in_idx + 1] = a->in[2 * i + 1];
 | 
			
		||||
            if (mag > (a->avg * a->threshold))
 | 
			
		||||
                a->count = a->trans_count + a->adv_count;
 | 
			
		||||
 | 
			
		||||
            switch (a->state)
 | 
			
		||||
            {
 | 
			
		||||
                case 0:
 | 
			
		||||
                    a->out[2 * i + 0] = a->dline[2 * a->out_idx + 0];
 | 
			
		||||
                    a->out[2 * i + 1] = a->dline[2 * a->out_idx + 1];
 | 
			
		||||
                    if (a->count > 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        a->state = 1;
 | 
			
		||||
                        a->dtime = 0;
 | 
			
		||||
                        a->power = 1.0;
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
                case 1:
 | 
			
		||||
                    scale = a->power * (0.5 + a->wave[a->dtime]);
 | 
			
		||||
                    a->out[2 * i + 0] = a->dline[2 * a->out_idx + 0] * scale;
 | 
			
		||||
                    a->out[2 * i + 1] = a->dline[2 * a->out_idx + 1] * scale;
 | 
			
		||||
                    if (++a->dtime > a->trans_count)
 | 
			
		||||
                    {
 | 
			
		||||
                        a->state = 2;
 | 
			
		||||
                        a->atime = 0;
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
                case 2:
 | 
			
		||||
                    a->out[2 * i + 0] = 0.0;
 | 
			
		||||
                    a->out[2 * i + 1] = 0.0;
 | 
			
		||||
                    if (++a->atime > a->adv_count)
 | 
			
		||||
                        a->state = 3;
 | 
			
		||||
                    break;
 | 
			
		||||
                case 3:
 | 
			
		||||
                    if (a->count > 0)
 | 
			
		||||
                        a->htime = -a->count;
 | 
			
		||||
 | 
			
		||||
                    a->out[2 * i + 0] = 0.0;
 | 
			
		||||
                    a->out[2 * i + 1] = 0.0;
 | 
			
		||||
                    if (++a->htime > a->hang_count)
 | 
			
		||||
                    {
 | 
			
		||||
                        a->state = 4;
 | 
			
		||||
                        a->itime = 0;
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
                case 4:
 | 
			
		||||
                    scale = 0.5 - a->wave[a->itime];
 | 
			
		||||
                    a->out[2 * i + 0] = a->dline[2 * a->out_idx + 0] * scale;
 | 
			
		||||
                    a->out[2 * i + 1] = a->dline[2 * a->out_idx + 1] * scale;
 | 
			
		||||
                    if (a->count > 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        a->state = 1;
 | 
			
		||||
                        a->dtime = 0;
 | 
			
		||||
                        a->power = scale;
 | 
			
		||||
                    }
 | 
			
		||||
                    else if (++a->itime > a->trans_count)
 | 
			
		||||
                        a->state = 0;
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
            if (a->count > 0) a->count--;
 | 
			
		||||
            if (++a->in_idx == a->dline_size) a->in_idx = 0;
 | 
			
		||||
            if (++a->out_idx == a->dline_size) a->out_idx = 0;
 | 
			
		||||
        }
 | 
			
		||||
        a->cs_update.unlock();
 | 
			
		||||
    }
 | 
			
		||||
    else if (a->in != a->out)
 | 
			
		||||
        memcpy (a->out, a->in, a->buffsize * sizeof (wcomplex));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ANB::setBuffers_anb (ANB *a, float* in, float* out)
 | 
			
		||||
{
 | 
			
		||||
    a->in = in;
 | 
			
		||||
    a->out = out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ANB::setSamplerate_anb (ANB *a, int rate)
 | 
			
		||||
{
 | 
			
		||||
    a->samplerate = rate;
 | 
			
		||||
    initBlanker (a);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ANB::setSize_anb (ANB *a, int size)
 | 
			
		||||
{
 | 
			
		||||
    a->buffsize = size;
 | 
			
		||||
    initBlanker (a);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/********************************************************************************************************
 | 
			
		||||
*                                                                                                       *
 | 
			
		||||
*                                             RXA PROPERTIES                                            *
 | 
			
		||||
*                                                                                                       *
 | 
			
		||||
********************************************************************************************************/
 | 
			
		||||
 | 
			
		||||
void ANB::SetRXAANBRun (RXA& rxa, int run)
 | 
			
		||||
{
 | 
			
		||||
    ANB *a = rxa.anb.p;
 | 
			
		||||
    a->cs_update.lock();
 | 
			
		||||
    a->run = run;
 | 
			
		||||
    a->cs_update.unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ANB::SetRXAANBBuffsize (RXA& rxa, int size)
 | 
			
		||||
{
 | 
			
		||||
    ANB *a = rxa.anb.p;
 | 
			
		||||
    a->cs_update.lock();
 | 
			
		||||
    a->buffsize = size;
 | 
			
		||||
    a->cs_update.unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ANB::SetRXAANBSamplerate (RXA& rxa, int rate)
 | 
			
		||||
{
 | 
			
		||||
    ANB *a = rxa.anb.p;
 | 
			
		||||
    a->cs_update.lock();
 | 
			
		||||
    a->samplerate = (double) rate;
 | 
			
		||||
    initBlanker (a);
 | 
			
		||||
    a->cs_update.unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ANB::SetRXAANBTau (RXA& rxa, double tau)
 | 
			
		||||
{
 | 
			
		||||
    ANB *a = rxa.anb.p;
 | 
			
		||||
    a->cs_update.lock();
 | 
			
		||||
    a->tau = tau;
 | 
			
		||||
    initBlanker (a);
 | 
			
		||||
    a->cs_update.unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ANB::SetRXAANBHangtime (RXA& rxa, double time)
 | 
			
		||||
{
 | 
			
		||||
    ANB *a = rxa.anb.p;
 | 
			
		||||
    a->cs_update.lock();
 | 
			
		||||
    a->hangtime = time;
 | 
			
		||||
    initBlanker (a);
 | 
			
		||||
    a->cs_update.unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ANB::SetRXAANBAdvtime (RXA& rxa, double time)
 | 
			
		||||
{
 | 
			
		||||
    ANB *a = rxa.anb.p;
 | 
			
		||||
    a->cs_update.lock();
 | 
			
		||||
    a->advtime = time;
 | 
			
		||||
    initBlanker (a);
 | 
			
		||||
    a->cs_update.unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ANB::SetRXAANBBacktau (RXA& rxa, double tau)
 | 
			
		||||
{
 | 
			
		||||
    ANB *a = rxa.anb.p;
 | 
			
		||||
    a->cs_update.lock();
 | 
			
		||||
    a->backtau = tau;
 | 
			
		||||
    initBlanker (a);
 | 
			
		||||
    a->cs_update.unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ANB::SetRXAANBThreshold (RXA& rxa, double thresh)
 | 
			
		||||
{
 | 
			
		||||
    ANB *a = rxa.anb.p;
 | 
			
		||||
    a->cs_update.lock();
 | 
			
		||||
    a->threshold = thresh;
 | 
			
		||||
    a->cs_update.unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,109 @@
 | 
			
		|||
/*  anb.h
 | 
			
		||||
 | 
			
		||||
This file is part of a program that implements a Software-Defined Radio.
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2013, 2014 Warren Pratt, NR0V
 | 
			
		||||
Copyright (C) 2024 Edouard Griffiths, F4EXB Adapted to SDRangel
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or
 | 
			
		||||
modify it under the terms of the GNU General Public License
 | 
			
		||||
as published by the Free Software Foundation; either version 2
 | 
			
		||||
of the License, or (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program; if not, write to the Free Software
 | 
			
		||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 | 
			
		||||
 | 
			
		||||
The author can be reached by email at
 | 
			
		||||
 | 
			
		||||
warren@wpratt.com
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef wdsp_anb_h
 | 
			
		||||
#define wdsp_anb_h
 | 
			
		||||
 | 
			
		||||
#include <QRecursiveMutex>
 | 
			
		||||
 | 
			
		||||
namespace WDSP {
 | 
			
		||||
 | 
			
		||||
class RXA;
 | 
			
		||||
 | 
			
		||||
class ANB
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    int run;
 | 
			
		||||
    int buffsize;                   // size of input/output buffer
 | 
			
		||||
    float* in;                     // input buffer
 | 
			
		||||
    float* out;                    // output buffer
 | 
			
		||||
    int dline_size;                 // length of delay line which is 'double dline[length][2]'
 | 
			
		||||
    float *dline;                  // pointer to delay line
 | 
			
		||||
    double samplerate;              // samplerate, used to convert times into sample counts
 | 
			
		||||
    double tau;                     // transition time, signal<->zero
 | 
			
		||||
    double hangtime;                // time to stay at zero after noise is no longer detected
 | 
			
		||||
    double advtime;                 // deadtime (zero output) in advance of detected noise
 | 
			
		||||
    double backtau;                 // time constant used in averaging the magnitude of the input signal
 | 
			
		||||
    double threshold;               // triggers if (noise > threshold * average_signal_magnitude)
 | 
			
		||||
    float *wave;                   // pointer to array holding transition waveform
 | 
			
		||||
    int state;                      // state of the state machine
 | 
			
		||||
    double avg;                     // average value of the signal magnitude
 | 
			
		||||
    int dtime;                      // count when decreasing the signal magnitude
 | 
			
		||||
    int htime;                      // count when hanging
 | 
			
		||||
    int itime;                      // count when increasing the signal magnitude
 | 
			
		||||
    int atime;                      // count at zero before the noise burst (advance count)
 | 
			
		||||
    double coef;                    // parameter in calculating transition waveform
 | 
			
		||||
    int trans_count;                // number of samples to equal 'tau' time
 | 
			
		||||
    int hang_count;                 // number of samples to equal 'hangtime' time
 | 
			
		||||
    int adv_count;                  // number of samples to equal 'advtime' time
 | 
			
		||||
    int in_idx;                     // ring buffer position into which new samples are inserted
 | 
			
		||||
    int out_idx;                    // ring buffer position from which delayed samples are pulled
 | 
			
		||||
    double power;                   // level at which signal was increasing when a new decrease is started
 | 
			
		||||
    int count;                      // set each time a noise sample is detected, counts down
 | 
			
		||||
    double backmult;                // multiplier for waveform averaging
 | 
			
		||||
    double ombackmult;              // multiplier for waveform averaging
 | 
			
		||||
    QRecursiveMutex cs_update;
 | 
			
		||||
    float *legacy;
 | 
			
		||||
 | 
			
		||||
    static ANB* create_anb   (
 | 
			
		||||
        int run,
 | 
			
		||||
        int buffsize,
 | 
			
		||||
        float* in,
 | 
			
		||||
        float* out,
 | 
			
		||||
        double samplerate,
 | 
			
		||||
        double tau,
 | 
			
		||||
        double hangtime,
 | 
			
		||||
        double advtime,
 | 
			
		||||
        double backtau,
 | 
			
		||||
        double threshold
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    static void destroy_anb (ANB *a);
 | 
			
		||||
    static void flush_anb (ANB *a);
 | 
			
		||||
    static void xanb (ANB *a);
 | 
			
		||||
    static void setBuffers_anb (ANB *a, float* in, float* out);
 | 
			
		||||
    static void setSamplerate_anb (ANB *a, int rate);
 | 
			
		||||
    static void setSize_anb (ANB *a, int size);
 | 
			
		||||
    // RXA
 | 
			
		||||
    static void SetRXAANBRun (RXA& rxa, int run);
 | 
			
		||||
    static void SetRXAANBBuffsize (RXA& rxa, int size);
 | 
			
		||||
    static void SetRXAANBSamplerate (RXA& rxa, int rate);
 | 
			
		||||
    static void SetRXAANBTau (RXA& rxa, double tau);
 | 
			
		||||
    static void SetRXAANBHangtime (RXA& rxa, double time);
 | 
			
		||||
    static void SetRXAANBAdvtime (RXA& rxa, double time);
 | 
			
		||||
    static void SetRXAANBBacktau (RXA& rxa, double tau);
 | 
			
		||||
    static void SetRXAANBThreshold (RXA& rxa, double thresh);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    static void initBlanker(ANB *a);                                                                                                    ////////////  legacy interface - remove
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
} // namespace
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,600 @@
 | 
			
		|||
/*  nobII.c
 | 
			
		||||
 | 
			
		||||
This file is part of a program that implements a Software-Defined Radio.
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2014 Warren Pratt, NR0V
 | 
			
		||||
Copyright (C) 2024 Edouard Griffiths, F4EXB Adapted to SDRangel
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or
 | 
			
		||||
modify it under the terms of the GNU General Public License
 | 
			
		||||
as published by the Free Software Foundation; either version 2
 | 
			
		||||
of the License, or (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program; if not, write to the Free Software
 | 
			
		||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 | 
			
		||||
 | 
			
		||||
The author can be reached by email at
 | 
			
		||||
 | 
			
		||||
warren@wpratt.com
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "comm.hpp"
 | 
			
		||||
 | 
			
		||||
#define MAX_ADV_SLEW_TIME           (0.002)
 | 
			
		||||
#define MAX_ADV_TIME                (0.002)
 | 
			
		||||
#define MAX_HANG_SLEW_TIME          (0.002)
 | 
			
		||||
#define MAX_HANG_TIME               (0.002)
 | 
			
		||||
#define MAX_SEQ_TIME                (0.025)
 | 
			
		||||
#define MAX_SAMPLERATE              (1536000.0)
 | 
			
		||||
 | 
			
		||||
#include "nob.hpp"
 | 
			
		||||
#include "RXA.hpp"
 | 
			
		||||
 | 
			
		||||
namespace WDSP {
 | 
			
		||||
 | 
			
		||||
void NOB::init_nob (NOB *a)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    double coef;
 | 
			
		||||
    a->adv_slew_count = (int)(a->advslewtime * a->samplerate);
 | 
			
		||||
    a->adv_count = (int)(a->advtime * a->samplerate);
 | 
			
		||||
    a->hang_count = (int)(a->hangtime * a->samplerate);
 | 
			
		||||
    a->hang_slew_count = (int)(a->hangslewtime * a->samplerate);
 | 
			
		||||
    a->max_imp_seq = (int)(a->max_imp_seq_time * a->samplerate);
 | 
			
		||||
    a->backmult = exp (-1.0 / (a->samplerate * a->backtau));
 | 
			
		||||
    a->ombackmult = 1.0 - a->backmult;
 | 
			
		||||
    if (a->adv_slew_count > 0)
 | 
			
		||||
    {
 | 
			
		||||
        coef = PI / (a->adv_slew_count + 1);
 | 
			
		||||
        for (i = 0; i < a->adv_slew_count; i++)
 | 
			
		||||
            a->awave[i] = 0.5 * cos ((i + 1) * coef);
 | 
			
		||||
    }
 | 
			
		||||
    if (a->hang_slew_count > 0)
 | 
			
		||||
    {
 | 
			
		||||
        coef = PI / a->hang_slew_count;
 | 
			
		||||
        for (i = 0; i < a->hang_slew_count; i++)
 | 
			
		||||
            a->hwave[i] = 0.5 * cos (i * coef);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    flush_nob (a);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NOB* NOB::create_nob (
 | 
			
		||||
    int run,
 | 
			
		||||
    int buffsize,
 | 
			
		||||
    float* in,
 | 
			
		||||
    float* out,
 | 
			
		||||
    double samplerate,
 | 
			
		||||
    int mode,
 | 
			
		||||
    double advslewtime,
 | 
			
		||||
    double advtime,
 | 
			
		||||
    double hangslewtime,
 | 
			
		||||
    double hangtime,
 | 
			
		||||
    double max_imp_seq_time,
 | 
			
		||||
    double backtau,
 | 
			
		||||
    double threshold
 | 
			
		||||
    )
 | 
			
		||||
{
 | 
			
		||||
    NOB *a = new NOB;
 | 
			
		||||
    a->run = run;
 | 
			
		||||
    a->buffsize = buffsize;
 | 
			
		||||
    a->in = in;
 | 
			
		||||
    a->out = out;
 | 
			
		||||
    a->samplerate = samplerate;
 | 
			
		||||
    a->mode = mode;
 | 
			
		||||
    a->advslewtime = advslewtime;
 | 
			
		||||
    a->advtime = advtime;
 | 
			
		||||
    a->hangslewtime = hangslewtime;
 | 
			
		||||
    a->hangtime = hangtime;
 | 
			
		||||
    a->max_imp_seq_time = max_imp_seq_time;
 | 
			
		||||
    a->backtau = backtau;
 | 
			
		||||
    a->threshold = threshold;
 | 
			
		||||
    a->dline_size = (int)(MAX_SAMPLERATE * (MAX_ADV_SLEW_TIME +
 | 
			
		||||
                                            MAX_ADV_TIME +
 | 
			
		||||
                                            MAX_HANG_SLEW_TIME +
 | 
			
		||||
                                            MAX_HANG_TIME +
 | 
			
		||||
                                            MAX_SEQ_TIME ) + 2);
 | 
			
		||||
    a->dline = new double[a->dline_size * 2];
 | 
			
		||||
    a->imp = new int[a->dline_size];
 | 
			
		||||
    a->awave = new double[(int)(MAX_ADV_SLEW_TIME  * MAX_SAMPLERATE + 1)];
 | 
			
		||||
    a->hwave = new double[(int)(MAX_HANG_SLEW_TIME * MAX_SAMPLERATE + 1)];
 | 
			
		||||
 | 
			
		||||
    a->filterlen = 10;
 | 
			
		||||
    a->bfbuff = new double[a->filterlen * 2];
 | 
			
		||||
    a->ffbuff = new double[a->filterlen * 2];
 | 
			
		||||
    a->fcoefs = new double[a->filterlen];
 | 
			
		||||
    a->fcoefs[0] = 0.308720593;
 | 
			
		||||
    a->fcoefs[1] = 0.216104415;
 | 
			
		||||
    a->fcoefs[2] = 0.151273090;
 | 
			
		||||
    a->fcoefs[3] = 0.105891163;
 | 
			
		||||
    a->fcoefs[4] = 0.074123814;
 | 
			
		||||
    a->fcoefs[5] = 0.051886670;
 | 
			
		||||
    a->fcoefs[6] = 0.036320669;
 | 
			
		||||
    a->fcoefs[7] = 0.025424468;
 | 
			
		||||
    a->fcoefs[8] = 0.017797128;
 | 
			
		||||
    a->fcoefs[9] = 0.012457989;
 | 
			
		||||
 | 
			
		||||
    init_nob (a);
 | 
			
		||||
 | 
			
		||||
    a->legacy = new double[2048 * 2];    /////////////// legacy interface - remove
 | 
			
		||||
    return a;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NOB::destroy_nob (NOB *a)
 | 
			
		||||
{
 | 
			
		||||
    delete[] (a->legacy); ///////////////  remove
 | 
			
		||||
    delete[] (a->fcoefs);
 | 
			
		||||
    delete[] (a->ffbuff);
 | 
			
		||||
    delete[] (a->bfbuff);
 | 
			
		||||
    delete[] (a->hwave);
 | 
			
		||||
    delete[] (a->awave);
 | 
			
		||||
    delete[] (a->imp);
 | 
			
		||||
    delete[] (a->dline);
 | 
			
		||||
    delete (a);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NOB::flush_nob (NOB *a)
 | 
			
		||||
{
 | 
			
		||||
    a->out_idx = 0;
 | 
			
		||||
    a->scan_idx = a->out_idx + a->adv_slew_count + a->adv_count + 1;
 | 
			
		||||
    a->in_idx = a->scan_idx + a->max_imp_seq + a->hang_count + a->hang_slew_count + a->filterlen;
 | 
			
		||||
    a->state = 0;
 | 
			
		||||
    a->overflow = 0;
 | 
			
		||||
    a->avg = 1.0;
 | 
			
		||||
    a->bfb_in_idx = a->filterlen - 1;
 | 
			
		||||
    a->ffb_in_idx = a->filterlen - 1;
 | 
			
		||||
    memset (a->dline, 0, a->dline_size * sizeof (wcomplex));
 | 
			
		||||
    memset (a->imp, 0, a->dline_size * sizeof (int));
 | 
			
		||||
    memset (a->bfbuff, 0, a->filterlen * sizeof (wcomplex));
 | 
			
		||||
    memset (a->ffbuff, 0, a->filterlen * sizeof (wcomplex));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NOB::xnob (NOB *a)
 | 
			
		||||
{
 | 
			
		||||
    double scale;
 | 
			
		||||
    double mag;
 | 
			
		||||
    int bf_idx;
 | 
			
		||||
    int ff_idx;
 | 
			
		||||
    int lidx, tidx;
 | 
			
		||||
    int i, j, k;
 | 
			
		||||
    int bfboutidx;
 | 
			
		||||
    int ffboutidx;
 | 
			
		||||
    int hcount;
 | 
			
		||||
    int len;
 | 
			
		||||
    int ffcount;
 | 
			
		||||
    int staydown;
 | 
			
		||||
    a->cs_update.lock();
 | 
			
		||||
    if (a->run)
 | 
			
		||||
    {
 | 
			
		||||
        for (i = 0; i < a->buffsize; i++)
 | 
			
		||||
        {
 | 
			
		||||
            a->dline[2 * a->in_idx + 0] = a->in[2 * i + 0];
 | 
			
		||||
            a->dline[2 * a->in_idx + 1] = a->in[2 * i + 1];
 | 
			
		||||
            mag = sqrt(a->dline[2 * a->in_idx + 0] * a->dline[2 * a->in_idx + 0] + a->dline[2 * a->in_idx + 1] * a->dline[2 * a->in_idx + 1]);
 | 
			
		||||
            a->avg = a->backmult * a->avg + a->ombackmult * mag;
 | 
			
		||||
            if (mag > (a->avg * a->threshold))
 | 
			
		||||
                a->imp[a->in_idx] = 1;
 | 
			
		||||
            else
 | 
			
		||||
                a->imp[a->in_idx] = 0;
 | 
			
		||||
            if ((bf_idx = a->out_idx + a->adv_slew_count) >= a->dline_size) bf_idx -= a->dline_size;
 | 
			
		||||
            if (a->imp[bf_idx] == 0)
 | 
			
		||||
            {
 | 
			
		||||
                if (++a->bfb_in_idx == a->filterlen) a->bfb_in_idx -= a->filterlen;
 | 
			
		||||
                a->bfbuff[2 * a->bfb_in_idx + 0] = a->dline[2 * bf_idx + 0];
 | 
			
		||||
                a->bfbuff[2 * a->bfb_in_idx + 1] = a->dline[2 * bf_idx + 1];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            switch (a->state)
 | 
			
		||||
            {
 | 
			
		||||
                case 0:     // normal output & impulse setup
 | 
			
		||||
                    {
 | 
			
		||||
                        a->out[2 * i + 0] = a->dline[2 * a->out_idx + 0];
 | 
			
		||||
                        a->out[2 * i + 1] = a->dline[2 * a->out_idx + 1];
 | 
			
		||||
                        a->Ilast = a->dline[2 * a->out_idx + 0];
 | 
			
		||||
                        a->Qlast = a->dline[2 * a->out_idx + 1];
 | 
			
		||||
                        if (a->imp[a->scan_idx] > 0)
 | 
			
		||||
                        {
 | 
			
		||||
                            a->time = 0;
 | 
			
		||||
                            if (a->adv_slew_count > 0)
 | 
			
		||||
                                a->state = 1;
 | 
			
		||||
                            else if (a->adv_count > 0)
 | 
			
		||||
                                a->state = 2;
 | 
			
		||||
                            else
 | 
			
		||||
                                a->state = 3;
 | 
			
		||||
                            tidx = a->scan_idx;
 | 
			
		||||
                            a->blank_count = 0;
 | 
			
		||||
                            do
 | 
			
		||||
                            {
 | 
			
		||||
                                len = 0;
 | 
			
		||||
                                hcount = 0;
 | 
			
		||||
                                while ((a->imp[tidx] > 0 || hcount > 0) && a->blank_count < a->max_imp_seq)
 | 
			
		||||
                                {
 | 
			
		||||
                                    a->blank_count++;
 | 
			
		||||
                                    if (hcount > 0) hcount--;
 | 
			
		||||
                                    if (a->imp[tidx] > 0) hcount = a->hang_count + a->hang_slew_count;
 | 
			
		||||
                                    if (++tidx >= a->dline_size) tidx -= a->dline_size;
 | 
			
		||||
                                }
 | 
			
		||||
                                j = 1;
 | 
			
		||||
                                len = 0;
 | 
			
		||||
                                lidx = tidx;
 | 
			
		||||
                                while (j <= a->adv_slew_count + a->adv_count && len == 0)
 | 
			
		||||
                                {
 | 
			
		||||
                                    if (a->imp[lidx] == 1)
 | 
			
		||||
                                    {
 | 
			
		||||
                                        len = j;
 | 
			
		||||
                                        tidx = lidx;
 | 
			
		||||
                                    }
 | 
			
		||||
                                    if (++lidx >= a->dline_size) lidx -= a->dline_size;
 | 
			
		||||
                                    j++;
 | 
			
		||||
                                }
 | 
			
		||||
                                if((a->blank_count += len) > a->max_imp_seq)
 | 
			
		||||
                                {
 | 
			
		||||
                                    a->blank_count = a->max_imp_seq;
 | 
			
		||||
                                    a->overflow = 1;
 | 
			
		||||
                                    break;
 | 
			
		||||
                                }
 | 
			
		||||
                            } while (len != 0);
 | 
			
		||||
                            if (a->overflow == 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                a->blank_count -= a->hang_slew_count;
 | 
			
		||||
                                a->Inext = a->dline[2 * tidx + 0];
 | 
			
		||||
                                a->Qnext = a->dline[2 * tidx + 1];
 | 
			
		||||
 | 
			
		||||
                                if (a->mode == 1 || a->mode == 2 || a->mode == 4)
 | 
			
		||||
                                {
 | 
			
		||||
                                    bfboutidx = a->bfb_in_idx;
 | 
			
		||||
                                    a->I1 = 0.0;
 | 
			
		||||
                                    a->Q1 = 0.0;
 | 
			
		||||
                                    for (k = 0; k < a->filterlen; k++)
 | 
			
		||||
                                    {
 | 
			
		||||
                                        a->I1 += a->fcoefs[k] * a->bfbuff[2 * bfboutidx + 0];
 | 
			
		||||
                                        a->Q1 += a->fcoefs[k] * a->bfbuff[2 * bfboutidx + 1];
 | 
			
		||||
                                        if (--bfboutidx < 0) bfboutidx += a->filterlen;
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                if (a->mode == 2 || a->mode == 3 || a->mode == 4)
 | 
			
		||||
                                {
 | 
			
		||||
                                    if ((ff_idx = a->scan_idx + a->blank_count) >= a->dline_size) ff_idx -= a->dline_size;
 | 
			
		||||
                                    ffcount = 0;
 | 
			
		||||
                                    while (ffcount < a->filterlen)
 | 
			
		||||
                                    {
 | 
			
		||||
                                        if (a->imp[ff_idx] == 0)
 | 
			
		||||
                                        {
 | 
			
		||||
                                            if (++a->ffb_in_idx == a->filterlen) a->ffb_in_idx -= a->filterlen;
 | 
			
		||||
                                            a->ffbuff[2 * a->ffb_in_idx + 0] = a->dline[2 * ff_idx + 0];
 | 
			
		||||
                                            a->ffbuff[2 * a->ffb_in_idx + 1] = a->dline[2 * ff_idx + 1];
 | 
			
		||||
                                            ++ffcount;
 | 
			
		||||
                                        }
 | 
			
		||||
                                        if (++ff_idx >= a->dline_size) ff_idx -= a->dline_size;
 | 
			
		||||
                                    }
 | 
			
		||||
                                    if ((ffboutidx = a->ffb_in_idx + 1) >= a->filterlen) ffboutidx -= a->filterlen;
 | 
			
		||||
                                    a->I2 = 0.0;
 | 
			
		||||
                                    a->Q2 = 0.0;
 | 
			
		||||
                                    for (k = 0; k < a->filterlen; k++)
 | 
			
		||||
                                    {
 | 
			
		||||
                                        a->I2 += a->fcoefs[k] * a->ffbuff[2 * ffboutidx + 0];
 | 
			
		||||
                                        a->Q2 += a->fcoefs[k] * a->ffbuff[2 * ffboutidx + 1];
 | 
			
		||||
                                        if (++ffboutidx >= a->filterlen) ffboutidx -= a->filterlen;
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                switch (a->mode)
 | 
			
		||||
                                {
 | 
			
		||||
                                    case 0: // zero
 | 
			
		||||
                                        a->deltaI = 0.0;
 | 
			
		||||
                                        a->deltaQ = 0.0;
 | 
			
		||||
                                        a->I = 0.0;
 | 
			
		||||
                                        a->Q = 0.0;
 | 
			
		||||
                                        break;
 | 
			
		||||
                                    case 1: // sample-hold
 | 
			
		||||
                                        a->deltaI = 0.0;
 | 
			
		||||
                                        a->deltaQ = 0.0;
 | 
			
		||||
                                        a->I = a->I1;
 | 
			
		||||
                                        a->Q = a->Q1;
 | 
			
		||||
                                        break;
 | 
			
		||||
                                    case 2: // mean-hold
 | 
			
		||||
                                        a->deltaI = 0.0;
 | 
			
		||||
                                        a->deltaQ = 0.0;
 | 
			
		||||
                                        a->I = 0.5 * (a->I1 + a->I2);
 | 
			
		||||
                                        a->Q = 0.5 * (a->Q1 + a->Q2);
 | 
			
		||||
                                        break;
 | 
			
		||||
                                    case 3: // hold-sample
 | 
			
		||||
                                        a->deltaI = 0.0;
 | 
			
		||||
                                        a->deltaQ = 0.0;
 | 
			
		||||
                                        a->I = a->I2;
 | 
			
		||||
                                        a->Q = a->Q2;
 | 
			
		||||
                                        break;
 | 
			
		||||
                                    case 4: // linear interpolation
 | 
			
		||||
                                        a->deltaI = (a->I2 - a->I1) / (a->adv_count + a->blank_count);
 | 
			
		||||
                                        a->deltaQ = (a->Q2 - a->Q1) / (a->adv_count + a->blank_count);
 | 
			
		||||
                                        a->I = a->I1;
 | 
			
		||||
                                        a->Q = a->Q1;
 | 
			
		||||
                                        break;
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            else
 | 
			
		||||
                            {
 | 
			
		||||
                                if (a->adv_slew_count > 0)
 | 
			
		||||
                                    a->state = 5;
 | 
			
		||||
                                else
 | 
			
		||||
                                {
 | 
			
		||||
                                    a->state = 6;
 | 
			
		||||
                                    a->time = 0;
 | 
			
		||||
                                    a->blank_count += a->adv_count + a->filterlen;
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                case 1:     // slew output in advance of blanking period
 | 
			
		||||
                    {
 | 
			
		||||
                        scale = 0.5 + a->awave[a->time];
 | 
			
		||||
                        a->out[2 * i + 0] = a->Ilast * scale + (1.0 - scale) * a->I;
 | 
			
		||||
                        a->out[2 * i + 1] = a->Qlast * scale + (1.0 - scale) * a->Q;
 | 
			
		||||
                        if (++a->time == a->adv_slew_count)
 | 
			
		||||
                        {
 | 
			
		||||
                            a->time = 0;
 | 
			
		||||
                            if (a->adv_count > 0)
 | 
			
		||||
                                a->state = 2;
 | 
			
		||||
                            else
 | 
			
		||||
                                a->state = 3;
 | 
			
		||||
                        }
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                case 2:     // initial advance period
 | 
			
		||||
                    {
 | 
			
		||||
                        a->out[2 * i + 0] = a->I;
 | 
			
		||||
                        a->out[2 * i + 1] = a->Q;
 | 
			
		||||
                        a->I += a->deltaI;
 | 
			
		||||
                        a->Q += a->deltaQ;
 | 
			
		||||
 | 
			
		||||
                        if (++a->time == a->adv_count)
 | 
			
		||||
                        {
 | 
			
		||||
                            a->state = 3;
 | 
			
		||||
                            a->time = 0;
 | 
			
		||||
                        }
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                case 3:     // impulse & hang period
 | 
			
		||||
                    {
 | 
			
		||||
                        a->out[2 * i + 0] = a->I;
 | 
			
		||||
                        a->out[2 * i + 1] = a->Q;
 | 
			
		||||
                        a->I += a->deltaI;
 | 
			
		||||
                        a->Q += a->deltaQ;
 | 
			
		||||
 | 
			
		||||
                        if (++a->time == a->blank_count)
 | 
			
		||||
                        {
 | 
			
		||||
                            if (a->hang_slew_count > 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                a->state = 4;
 | 
			
		||||
                                a->time = 0;
 | 
			
		||||
                            }
 | 
			
		||||
                            else
 | 
			
		||||
                                a->state = 0;
 | 
			
		||||
                        }
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                case 4:     // slew output after blanking period
 | 
			
		||||
                    {
 | 
			
		||||
                        scale = 0.5 - a->hwave[a->time];
 | 
			
		||||
                        a->out[2 * i + 0] = a->Inext * scale + (1.0 - scale) * a->I;
 | 
			
		||||
                        a->out[2 * i + 1] = a->Qnext * scale + (1.0 - scale) * a->Q;
 | 
			
		||||
                        if (++a->time == a->hang_slew_count)
 | 
			
		||||
                            a->state = 0;
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                case 5:
 | 
			
		||||
                    {
 | 
			
		||||
                        scale = 0.5 + a->awave[a->time];
 | 
			
		||||
                        a->out[2 * i + 0] = a->Ilast * scale;
 | 
			
		||||
                        a->out[2 * i + 1] = a->Qlast * scale;
 | 
			
		||||
                        if (++a->time == a->adv_slew_count)
 | 
			
		||||
                        {
 | 
			
		||||
                            a->state = 6;
 | 
			
		||||
                            a->time = 0;
 | 
			
		||||
                            a->blank_count += a->adv_count + a->filterlen;
 | 
			
		||||
                        }
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                case 6:
 | 
			
		||||
                    {
 | 
			
		||||
                        a->out[2 * i + 0] = 0.0;
 | 
			
		||||
                        a->out[2 * i + 1] = 0.0;
 | 
			
		||||
                        if (++a->time == a->blank_count)
 | 
			
		||||
                            a->state = 7;
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                case 7:
 | 
			
		||||
                    {
 | 
			
		||||
                        a->out[2 * i + 0] = 0.0;
 | 
			
		||||
                        a->out[2 * i + 1] = 0.0;
 | 
			
		||||
                        staydown = 0;
 | 
			
		||||
                        a->time = 0;
 | 
			
		||||
                        if ((tidx = a->scan_idx + a->hang_slew_count + a->hang_count) >= a->dline_size) tidx -= a->dline_size;
 | 
			
		||||
                        while (a->time++ <= a->adv_count + a->adv_slew_count + a->hang_slew_count + a->hang_count)                                                                            //  CHECK EXACT COUNTS!!!!!!!!!!!!!!!!!!!!!!!
 | 
			
		||||
                        {
 | 
			
		||||
                            if (a->imp[tidx] == 1) staydown = 1;
 | 
			
		||||
                            if (--tidx < 0) tidx += a->dline_size;
 | 
			
		||||
                        }
 | 
			
		||||
                        if (staydown == 0)
 | 
			
		||||
                        {
 | 
			
		||||
                            if (a->hang_count > 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                a->state = 8;
 | 
			
		||||
                                a->time = 0;
 | 
			
		||||
                            }
 | 
			
		||||
                            else if (a->hang_slew_count > 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                a->state = 9;
 | 
			
		||||
                                a->time = 0;
 | 
			
		||||
                                if ((tidx = a->scan_idx + a->hang_slew_count + a->hang_count - a->adv_count - a->adv_slew_count) >= a->dline_size) tidx -= a->dline_size;
 | 
			
		||||
                                if (tidx < 0) tidx += a->dline_size;
 | 
			
		||||
                                a->Inext = a->dline[2 * tidx + 0];
 | 
			
		||||
                                a->Qnext = a->dline[2 * tidx + 1];
 | 
			
		||||
                            }
 | 
			
		||||
                            else
 | 
			
		||||
                            {
 | 
			
		||||
                                a->state = 0;
 | 
			
		||||
                                a->overflow = 0;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                case 8:
 | 
			
		||||
                    {
 | 
			
		||||
                        a->out[2 * i + 0] = 0.0;
 | 
			
		||||
                        a->out[2 * i + 1] = 0.0;
 | 
			
		||||
                        if (++a->time == a->hang_count)
 | 
			
		||||
                        {
 | 
			
		||||
                            if (a->hang_slew_count > 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                a->state = 9;
 | 
			
		||||
                                a->time = 0;
 | 
			
		||||
                                if ((tidx = a->scan_idx + a->hang_slew_count - a->adv_count - a->adv_slew_count) >= a->dline_size) tidx -= a->dline_size;
 | 
			
		||||
                                if (tidx < 0) tidx += a->dline_size;
 | 
			
		||||
                                a->Inext = a->dline[2 * tidx + 0];
 | 
			
		||||
                                a->Qnext = a->dline[2 * tidx + 1];
 | 
			
		||||
                            }
 | 
			
		||||
                            else
 | 
			
		||||
                            {
 | 
			
		||||
                                a->state = 0;
 | 
			
		||||
                                a->overflow = 0;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                case 9:
 | 
			
		||||
                    {
 | 
			
		||||
                        scale = 0.5 - a->hwave[a->time];
 | 
			
		||||
                        a->out[2 * i + 0] = a->Inext * scale;
 | 
			
		||||
                        a->out[2 * i + 1] = a->Qnext * scale;
 | 
			
		||||
 | 
			
		||||
                        if (++a->time >= a->hang_slew_count)
 | 
			
		||||
                        {
 | 
			
		||||
                            a->state = 0;
 | 
			
		||||
                            a->overflow = 0;
 | 
			
		||||
                        }
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
            }
 | 
			
		||||
            if (++a->in_idx == a->dline_size) a->in_idx = 0;
 | 
			
		||||
            if (++a->scan_idx == a->dline_size) a->scan_idx = 0;
 | 
			
		||||
            if (++a->out_idx == a->dline_size) a->out_idx = 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else if (a->in != a->out)
 | 
			
		||||
        memcpy (a->out, a->in, a->buffsize * sizeof (wcomplex));
 | 
			
		||||
    a->cs_update.unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NOB::setBuffers_nob (NOB *a, float* in, float* out)
 | 
			
		||||
{
 | 
			
		||||
    a->in = in;
 | 
			
		||||
    a->out = out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NOB::setSamplerate_nob (NOB *a, int rate)
 | 
			
		||||
{
 | 
			
		||||
    a->samplerate = rate;
 | 
			
		||||
    init_nob (a);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NOB::setSize_nob (NOB *a, int size)
 | 
			
		||||
{
 | 
			
		||||
    a->buffsize = size;
 | 
			
		||||
    flush_nob (a);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/********************************************************************************************************
 | 
			
		||||
*                                                                                                       *
 | 
			
		||||
*                                             RXA PROPERTIES                                            *
 | 
			
		||||
*                                                                                                       *
 | 
			
		||||
********************************************************************************************************/
 | 
			
		||||
 | 
			
		||||
void NOB::SetRXANOBRun (RXA& rxa, int run)
 | 
			
		||||
{
 | 
			
		||||
    NOB *a = rxa.nob.p;
 | 
			
		||||
    a->cs_update.lock();
 | 
			
		||||
    a->run = run;
 | 
			
		||||
    a->cs_update.unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NOB::SetRXANOBMode (RXA& rxa, int mode)
 | 
			
		||||
{
 | 
			
		||||
    NOB *a = rxa.nob.p;
 | 
			
		||||
    a->cs_update.lock();
 | 
			
		||||
    a->mode = mode;
 | 
			
		||||
    a->cs_update.unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NOB::SetRXANOBBuffsize (RXA& rxa, int size)
 | 
			
		||||
{
 | 
			
		||||
    NOB *a = rxa.nob.p;
 | 
			
		||||
    a->cs_update.lock();
 | 
			
		||||
    a->buffsize = size;
 | 
			
		||||
    a->cs_update.unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NOB::SetRXANOBSamplerate (RXA& rxa, int rate)
 | 
			
		||||
{
 | 
			
		||||
    NOB *a = rxa.nob.p;
 | 
			
		||||
    a->cs_update.lock();
 | 
			
		||||
    a->samplerate = (double) rate;
 | 
			
		||||
    init_nob (a);
 | 
			
		||||
    a->cs_update.unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NOB::SetRXANOBTau (RXA& rxa, double tau)
 | 
			
		||||
{
 | 
			
		||||
    NOB *a = rxa.nob.p;
 | 
			
		||||
    a->cs_update.lock();
 | 
			
		||||
    a->advslewtime = tau;
 | 
			
		||||
    a->hangslewtime = tau;
 | 
			
		||||
    init_nob (a);
 | 
			
		||||
    a->cs_update.unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NOB::SetRXANOBHangtime (RXA& rxa, double time)
 | 
			
		||||
{
 | 
			
		||||
    NOB *a = rxa.nob.p;
 | 
			
		||||
    a->cs_update.lock();
 | 
			
		||||
    a->hangtime = time;
 | 
			
		||||
    init_nob (a);
 | 
			
		||||
    a->cs_update.unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NOB::SetRXANOBAdvtime (RXA& rxa, double time)
 | 
			
		||||
{
 | 
			
		||||
    NOB *a = rxa.nob.p;
 | 
			
		||||
    a->cs_update.lock();
 | 
			
		||||
    a->advtime = time;
 | 
			
		||||
    init_nob (a);
 | 
			
		||||
    a->cs_update.unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NOB::SetRXANOBBacktau (RXA& rxa, double tau)
 | 
			
		||||
{
 | 
			
		||||
    NOB *a = rxa.nob.p;
 | 
			
		||||
    a->cs_update.lock();
 | 
			
		||||
    a->backtau = tau;
 | 
			
		||||
    init_nob (a);
 | 
			
		||||
    a->cs_update.unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NOB::SetRXANOBThreshold (RXA& rxa, double thresh)
 | 
			
		||||
{
 | 
			
		||||
    NOB *a = rxa.nob.p;
 | 
			
		||||
    a->cs_update.lock();
 | 
			
		||||
    a->threshold = thresh;
 | 
			
		||||
    a->cs_update.unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,129 @@
 | 
			
		|||
/*  nobII.h
 | 
			
		||||
 | 
			
		||||
This file is part of a program that implements a Software-Defined Radio.
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2014 Warren Pratt, NR0V
 | 
			
		||||
Copyright (C) 2024 Edouard Griffiths, F4EXB Adapted to SDRangel
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or
 | 
			
		||||
modify it under the terms of the GNU General Public License
 | 
			
		||||
as published by the Free Software Foundation; either version 2
 | 
			
		||||
of the License, or (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program; if not, write to the Free Software
 | 
			
		||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 | 
			
		||||
 | 
			
		||||
The author can be reached by email at
 | 
			
		||||
 | 
			
		||||
warren@wpratt.com
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef wdsp_nob_h
 | 
			
		||||
#define wdsp_nob_h
 | 
			
		||||
 | 
			
		||||
#include <QRecursiveMutex>
 | 
			
		||||
 | 
			
		||||
namespace WDSP {
 | 
			
		||||
 | 
			
		||||
class RXA;
 | 
			
		||||
 | 
			
		||||
class NOB
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    int run;
 | 
			
		||||
    int buffsize;                   // size of input/output buffer
 | 
			
		||||
    float* in;                     // input buffer
 | 
			
		||||
    float* out;                    // output buffer
 | 
			
		||||
    int mode;
 | 
			
		||||
    int dline_size;                 // length of delay line which is 'double dline[length][2]'
 | 
			
		||||
    double *dline;                  // pointer to delay line
 | 
			
		||||
    int *imp;
 | 
			
		||||
    double samplerate;              // samplerate, used to convert times into sample counts
 | 
			
		||||
    double advslewtime;                     // transition time, signal<->zero
 | 
			
		||||
    double advtime;                 // deadtime (zero output) in advance of detected noise
 | 
			
		||||
    double hangslewtime;
 | 
			
		||||
    double hangtime;                // time to stay at zero after noise is no longer detected
 | 
			
		||||
    double max_imp_seq_time;
 | 
			
		||||
    int filterlen;
 | 
			
		||||
    double *fcoefs;
 | 
			
		||||
    double *bfbuff;
 | 
			
		||||
    int bfb_in_idx;
 | 
			
		||||
    double *ffbuff;
 | 
			
		||||
    int ffb_in_idx;
 | 
			
		||||
    double backtau;                 // time constant used in averaging the magnitude of the input signal
 | 
			
		||||
    double threshold;               // triggers if (noise > threshold * average_signal_magnitude)
 | 
			
		||||
    double *awave;                   // pointer to array holding transition waveform
 | 
			
		||||
    double *hwave;
 | 
			
		||||
    int state;                      // state of the state machine
 | 
			
		||||
    double avg;                     // average value of the signal magnitude
 | 
			
		||||
    int time;                       // count when decreasing the signal magnitude
 | 
			
		||||
    int adv_slew_count;
 | 
			
		||||
    int adv_count;                  // number of samples to equal 'tau' time
 | 
			
		||||
    int hang_count;                 // number of samples to equal 'hangtime' time
 | 
			
		||||
    int hang_slew_count;            // number of samples to equal 'advtime' time
 | 
			
		||||
    int max_imp_seq;
 | 
			
		||||
    int blank_count;
 | 
			
		||||
    int in_idx;                     // ring buffer position into which new samples are inserted
 | 
			
		||||
    int scan_idx;
 | 
			
		||||
    int out_idx;                    // ring buffer position from which delayed samples are pulled
 | 
			
		||||
    double backmult;                // multiplier for waveform averaging
 | 
			
		||||
    double ombackmult;              // multiplier for waveform averaging
 | 
			
		||||
    double I1, Q1;
 | 
			
		||||
    double I2, Q2;
 | 
			
		||||
    double I, Q;
 | 
			
		||||
    double Ilast, Qlast;
 | 
			
		||||
    double deltaI, deltaQ;
 | 
			
		||||
    double Inext, Qnext;
 | 
			
		||||
    int overflow;
 | 
			
		||||
    QRecursiveMutex cs_update;
 | 
			
		||||
    double *legacy;
 | 
			
		||||
 | 
			
		||||
                                                                                           ////////////  legacy interface - remove
 | 
			
		||||
    static NOB* create_nob   (
 | 
			
		||||
        int run,
 | 
			
		||||
        int buffsize,
 | 
			
		||||
        float* in,
 | 
			
		||||
        float* out,
 | 
			
		||||
        double samplerate,
 | 
			
		||||
        int mode,
 | 
			
		||||
        double advslewtime,
 | 
			
		||||
        double advtime,
 | 
			
		||||
        double hangslewtime,
 | 
			
		||||
        double hangtime,
 | 
			
		||||
        double max_imp_seq_time,
 | 
			
		||||
        double backtau,
 | 
			
		||||
        double threshold
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    static void destroy_nob (NOB* a);
 | 
			
		||||
    static void flush_nob (NOB* a);
 | 
			
		||||
    static void xnob (NOB* a);
 | 
			
		||||
    static void setBuffers_nob (NOB *a, float* in, float* out);
 | 
			
		||||
    static void setSamplerate_nob (NOB *a, int rate);
 | 
			
		||||
    static void setSize_nob (NOB *a, int size);
 | 
			
		||||
    // RXA
 | 
			
		||||
    static void SetRXANOBRun (RXA& rxa, int run);
 | 
			
		||||
    static void SetRXANOBMode (RXA& rxa, int mode);
 | 
			
		||||
    static void SetRXANOBBuffsize (RXA& rxa, int size);
 | 
			
		||||
    static void SetRXANOBSamplerate (RXA& rxa, int size);
 | 
			
		||||
    static void SetRXANOBTau (RXA& rxa, double tau);
 | 
			
		||||
    static void SetRXANOBHangtime (RXA& rxa, double time);
 | 
			
		||||
    static void SetRXANOBAdvtime (RXA& rxa, double time);
 | 
			
		||||
    static void SetRXANOBBacktau (RXA& rxa, double tau);
 | 
			
		||||
    static void SetRXANOBThreshold (RXA& rxa, double thresh);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    static void init_nob (NOB *a);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
} // namespace
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
		Ładowanie…
	
		Reference in New Issue