/* -*- 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< 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<> 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