hamnet70/impl/src/layer1/correlator.h

149 lines
4.5 KiB
C

#ifndef LAYER1_CORRELATOR_H
#define LAYER1_CORRELATOR_H
/*!
* \file
*
* \brief A cross-correlator.
*
* \details
* This module implements a cross-correlator that correlates a static sequence
* (like a preamble) with a continuous stream of symbols. For example, it can
* be used to detect the start of a packet in a stream of samples.
*/
#include <stdbool.h>
#include <stdlib.h>
#include <complex.h>
/*!
* \brief Context information for the correlator.
*/
typedef struct
{
float complex *search_sequence;
float complex *input_history;
float phase_deviation;
/*!
* \brief The history pointer.
*
* \details
* Always points to the last updated sample in the input_history. On every
* written sample, the pointer is incremented and wrapped using
* buffer_size_mask. Therefore, older samples have lower indices in the
* array.
*/
size_t history_ptr;
size_t search_sequence_len;
size_t buffer_size;
size_t buffer_size_mask;
} correlator_ctx_t;
/*!
* \brief Initialize a correlator.
*
* \details
* Initializes all variables in the given context and imports the search sequence.
*
* The search sequence needs to be given such that index 0 contains the
* „oldest“ correlated sample.
*
* \param ctx The correlator context to initialize.
* \param search_seq The search sequence.
* \param nsymbols Length of the search sequence.
*
* \returns Whether the correlator was initialized successfully.
*/
bool correlator_init(correlator_ctx_t *ctx, const float complex *search_seq, size_t nsymbols);
/*!
* \brief Delete a correlator.
*
* \param ctx The correlator context to free.
*/
void correlator_free(correlator_ctx_t *ctx);
/*!
* \brief Process one sample in the correlator.
*
* The input sample will be stored in the internal history buffer and then the
* following calculation will be executed, where k determines the “age” of the
* sample and n is the size of the search sequence:
*
* result = sum{k = 0..n-1} (input_history[k] * search_sequence[k])
*
* \param ctx The correlator context to use.
* \param sample The input sample to process.
*
* \returns The new correlator output value.
*/
float complex correlator_step(correlator_ctx_t *ctx, float complex sample);
/*!
* \brief Retrieve the history of input values.
*
* \details
* This function gives the last n input values, where n is the size of the
* search sequence.
*
* The values will be ordered such that the oldest value has index 0.
*
* Note that this function is rather expensive as it copies all the data.
* However it might releave the user of keeping track of the input samples in
* case the history is only used occasionally.
*
* \param ctx The correlator context to use.
* \param history Pointer to the output array. Must have space for n values.
*/
void correlator_get_input_history(correlator_ctx_t *ctx, float complex *history);
/*!
* \brief Retrieve the conjugated search sequence.
*
* \details
* Returns a pointer to the internally used search sequence, which corresponds
* to the sequence given to \ref correlator_init(), but all values are
* conjugated.
*
* \param ctx The correlator context to use.
* \returns A pointer to the internal search sequence.
*/
const float complex* correlator_get_conj_search_sequence(correlator_ctx_t *ctx);
/*!
* \brief Calculate mean phase deviation between current input and search sequence.
*
* \details
* Calling this probably only makes sense directly after a correlation peak was
* found.
*
* \param ctx The correlator context to use.
* \returns The mean phase deviation in radians.
*/
float correlator_get_mean_phase_deviation(correlator_ctx_t *ctx);
/*!
* \brief Calculate mean frequency deviation between current input and search sequence.
*
* \details
* Calling this probably only makes sense directly after a correlation peak was
* found.
*
* This uses the Louise & Regiannini frequency estimation algorithm for known
* symbol sequences.
*
* \param ctx The correlator context to use.
* \param L Number of symbols to use (at the end of the sequence)
* \param phase_offset The phase offset of the symbol *following* the preamble.
* May be NULL if not needed.
* \returns The mean frequency deviation in radians/symbol.
*/
float correlator_get_mean_frequency_deviation(correlator_ctx_t *ctx, size_t L, float *phase_offset);
#endif // LAYER1_CORRELATOR_H