fd2ba84e7d
Three separate costs, found with a sampling profile of the RX chain with
emnr forced on:
aepf() averaged mask[] over a window of N = 2*psi + 1 = 41 bins by walking
the window for every one of the 2049 bins, i.e. O(msize*N). Its three spans
are all symmetric windows clipped at the array ends, so take each from a
prefix sum instead: one subtraction per output, O(msize).
xemnr() advanced four ring indices with a '% size' per step. iasize is 4096
and oasize 1024 here, and neither is known to the compiler, so each step was
a real integer division -- ~8700 of them per frame. The indices step by one
and, since iasize >= fsize and oasize >= incr always hold, wrap at most once
per loop, so walk contiguous runs and wrap between them.
calc_gain() called getKey() twice per bin with the same gamma, so the gamma
row index and its log10 were computed twice. Split getKey into keyIndex() +
keyLerp() and locate gamma once. The remaining logs go through wdsp_log10()
(new fastmath.h), accurate to 2e-13 against libm and ~2.4x its throughput;
gamma and xi are bracketed against the table limits first, so the argument
is always positive and normal. Also clamp the row index so the second
bilinear corner cannot address the next row of the 241x241 table.
Measured in situ on an Apple M1 Pro, 512-sample buffers, cost of turning
emnr on, best of 5:
baseline 73661 ns
+ aepf, ring walks 48927 ns 1.51x
+ getKey 37852 ns 1.95x
Output is not bit-identical, as the prefix sum and the reassociated logs
round differently. Over 300 buffers with emnr alone the worst deviation is
4.0e-09, an SNR of 196 dB; perturbing a single input sample of the unmodified
code by one ulp diverges it from itself by 1.4e-08 (186 dB), so this change
disturbs the chain less than the last bit of the input does.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
160 lines
4.4 KiB
C
160 lines
4.4 KiB
C
/* comm.h
|
|
|
|
This file is part of a program that implements a Software-Defined Radio.
|
|
|
|
Copyright (C) 2013, 2024, 2025 Warren Pratt, NR0V
|
|
|
|
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
|
|
|
|
*/
|
|
|
|
#if defined(linux) || defined(__APPLE__)
|
|
#include <stdlib.h>
|
|
#include <pthread.h>
|
|
#include <semaphore.h>
|
|
#include <string.h>
|
|
#include "linux_port.h"
|
|
#endif
|
|
|
|
#ifdef _WIN32
|
|
#include <Windows.h>
|
|
#include <process.h>
|
|
#include <intrin.h>
|
|
#endif
|
|
#include <math.h>
|
|
#include <stdint.h>
|
|
#include <time.h>
|
|
#ifdef _WIN32
|
|
#include <avrt.h>
|
|
#endif
|
|
#include "fftw3.h"
|
|
|
|
#include "amd.h"
|
|
#include "ammod.h"
|
|
#include "amsq.h"
|
|
#include "analyzer.h"
|
|
#include "anf.h"
|
|
#include "anr.h"
|
|
#include "apfshadow.h"
|
|
#include "bandpass.h"
|
|
#include "calcc.h"
|
|
#include "cblock.h"
|
|
#include "cfcomp.h"
|
|
#include "cfir.h"
|
|
#include "channel.h"
|
|
#include "cmath.h"
|
|
#include "compress.h"
|
|
#include "delay.h"
|
|
#include "dexp.h"
|
|
#include "div.h"
|
|
#include "doublepole.h"
|
|
#include "eer.h"
|
|
#include "emnr.h"
|
|
#include "rnnr.h" // NR3 + NR4 support
|
|
#include "sbnr.h" // NR3 + NR4 support
|
|
#include "emph.h"
|
|
#include "eq.h"
|
|
#include "fastmath.h"
|
|
#include "fcurve.h"
|
|
#include "fir.h"
|
|
#include "firmin.h"
|
|
#include "fmd.h"
|
|
#include "fmmod.h"
|
|
#include "fmsq.h"
|
|
#include "gain.h"
|
|
#include "gaussian.h"
|
|
#include "gen.h"
|
|
#include "icfir.h"
|
|
#include "iir.h"
|
|
#include "impulse_cache.h"
|
|
#include "iobuffs.h"
|
|
#include "iqc.h"
|
|
#include "lmath.h"
|
|
#include "main.h"
|
|
#include "matchedCW.h"
|
|
#include "meter.h"
|
|
#include "meterlog10.h"
|
|
#include "nbp.h"
|
|
#include "nob.h"
|
|
#include "nobII.h"
|
|
#include "osctrl.h"
|
|
#include "patchpanel.h"
|
|
#include "resample.h"
|
|
#include "rmatch.h"
|
|
#include "RXA.h"
|
|
#include "sender.h"
|
|
#include "shift.h"
|
|
#include "siphon.h"
|
|
#include "slew.h"
|
|
#include "snb.h"
|
|
#include "ssql.h"
|
|
#include "syncbuffs.h"
|
|
#include "TXA.h"
|
|
#include "utilities.h"
|
|
#include "varsamp.h"
|
|
#include "wcpAGC.h"
|
|
|
|
// manage differences among consoles
|
|
#define _Thetis
|
|
|
|
// channel definitions
|
|
#define MAX_CHANNELS 32 // maximum number of supported channels
|
|
#define DSP_MULT 2 // number of dsp_buffsizes that are held in an iobuff pseudo-ring
|
|
#define INREAL float // data type for channel input buffer
|
|
#define OUTREAL float // data type for channel output buffer
|
|
|
|
// display definitions
|
|
#define dMAX_DISPLAYS 72 // maximum number of displays = max instances
|
|
#define dMAX_STITCH 4 // maximum number of sub-spans to stitch together
|
|
#define dMAX_NUM_FFT 1 // maximum number of ffts for an elimination
|
|
#define dMAX_PIXELS 16384 // maximum number of pixels that can be requested
|
|
#define dMAX_AVERAGE 60 // maximum number of pixel frames that will be window-averaged
|
|
#ifdef _Thetis
|
|
#define dINREAL double
|
|
#else
|
|
#define dINREAL float
|
|
#endif
|
|
#define dOUTREAL float
|
|
#define dSAMP_BUFF_MULT 2 // ratio of input sample buffer size to fft size (for overlap)
|
|
#define dNUM_PIXEL_BUFFS 3 // number of pixel output buffers
|
|
#define dMAX_M 1 // number of variables to calibrate
|
|
#define dMAX_N 100 // maximum number of frequencies at which to calibrate
|
|
#define dMAX_CAL_SETS 2 // maximum number of calibration data sets
|
|
#define dMAX_PIXOUTS 4 // maximum number of det/avg/outputs per display instance
|
|
|
|
// wisdom definitions
|
|
#define MAX_WISDOM_SIZE_DISPLAY 262144
|
|
#define MAX_WISDOM_SIZE_FILTER 262144 // was 32769
|
|
|
|
// math definitions
|
|
#define PI 3.1415926535897932
|
|
#define TWOPI 6.2831853071795864
|
|
|
|
// Non-aliasing qualifier for DSP buffers. Spelled __restrict rather than
|
|
// restrict because the JNI translation unit is compiled as -std=gnu89.
|
|
#if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER)
|
|
#define WDSP_RESTRICT __restrict
|
|
#else
|
|
#define WDSP_RESTRICT
|
|
#endif
|
|
|
|
// miscellaneous
|
|
typedef double complex[2];
|
|
#define PORT __declspec( dllexport )
|