/* * A specialzed vector de-mux for estimating power within defined sub-bands of a vector that * is the output of an FFT+complex-to-MAG * * It takes in a fixed-size float vector, and a list of descriptors describing the sub-bands that are to * be added together to form an output channel. The output is a number of channels (one per descriptor). * * Consider the following example: * * Input vector: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX * ^^^^^^ ^^^^ ^^^^^^^ * CH 0 CH 1 CH 2 (etc) * * For simple multi-channel power estimation this is significantly more efficient than many other techniques * that might be used. Channel-width resolution is based purely on the resolution of the FFT+complex-to-MAG * that feeds this specialized demux. Resolutions of a few hundred Hz with 25MHz input bandwidths appear to * be feasible with this technique. For uniformly-spaced channels with relatively-coarse resolution, a PFB * channel bank might be better. * * This "rides" on the fact that the Gnu Radio FFT implementation is very efficient, due to its use of * FFTW, which provides several overlapping techniques to improve performance including: * * o an optimizer * o aggressive use of SSEx/3DNow! instruction sets * o multi-threaded FFT calculations (useful for very large FFTs, which are required for fine resolution) * * In many situations, the total number of post-FFT ops you need to do is quite modest compared to the FFT, * since you may be ignoring the vast majority of the input vector. In the application domain of interest * (multi-channel power estimation for ionospheric measurements), probably 98% of the input vector isn't * touched. But the channels of interest are: * * o not evenly spaced * o not of uniform bandwidth * o between 1 and perhaps 10 sub-band "collections" (output channels) might be of interest * * invector - input vector of size 'vecsize' * vec_begins - list of sub-channel start points (offsets from beginning of input vector) * vec_ends - list of sub-channel end points (offsets from beginning of input vector) * nchan - number of output channels (or "collections of sub-bands from input") * outchans - the output channels * */ int vector_power_estimator_ff (float invector[], int vecsize, int vec_begins[], int vec_ends[], int nchan, float outchans[]) { int i, j; /* * For each output channel descriptor */ for (i = 0; i < nchan; i++) { /* * Accumulate an output channel from sub-bands in the input */ outchans[i] = 0.0; for (j = vec_begins[i]; j < vec_ends[i]; j++) { if (j < vecsize) { /* * Opportunity for volk-ifying here */ outchans[i] += invector[j]; } } } return nchan; }