UHSDR/UHSDR-active-devel/mchf-eclipse/drivers/audio/audio_driver.h
2022-08-24 08:41:00 +02:00

683 lines
27 KiB
C

/* -*- mode: c; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4; coding: utf-8 -*- */
/************************************************************************************
** **
** mcHF QRP Transceiver **
** K Atanassov - M0NKA 2014 **
** **
**---------------------------------------------------------------------------------**
** **
** File name: **
** Description: **
** Last Modified: **
** Licence: GNU GPLv3 **
************************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __AUDIO_DRIVER_H
#define __AUDIO_DRIVER_H
#include "uhsdr_board_config.h"
#include "uhsdr_types.h"
#include "arm_math.h"
#include "softdds.h"
#include "audio_filter.h"
#define IQ_SAMPLE_RATE_F ((float32_t)IQ_SAMPLE_RATE)
#define AUDIO_SAMPLE_RATE_F ((float32_t)AUDIO_SAMPLE_RATE)
#if defined(USE_32_IQ_BITS)
typedef int32_t iq_data_t;
#else
typedef int16_t iq_data_t;
#endif
#if defined(USE_32_AUDIO_BITS)
typedef int32_t audio_data_t;
#else
typedef int16_t audio_data_t;
#endif
typedef struct {
__packed audio_data_t l;
__packed audio_data_t r;
} AudioSample_t;
typedef struct {
__packed iq_data_t l;
__packed iq_data_t r;
} IqSample_t;
#ifdef USE_CONVOLUTION
typedef struct {
COMP samples[SAMPLE_BUFFER_SIZE];
} Sample_Buffer;
#endif
// -----------------------------
// FFT buffer, this is double the size of the length of the FFT used for spectrum display and waterfall spectrum
#ifdef USE_FFT_1024
#define FFT_IQ_BUFF_LEN 1024
#else
#define FFT_IQ_BUFF_LEN 512
#endif
#define SPEC_BUFF_LEN (FFT_IQ_BUFF_LEN/2)
// twice the number of samples in the each iq block buffer
// (which is half of the total dma buffer, since in each interrupt we get half of the total dma buffer)
#define IQ_BUFSZ (2*IQ_BLOCK_SIZE)
#define AUDIO_BUFSZ (2*AUDIO_BLOCK_SIZE)
// Audio filter
#define FIR_RXAUDIO_BLOCK_SIZE IQ_BLOCK_SIZE
#define FIR_RXAUDIO_NUM_TAPS 16 // maximum number of taps in the decimation and interpolation FIR filters
#define IIR_RXAUDIO_BLOCK_SIZE IQ_BLOCK_SIZE
#define IIR_RXAUDIO_NUM_STAGES_MAX 12 // we use a maximum stage number of 10 at the moment, so this is 12 just to be safe
//
#define CODEC_DEFAULT_GAIN 0x1F // Gain of line input to start with
#define ADC_CLIP_WARN_THRESHOLD 4096 // This is at least 12dB below the clipping threshold of the A/D converter itself
//
//
//
#define SCALING_FACTOR_IQ_PHASE_ADJUST 2000.0
#define SCALING_FACTOR_IQ_AMPLITUDE_ADJUST 2731.0
#define SAM_PLL_HILBERT_STAGES 7
#ifdef USE_TWO_CHANNEL_AUDIO
#define NUM_AUDIO_CHANNELS 2
#else
#define NUM_AUDIO_CHANNELS 1
#endif
typedef struct
{
// for SAM demodulation
// DX adjustments: zeta = 0.15, omegaN = 100.0
// very stable, but does not lock very fast
// standard settings: zeta = 1.0, omegaN = 250.0
// maybe user can choose between slow (DX), medium, fast SAM PLL
// zeta / omegaN
// DX = 0.2, 70
// medium 0.6, 200
// fast 1.2, 500
//pll
float32_t omega_min; // (2.0 * 3.141592653589793f * pll_fmin * DF / IQ_SAMPLE_RATE_F);
float32_t omega_max; //(2.0 * 3.141592653589793f * pll_fmax * DF / IQ_SAMPLE_RATE_F);
float32_t g1; //(1.0 - exp(-2.0 * omegaN * zeta * DF / IQ_SAMPLE_RATE_F));
float32_t g2; //(- g1 + 2.0 * (1 - exp(- omegaN * zeta * DF / IQ_SAMPLE_RATE_F)
// * cosf(omegaN * DF / IQ_SAMPLE_RATE_F * sqrtf(1.0 - zeta * zeta))));
//fade leveler
float32_t mtauR; //(exp(- DF / (IQ_SAMPLE_RATE_F * tauR))); //0.99948;
float32_t onem_mtauR;
float32_t mtauI; //(exp(- DF / (IQ_SAMPLE_RATE_F * tauI))); //0.99999255955;
float32_t onem_mtauI;
} demod_sam_param_t;
typedef struct
{
float32_t teta1;
float32_t teta2;
float32_t teta3;
float32_t teta1_old;
float32_t teta2_old;
float32_t teta3_old;
float32_t M_c1;
float32_t M_c2;
} iq_correction_data_t;
typedef float32_t audio_block_t[AUDIO_BLOCK_SIZE];
typedef float32_t iq_block_t[IQ_BLOCK_SIZE];
typedef struct
{
iq_block_t i_buffer;
iq_block_t q_buffer;
} iq_buffer_t;
typedef struct
{
// Stereo buffers
iq_buffer_t iq_buf;
float32_t agc_valbuf[IQ_BLOCK_SIZE]; // holder for "running" AGC value
audio_block_t a_buffer[2];
demod_sam_param_t sam;
iq_correction_data_t iq_corr;
} AudioDriverBuffer;
typedef struct
{
float sql_avg; // averaged squelch level (for FM)
bool squelched; // TRUE if FM receiver audio is to be squelched
float subaudible_tone_gen_freq; // frequency, in Hz, of currently-selected subaudible tone for generation
soft_dds_t subaudible_tone_dds;
soft_dds_t tone_burst_dds;
bool tone_burst_active; // this is TRUE if the tone burst is actively being generated
//
float subaudible_tone_det_freq; // frequency, in Hz, of currently-selected subaudible tone for detection
bool subaudible_tone_detected; // TRUE if subaudible tone has been detected
Goertzel goertzel[3];
#define FM_HIGH 0
#define FM_LOW 1
#define FM_CTR 2
} fm_conf_t;
typedef enum
{
SAM_SIDEBAND_BOTH = 0,
SAM_SIDEBAND_LSB,
SAM_SIDEBAND_USB,
#ifdef USE_TWO_CHANNEL_AUDIO
SAM_SIDEBAND_STEREO,
#endif
SAM_SIDEBAND_MAX
} sam_sideband_t;
typedef struct
{
#define DSP_NR_ENABLE 0x01 // DSP NR mode is on (| 1)
#define DSP_NR_POSTAGC_ENABLE 0x02 // DSP NR is to occur post AGC (| 2)
#define DSP_NOTCH_ENABLE 0x04 // DSP Notch mode is on (| 4)
#define DSP_NB_ENABLE 0x08 // DSP is to be displayed on screen instead of NB (| 8)
#define DSP_MNOTCH_ENABLE 0x10 // Manual Notch enabled
#define DSP_MPEAK_ENABLE 0x20 // Manual Peak enabled
#define DSP_ANR_ENABLE 0x40 // DSP ANR (Leak LMS) mode is on
uint8_t active; // Used to hold various aspects of DSP mode selection
uint8_t mode; // holds the mode chosen in the DSP
uint16_t mode_mask; // holds the DSP mode mask (to be chosen by virtual dsp keyboard)
uint8_t active_toggle; // holder used on the press-hold of button G2 to "remember" the previous setting
uint8_t nr_strength; // "Strength" of DSP Noise reduction - to be converted to "Mu" factor
#if defined (USE_LMS_AUTONOTCH)
uint8_t notch_numtaps;
uint8_t notch_mu;
// mu adjust of notch DSP LMS
uint8_t notch_delaybuf_len; // size of DSP notch delay buffer
#endif
uint8_t inhibit; // if != 0, DSP (NR, Notch) functions are inhibited. Used during power-up and switching
uint8_t nb_setting;
ulong notch_frequency; // frequency of the manual notch filter
ulong peak_frequency; // frequency of the manual peak filter
int bass_gain; // gain of the low shelf EQ filter
int treble_gain; // gain of the high shelf EQ filter
// int tx_bass_gain; // gain of the TX low shelf EQ filter
// int tx_treble_gain; // gain of the TX high shelf EQ filter
int tx_eq_gain[5]; // gain of the TX 5-bands EQ filter
} dsp_params_t;
// Audio driver publics
typedef struct AudioDriverState
{
//
// Lock audio filter flag
//
volatile bool af_disabled; // if TRUE, audio filtering is disabled (used during filter bandwidth changing, etc.)
volatile bool tx_filter_adjusting; // used to disable TX I/Q filter during phase adjustment
float codec_gain_calc; // spectrum gain value
bool adc_clip; // used to display warning in s meter
bool adc_half_clip; // used to control input gain and spectrum gain
bool adc_quarter_clip; // used to control input gain and spectrum gain
float peak_audio; // used for audio metering to detect the peak audio level
float alc_val; // "live" transmitter ALC value
float alc_decay; // decay rate (speed) of ALC
uchar decimation_rate; // current decimation/interpolation rate
uint32_t decimated_freq; // resulting decimated sample frequency (used in iq and audio processing)
fm_conf_t fm_conf; // configuration parameters for the fm demodulator
soft_dds_t beep; // this is the actively-used DDS tone word for the radio's beep generator
float beep_loudness_factor; // this is used to set the beep loudness
/* SAM */
// sam related output variables
int carrier_freq_offset;
// sam related configuration parameters, stored in config memory
int pll_fmax_int;
int zeta_int; // zeta * 100
int omegaN_int;
uint8_t fade_leveler; // boolean
// sam related operation parameters, not stored in config memory
sam_sideband_t sam_sideband; // 0 = both, 1 = LSB, 2 = USB
/* IQ Balance */
float32_t iq_phase_balance_rx;
float32_t iq_phase_balance_tx[IQ_TRANS_NUM];
ulong snap_carrier_freq; // used for passing the estimated carrier freq in SNAP mode to the print routine in UI_Driver
bool CW_signal; // if CW decoder is enabled and carrier snap is wanted, this indicates whenever a pulse is received
// only in that case, the carrier frequency is estimated and the display refreshed
} AudioDriverState;
void AudioManagement_CalcIQPhaseAdjust(uint32_t freq);
// S meter public
typedef struct SMeter
{
// configurable ALPHA = 1 - e^(-T/Tau)
// we use alpha config value scaling of 100, i.e. 100 => alpha = 1.00
// this construct permits us to use a single configuration store for both
// it looks rather complex but this is necessary to ensure type safety checks are working
union {
uint16_t alphaCombined;
struct
{
uint8_t DecayAlpha;
uint8_t AttackAlpha;
} alphaSplit;
} config;
// first/upper 8 bits is AttackAlpha
// second/lower 8 bits is DecayAlpha
#define SMETER_ALPHA_ATTACK_DEFAULT 50
#define SMETER_ALPHA_DECAY_DEFAULT 5
#define SMETER_ALPHA_MIN 1 // used for both alphas
#define SMETER_ALPHA_MAX 100 // used for both alphas
// averaged values, used for display
float32_t dbm;
float32_t dbmhz;
// current measurements, used for averaging
float32_t dbm_cur;
float32_t dbmhz_cur;
// internal variables for dbm low pass calculation
float32_t AttackAvedbm;
float32_t DecayAvedbm;
float32_t AttackAvedbmhz;
float32_t DecayAvedbmhz;
uint32_t s_count; // number of S steps, used for display and CAT level
} SMeter;
#define MAX_BASS 20
#define MIN_BASS -20
#define MAX_TREBLE 20
#define MIN_TREBLE -20
//#define MAX_TX_BASS 5
//#define MIN_TX_BASS -20
//#define MAX_TX_TREBLE 5
//#define MIN_TX_TREBLE -20
#define MAX_TX_EQ 20
#define MIN_TX_EQ -20
#define MIN_PEAK_NOTCH_FREQ 200
//
// AGC Time constants
// C. Turner, KA7OEI
//
#define AGC_KNEE 1000//4000 // ADC "knee" threshold for AGC action
//
#define AGC_KNEE_REF 1000
#define AGC_VAL_MAX_REF 131072//4096
#define POST_AGC_GAIN_SCALING_REF 1.333
#define AGC_ATTACK 0.033 // Attack time multiplier for AGC
//
#define AGC_FAST_DECAY 0.0002 // Decay rate multiplier for "Fast" AGC
#define AGC_MED_DECAY 0.00006 // Decay rate multiplier for "Medium" AGC
#define AGC_SLOW_DECAY 0.00001 // Decay rate for multiplier "Slow" AGC
//
#define AGC_ATTACK_FM 0.0033 // Attack time for FM (S-meter reading only)
#define AGC_DECAY_FM 0.0333 // Decay time for FM (S-meter reading only)
//
#define AGC_VAL_MIN 0.02 // Minimum AGC gain multiplier (e.g. gain reduction of 34dB)
//#define AGC_VAL_MAX 4096//1024 // Maximum AGC gain multiplier (e.g. gain multiplication of 60dB)
#define AGC_PREFILTER_MAXGAIN 5 // Scaling factor for RF gain adjustment (e.g. factor by which RFG will be multiplied to yield actual RFG multiplier
#define AGC_PREFILTER_MINGAIN 0.5 // Minimum "RFG" gain multiplier (e.g. gain reduction of 6 dB)
//
#define AGC_PREFILTER_HISIG_THRESHOLD 0.1 // Threshold at which adjustment of RFGAIN (pre-filter) gain adjustment will occur
#define AGC_PREFILTER_LOWSIG_THRESHOLD 1.0 // Threshold at which adjustment of RFGAIN (pre-filter) gain adjustment will occur
#define AGC_PREFILTER_ATTACK_RATE 0.0002 // Attack rate for RFG reduction
#define AGC_PREFILTER_DECAY_RATE 0.000002 // Decay rate for RFG gain recovery
//
#define AGC_PREFILTER_MAX_SIGNAL 1 // maximum level of pre-filtered signal
//
#define POST_AGC_GAIN_SCALING 1.333//0.333 // Used to rescale the post-filter audio level to a value suitable for the codec. This sets the line level output
// to approx. 1000mV peak-peak.
//
#define POST_AGC_GAIN_SCALING_DECIMATE_4 3.46 // Used to scale audio from the decimation/interpolation-by-4 process (based square root of decimation factor)
//
#define POST_AGC_GAIN_SCALING_DECIMATE_2 (POST_AGC_GAIN_SCALING_DECIMATE_4 * 0.6) // Scales audio from decimation/interpolation-by-2 process
//
#define AM_SCALING 1.0 // was 2.0 // Amount of gain multiplication to apply to audio and AGC to make recovery equal to that of SSB
#define AM_AUDIO_SCALING 1.4 // was 1.4 // Additional correction factor applied to audio demodulation to make amplitude equal to that of SSB demodulation
//
//#define AGC_GAIN_CAL 155000.0//22440 // multiplier value (linear, not DB) to calibrate the S-Meter reading to the AGC value
//
#define AUTO_RFG_DECREASE_LOCKOUT 1
#define AUTO_RFG_INCREASE_TIMER 5//10
//
//#define AGC_SLOW 0 // Mode setting for slow AGC
//#define AGC_MED 1 // Mode setting for medium AGC
//#define AGC_FAST 2 // Mode setting for fast AGC
//#define AGC_CUSTOM 3 // Mode setting for custom AGC
//#define AGC_OFF 4 // Mode setting for AGC off
//#define AGC_MAX_MODE 4 // Maximum for mode setting for AGC
//#define AGC_DEFAULT AGC_MED // Default!
//
//#define AGC_CUSTOM_MAX 30 // Maximum (slowest) setting for custom AGC
//#define AGC_CUSTOM_DEFAULT 12 // Default custom AGC setting (approx. equal to "medium")
//#define AGC_CUSTOM_FAST_WARNING 2 // Value at or below which setting the custom AGC is likely to degrade audio
//
#define MAX_RF_GAIN_MAX 30 // Maximum setting for "Max RF gain"
#define MAX_RF_GAIN_DEFAULT 10
// Noise blanker constants
#define MAX_NB_SETTING 15
#define NB_WARNING1_SETTING 7 // setting at or above which NB warning1 (yellow) is given
#define NB_WARNING2_SETTING 12 // setting at or above which NB warning2 (orange) is given
#define NB_WARNING3_SETTING 15 // setting at or above which NB warning3 (red) is given
// Values used for "custom" AGC settings
#define LINE_OUT_SCALING_FACTOR 10 // multiplication of audio for fixed LINE out level (nominally 1vpp)
//
#define LINE_IN_GAIN_RESCALE 20 // multiplier for line input gain
#define MIC_GAIN_RESCALE 2 // divisor for microphone gain setting
// ALC (Auto Level Control) for transmitter, constants
#define ALC_VAL_MAX 1 // Maximum ALC Value is 1 (e.g. it can NEVER amplify)
#define ALC_VAL_MIN 0.001 // Minimum ALC Value - it can provide up to 60dB of attenuation
#define ALC_ATTACK 0.1//0.033 // Attack time for the ALC's gain control
#define ALC_KNEE 30000 // The audio value threshold for the ALC operation
// Decay (release time) for ALC/Audio compressor
#define ALC_DECAY_MAX 20 // Maximum (slowest) setting for ALC decay
#define ALC_DECAY_DEFAULT 10 // Default custom ALC setting (approx. equal to AGC "medium")
// Audio post-filter (pre-alc) gain adjust. This effectively sets the min/max compression level.
#define ALC_POSTFILT_GAIN_MIN 1
#define ALC_POSTFILT_GAIN_MAX 25
#define ALC_POSTFILT_GAIN_DEFAULT 1
//
#define SSB_ALC_GAIN_CORRECTION 1.00 // This scales the output of the ALC for 100% modulation for SSB transmission
//
#define SSB_GAIN_COMP 1.133 // This compensates for slight differences in gain processing in the SSB algorithm (empirically derived)
//
#define AM_GAIN_COMP 1.133 // This compensates for slight differences in gain processing in the AM algorithm (empirically derived)
//
#define FREEDV_GAIN_COMP (20*SSB_GAIN_COMP)
// The following are calibration constants for AM (transmitter) modulation, carefully adjusted for proper D/A scaling to set
// maximum possible 95-100% AM modulation depth.
//
#define AM_ALC_GAIN_CORRECTION 0.23 // This scales the output of the ALC for 100% modulation with respect to the carrier level
#define AM_CARRIER_LEVEL 5100 // This sets the AM carrier level in DAC units, scaled for proper ALC operation and 100% modulation
//
// DO NOT change the above unless you know *EXACTLY* what you are doing! If you screw with these numbers, you WILL wreck the
// AM modulation!!! (No, I'm not kidding!)
// FM TX/RX
#define NUM_SUBAUDIBLE_TONES 56
#define FM_SUBAUDIBLE_TONE_OFF 0
// FM TX
#define FM_TONE_BURST_MAX 2
extern uint32_t fm_tone_burst_freq[FM_TONE_BURST_MAX+1];
#define FM_TONE_BURST_OFF 0
#define FM_TONE_BURST_DURATION 100 // duration, in 100ths of a second, of the tone burst
// FM RX
#define FM_SQUELCH_MAX 20 // maximum setting for FM squelch
#define FM_SQUELCH_DEFAULT 12 // default setting for FM squelch
#define FM_SUBAUDIBLE_GOERTZEL_WINDOW 400 // this sets the overall number of samples involved in the Goertzel decode windows (this value * "size/2")
#define MIN_BEEP_FREQUENCY 200 // minimum beep frequency in Hz
#define MAX_BEEP_FREQUENCY 3000 // maximum beep frequency in Hz
#define DEFAULT_BEEP_FREQUENCY 1000 // default beep frequency in Hz
#define BEEP_DURATION 2 // duration of beep in 100ths of a second
#define MAX_BEEP_LOUDNESS 21 // maximum setting for beep loudness
#define DEFAULT_BEEP_LOUDNESS 10 // default loudness for the keyboard beep
// Factors used in audio compressor adjustment limits
//
#define TX_AUDIO_COMPRESSION_MIN -1 // -1 = OFF
#define TX_AUDIO_COMPRESSION_MAX 13 // 0 = least compression, 12 = most, 13 = EEPROM values ("CUS" = CUSTOM) - custom selected by user
#define TX_AUDIO_COMPRESSION_SV 13
#define TX_AUDIO_COMPRESSION_DEFAULT 2
//
//
#define RX_DECIMATION_RATE_8KHZ 6 // Decimation/Interpolation rate in receive function for 8 kHz sample rate
#define RX_DECIMATION_RATE_12KHZ 4 // Decimation/Interpolation rate in receive function for 12 kHz sample rate
#define RX_DECIMATION_RATE_24KHZ 2 // Decimation/Interpolation rate in receive function for 24 kHz sample rate
#define RX_DECIMATION_RATE_48KHZ 1 // Deimcation/Interpolation rate in receive function for 48 kHz sample rate (e.g. no decimation!)
#define DSP_NR_STRENGTH_MIN 1
#define DSP_NR_STRENGTH_MAX 200 // Maximum menu setting for DSP "Strength"
#define DSP_NR_STRENGTH_STEP 5
#define DSP_NR_STRENGTH_DEFAULT 160 // Default setting
#ifdef USE_LMS_AUTONOTCH
//
// Automatic Notch Filter
//
#define LMS_NOTCH_DELAYBUF_SIZE_MAX 512
//
#define DSP_NOTCH_NUMTAPS_MAX 64//128
#define DSP_NOTCH_NUMTAPS_MIN 64
#define DSP_NOTCH_NUMTAPS_DEFAULT 64//96
//
#define DSP_NOTCH_BUFLEN_MIN 128//64//48 // minimum length of decorrelation buffer for the notch filter FIR
#define DSP_NOTCH_BUFLEN_MAX 128//192 // maximum decorrelation buffer length for the notch filter FIR
#define DSP_NOTCH_DELAYBUF_DEFAULT 128//104 // default decorrelation buffer length for the notch filter FIR
//
#define DSP_NOTCH_MU_MAX 40//40 // maximum "strength" (convergence) setting for the notch
#define DSP_NOTCH_MU_DEFAULT 10//25 // default convergence setting for the notch
#endif
typedef enum
{
DSP_SWITCH_OFF = 0,
DSP_SWITCH_NR,
DSP_SWITCH_ANR,
DSP_SWITCH_NOTCH,
DSP_SWITCH_NR_AND_NOTCH,
DSP_SWITCH_NOTCH_MANUAL,
DSP_SWITCH_PEAK_FILTER,
DSP_SWITCH_MAX, // bass & treble not used here
DSP_SWITCH_BASS = 98,
DSP_SWITCH_TREBLE = 99,
} dsp_mode_t;
typedef enum
{
ModeVK_SSB = 0,
ModeVK_CW,
ModeVK_AM,
ModeVK_SAM,
ModeVK_FM,
ModeVK_RTTY,
ModeVK_BPSK,
ModeVK_FDV,
ModeVK_SWITCH_MAX,
} ModeVK_t;
#define DSP_SWITCH_MODEMASK_ENABLE_MASK ((1<<DSP_SWITCH_MAX)-1)
#define DSP_SWITCH_MODEMASK_ENABLE_DEFAULT ((1<<DSP_SWITCH_MAX)-1)
#define DSP_SWITCH_MODEMASK_ENABLE_DSPOFF (1<<DSP_SWITCH_OFF)
//
#define AUDIO_DELAY_BUFSIZE (IQ_BUFSZ)*5 // Size of AGC delaying audio buffer - Must be a multiple of IQ_BUFSZ.
// This is divided by the decimation rate so that the time delay is constant.
#define FREQ_IQ_CONV_MODE_OFF 0 // No frequency conversion
#define FREQ_IQ_CONV_P6KHZ 1 // LO is 6KHz above receive frequency in RX mode
#define FREQ_IQ_CONV_M6KHZ 2 // LO is 6KHz below receive frequency in RX mode
#define FREQ_IQ_CONV_P12KHZ 3 // LO is 12KHz above receive frequency in RX mode
#define FREQ_IQ_CONV_M12KHZ 4 // LO is 12KHz below receive frequency in RX mode
#define FREQ_IQ_CONV_SLIDE 5 // LO slide frequency in RX mode
//
#define FREQ_IQ_CONV_MODE_DEFAULT FREQ_IQ_CONV_M12KHZ //FREQ_IQ_CONV_MODE_OFF
#define FREQ_IQ_CONV_MODE_MAX 5
// Public Audio
extern AudioDriverState ads;
extern SMeter sm;
extern AudioDriverBuffer adb;
typedef struct SnapCarrier
{
bool snap;
} SnapCarrier;
extern SnapCarrier sc;
#ifdef USE_LEAKY_LMS
#define LEAKYLMSDLINE_SIZE 256 //512 // was 256 //2048 // dline_size
// 1024 funktioniert nicht
typedef struct
{// Automatic noise reduction
// Variable-leak LMS algorithm
// taken from (c) Warren Pratts wdsp library 2016
// GPLv3 licensed
// #define DLINE_SIZE 256 //512 //2048 // dline_size
int16_t n_taps; // = 64; //64; // taps
int16_t delay; // = 16; //16; // delay
int dline_size; // = LEAKYLMSDLINE_SIZE;
//int ANR_buff_size = FFT_length / 2.0;
int position;// = 0;
float32_t two_mu;// = 0.0001; typical: 0.001 to 0.000001 = 1000 to 1 -> div by 1000000 // two_mu --> "gain"
uint32_t two_mu_int;
float32_t gamma;// = 0.1; typical: 1.000 to 0.001 = 1000 to 1 -> div by 1000 // gamma --> "leakage"
uint32_t gamma_int;
float32_t lidx;// = 120.0; // lidx
float32_t lidx_min;// = 0.0; // lidx_min
float32_t lidx_max;// = 200.0; // lidx_max
float32_t ngamma;// = 0.001; // ngamma
float32_t den_mult;// = 6.25e-10; // den_mult
float32_t lincr;// = 1.0; // lincr
float32_t ldecr;// = 3.0; // ldecr
//int ANR_mask = ANR_dline_size - 1;
int mask;// = DLINE_SIZE - 1;
int in_idx;// = 0;
float32_t d [LEAKYLMSDLINE_SIZE];
float32_t w [LEAKYLMSDLINE_SIZE];
uint8_t on;// = 0;
uint8_t notch;// = 0;
} lLMS;
extern lLMS leakyLMS;
#endif
// TODO: Discuss to drop 16 bit I2S support. Would simplify the incoming/outgoing data handling. We could
// align all scalings accordingly and would not have most of the ugly stuff below
// FIXME: This is ugly: The STM32F4 returns 32bit reads from 16 bit peripherals such as the SPI/I2S
// with the two half words in "mixed endian" instead of the wanted "little endian". This is documented in
// the data sheet, so the only thing we can do is to swap the halfwords. This is in fact a single ror16 operation
// if the compiler is smart enough to detect what we want.
// these constants are used to adjust the 32 bit integer samples to represent the same levels as if we sample 16 bit integers,
// effectively "shifting" them down or up.
// FIXME: switch to 16 bit extended mode for 16 bit samples will eliminate the need for this at the expense of
// using the same DMA memory (two times the memory true 16 bit values take, in our case this is 2*(2*(IQ_BLOCK_SIZE*2samples*2bytes) = 512 bytes)
#ifdef USE_32_IQ_BITS
#define IQ_BIT_SHIFT 16
#define IQ_BIT_SCALE_DOWN (0.0000152587890625)
#else
#define IQ_BIT_SHIFT 0
#define IQ_BIT_SCALE_DOWN (1.0)
#endif
#define IQ_BIT_SCALE_UP (1<<IQ_BIT_SHIFT)
#define IQ_BIT_SCALE_DOWN24 (0.0039)
#ifdef USE_32_AUDIO_BITS
#define AUDIO_BIT_SHIFT 16
#define AUDIO_BIT_SCALE_DOWN (0.0000152587890625)
#else
#define AUDIO_BIT_SHIFT 0
#define AUDIO_BIT_SCALE_DOWN (1.0)
#endif
#define AUDIO_BIT_SCALE_UP (1<<AUDIO_BIT_SHIFT)
// we have to swap them only if we are having 32bit values from/to I2S and an STM32F4
#if defined(STM32F4) && defined(USE_32_IQ_BITS)
static inline int32_t I2S_correctHalfWord(const int32_t word)
{
uint32_t uWord = (uint32_t)word;
return uWord >> 16 | uWord << 16;
}
static inline int16_t I2S_IqSample_2_Int16(const iq_data_t sample) { return (I2S_correctHalfWord(sample)) >> IQ_BIT_SHIFT; }
static inline int16_t I2S_AudioSample_2_Int16(const iq_data_t sample) { return (I2S_correctHalfWord(sample)) >> IQ_BIT_SHIFT; }
static inline iq_data_t I2S_Int16_2_IqSample(const int16_t sample) { return (I2S_correctHalfWord(sample << IQ_BIT_SHIFT)); }
static inline iq_data_t I2S_Int16_2_AudioSample(const int16_t sample) { return (I2S_correctHalfWord(sample << IQ_BIT_SHIFT)); }
#else
#define I2S_correctHalfWord(a) (a)
#if defined(USE_32_IQ_BITS)
static inline int16_t I2S_IqSample_2_Int16(const iq_data_t sample) { return sample >> 16; }
static inline iq_data_t I2S_Int16_2_IqSample(const int16_t sample) { return sample << 16; }
#else
static inline int16_t I2S_IqSample_2_Int16(const iq_data_t sample) { return sample; }
static inline iq_data_t I2S_Int16_2_IqSample(const int16_t sample) { return sample; }
#endif
#if defined(USE_32_AUDIO_BITS)
static inline int16_t I2S_AudioSample_2_Int16(const iq_data_t sample) { return sample >> 16; }
static inline iq_data_t I2S_Int16_2_AudioSample(const int16_t sample) { return sample << 16; }
#else
static inline int16_t I2S_AudioSample_2_Int16(const iq_data_t sample) { return sample; }
static inline iq_data_t I2S_Int16_2_AudioSample(const int16_t sample) { return sample; }
#endif
#endif
// Exports
void AudioDriver_Init(void);
void AudioDriver_SetProcessingChain(uint8_t dmod_mode, bool reset_dsp_nr);
int32_t AudioDriver_GetTranslateFreq(void);
void AudioDriver_SetSamPllParameters (void);
void AudioDriver_I2SCallback(AudioSample_t *audio, IqSample_t *iq, AudioSample_t *audioDst, int16_t size);
void AudioDriver_CalcPeakEQ(float32_t coeffs[5], float32_t f0, float32_t q, float32_t gain, float32_t FS);
void AudioDriver_CalcLowShelf(float32_t coeffs[5], float32_t f0, float32_t S, float32_t gain, float32_t FS);
void AudioDriver_CalcHighShelf(float32_t coeffs[5], float32_t f0, float32_t S, float32_t gain, float32_t FS);
void AudioDriver_CalcBandpass(float32_t coeffs[5], float32_t f0, float32_t FS);
void AudioDriver_SetBiquadCoeffs(float32_t* coeffsTo,const float32_t* coeffsFrom);
void AudioDriver_IQPhaseAdjust(uint16_t txrx_mode, float32_t* i_buffer, float32_t* q_buffer, const uint16_t blockSize);
void AudioDriver_AgcWdsp_Set(void);
#endif