// Copyright 2022-2026 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifndef AEC_DEFINES_H
#define AEC_DEFINES_H

#ifdef __aec_conf_h_exists__
    #include "aec_conf.h"
#endif

/**
 * @defgroup aec_defines   AEC #define constants
 */

/**
 *
 * @brief Maximum number of main-filter phases per adaptive filter at compile time.
 *
 * This sets the compile-time capacity for the main adaptive filter and is
 * used to size internal state and memory pools (see @ref aec_memory_pool_t).
 * It gets overridden by an autogenerated header (\c aec_conf.h) when using AEC
 * custom schedule generation via CMake.
 *
 * The `num_main_filter_phases` passed to `aec_init()` must satisfy @ref aec_phase_pool_capacity.
 *
 * @ingroup aec_defines
 */
#ifndef AEC_MAIN_FILTER_PHASES
#define AEC_MAIN_FILTER_PHASES (10)
#endif

/** @brief Maximum number of shadow-filter phases per adaptive filter at compile time.
 *
 * This sets the compile-time capacity for the shadow adaptive filter and is
 * used to size internal state and memory pools (see @ref aec_shadow_filt_memory_pool_t).
 * It gets overridden by an autogenerated header (\c aec_conf.h) when using AEC
 * custom schedule generation via CMake.
 *
 * The `num_shadow_filter_phases` passed to `aec_init()` must satisfy @ref aec_phase_pool_capacity.
 *
 * @ingroup aec_defines
 */
#ifndef AEC_SHADOW_FILTER_PHASES
#define AEC_SHADOW_FILTER_PHASES (5)
#endif


/** @brief Maximum number of microphone input channels at compile time.
 * Microphone input to the AEC refers to the input from the device's microphones from which AEC removes the echo
 * created in the room by the device's loudspeakers.
 *
 * AEC functions follow the convention of using @math{y} and @math{Y} for referring to time domain and frequency domain
 * representation of microphone input.
 *
 * The `num_y_channels` passed into `aec_init()` call should be less than or equal to AEC_MAX_Y_CHANNELS,
 * and satisfy the capacity rule in @ref aec_phase_pool_capacity.
 *
 * This macro is used to size compile-time data structures (see @ref aec_state_t, @ref aec_memory_pool_t).
 * It gets overridden by an autogenerated header (\c aec_conf.h) when using AEC
 * custom schedule generation via CMake.
 * The implementation operates on the runtime value configured via \c aec_init().
 *
 * @ingroup aec_defines
 *
 */
#ifndef AEC_MAX_Y_CHANNELS
#define AEC_MAX_Y_CHANNELS (2)
#endif

/** @brief Maximum number of reference (X) input channels at compile time.
 *
 * Reference input is a copy of the device’s loudspeaker output used by the AEC
 * to model echo paths between loudspeakers and microphones.
 *
 * AEC uses the convention @math{x} (time domain) and @math{X} (frequency domain)
 * for reference signals.
 *
 * The `num_x_channels` passed to `aec_init()` must be <= @ref AEC_MAX_X_CHANNELS
 * and satisfy the capacity rule in @ref aec_phase_pool_capacity.
 *
 * This macro is used to size compile-time data structures (see @ref aec_state_t, @ref aec_memory_pool_t).
 * It gets overridden by an autogenerated header (\c aec_conf.h) when using AEC
 * custom schedule generation via CMake.
 * The implementation operates on the runtime value configured via `aec_init()`.
 *
 * @ingroup aec_defines
 */
#ifndef AEC_MAX_X_CHANNELS
#define AEC_MAX_X_CHANNELS (2)
#endif

/** @brief AEC frame size
 * This is the number of samples of new data that the AEC works on every frame. 240 samples at 16kHz is 15msec. Every
 * frame, the echo canceller takes in 15msec of mic and reference data and generates 15msec of echo cancelled output.
 *
 * @ingroup aec_defines
 */
#define AEC_FRAME_ADVANCE (240)

/** Time domain samples block length used internally in AEC's block LMS algorithm
 *
 * @ingroup aec_defines
 */
#define AEC_PROC_FRAME_LENGTH (512)

/** Number of bins of spectrum data computed when doing a DFT of a AEC_PROC_FRAME_LENGTH length time domain vector. The
 * AEC_FD_FRAME_LENGTH spectrum values represent the bins from DC to Nyquist.
 *
 * @ingroup aec_defines
 */
#define AEC_FD_FRAME_LENGTH ((AEC_PROC_FRAME_LENGTH / 2) + 1)

/** @brief Maximum total number of phases supported in the AEC library
 * This is the maximum number of total phases supported in the AEC library. Total phases are calculated by summing
 * phases across adaptive filters for all x-y pairs.
 *
 * For example. for a 2 y-channels, 2 x-channels, 10 phases per x channel configuration, there are 4 adaptive filters,
 * H_hat<SUB>y0x0</SUB>, H_hat<SUB>y0x1</SUB>, H_hat<SUB>y1x0</SUB> and H_hat<SUB>y1x1</SUB>, each filter having 10
 * phases, so the total number of phases is 40.
 * When aec_init() is called to initialise the AEC, the num_y_channels, num_x_channels and num_main_filter_phases
 * parameters passed in should be such that num_y_channels * num_x_channels * num_main_filter_phases is less than equal
 * to AEC_LIB_MAX_PHASES.
 *
 * This define is only used when defining data structures within the AEC state structure. The AEC algorithm
 * implementation uses the num_main_filter_phases and num_shadow_filter_phases values that are passed into aec_init().
 *
 * @ingroup aec_defines
 */
#define AEC_LIB_MAX_PHASES (AEC_MAX_Y_CHANNELS * AEC_MAX_X_CHANNELS * AEC_MAIN_FILTER_PHASES)

/** Overlap data length
 *
 * @ingroup aec_defines
 */
#define AEC_UNUSED_TAPS_PER_PHASE (16)

/** Extra 2 samples you need to allocate in time domain so that the full spectrum (DC to nyquist) can be stored
 * after the in-place FFT. NOT USER MODIFIABLE.
 *
 * @ingroup aec_defines
 */
//
#define AEC_FFT_PADDING (2)

#define AEC_ZEROVAL_EXP (-1024) /// A very small exponent indicating 0 value.
#define AEC_ZEROVAL_HR (31) /// Headroom value used in BFP arrays when indicating 0 value by setting exponent to AEC_ZEROVAL_EXP

/** @brief Maximum number of hardware threads supported by the AEC.
 *
 * This compile-time limit bounds the number of threads that a task distribution
 * schedule can target (see @ref aec_task_distribution_t).
 * Custom schedules generated via CMake (``AEC_SCHEDULE_CONFIG``) must set
 * ``<num_hw_threads>`` <= AEC_LIB_MAX_THREADS.
 *
 * @ingroup aec_defines
 */
#define AEC_LIB_MAX_THREADS (3)

#endif
