Show nl.h syntax highlighted
/*
*
* Copyright (c) 2005 The Regents of the University of California. All
* rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of the University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <sys/types.h>
#include <math.h>
#ifndef __NL_H__
#define __NL_H__
typedef struct complex_s {
float real;
float imag;
} complex;
#define fswap(x,y) do { float t=x; x=y; y=t; } while (0)
static inline complex Cmul(complex a, complex b)
{
complex x;
x.real = a.real*b.real - a.imag*b.imag;
x.imag = a.real*b.imag + a.imag*b.real;
return x;
}
static inline complex Cadd(complex a, complex b)
{
complex x;
x.real = a.real + b.real;
x.imag = a.imag + b.imag;
return x;
}
static inline complex Csmul(float s, complex a)
{
complex x;
x.real = s*a.real;
x.imag = s*a.imag;
return x;
}
/* Compute exponential of an imaginary number */
static inline complex Cexp(float x)
{
complex y;
y.real = cosf(x);
y.imag = sinf(x);
return y;
}
/* Takes the complex norm of scalar */
static inline float Cnorm(complex z)
{
/* overflow protection */
float re;
if (z.real == 0) return z.imag;
if (z.imag == 0) return z.real;
if (fabs(z.real) >= fabs(z.imag)) {
re = fabsf(z.real)*sqrtf(1.0+(z.imag*z.imag)/(z.real*z.real));
} else {
re = fabsf(z.imag)*sqrtf(1.0+(z.real*z.real)/(z.imag*z.imag));
}
return re;
}
static inline complex Cdiv(complex a, complex b)
{
complex x;
float u, v, denom;
denom = b.real*b.real + b.imag*b.imag;
u = b.real / denom;
v = -b.imag / denom;
x.real = a.real*u - a.imag*v;
x.imag = a.real*v + a.imag*u;
return x;
}
static inline complex Csub(complex a, complex b)
{
complex x;
x.real = a.real - b.real;
x.imag = a.imag - b.imag;
return x;
}
/*
* Function prototypes
*/
void nl_2fft(float *real1, float *real2, complex *fft1, complex *fft2, size_t n);
void nl_fft(float *real, complex *fft, size_t real_n);
void nl_ifft(complex *fft, float *real, size_t real_n);
/* WARNING: requires that real be 2x as large as real_n;
* returns casted pointer to real. */
complex *nl_fft_inplace(float *real, size_t real_n);
void nl_phase_shift(complex *fft, size_t points, float delta_t);
void nl_convolve(complex *fft1, complex *fft2, size_t points);
void nl_ifft_subsample(float *dst, complex *src, size_t orig_points, size_t expand_factor);
float nl_ifft_subsample_partial(float *dst, complex *src, size_t orig_points,
size_t expand_factor, size_t dst_start, size_t dst_count);
void nl_copy_vector(complex *dst, complex *src, size_t points);
void nl_accum(complex *dst, complex *src, size_t points);
float nl_sum_magnitudes(complex *fft, size_t points);
void nl_sqr(float *dst, size_t points);
void nl_mult_scalar(complex *dst, float scalar, size_t points);
float nl_sum_power(complex *fft, size_t points);
void nl_reverse_cvector(complex *fft, size_t points);
void nl_reverse_fvector(float *fft, size_t points);
void nl_fd_correl(complex *corr, float *corr_td, complex *a, complex *b, size_t points);
void nl_td_corr(float *corr, float *a, float *b, size_t points);
void nl_td_limited_corr(float *corr, float *a, float *b, size_t points, size_t limit);
float nl_mac(float *a, float *b, size_t points, int offset);
void nl_mult_into(float *a, float *b, size_t points);
void nl_mean_stddev(float *vector, int len, float *mean, float *variance, float *stddev);
float *nl_hanning(int points);
/*
* Allocation prototypes. They zero out the vector and matrices for you
*/
float* new_fvector(unsigned int size);
float** new_fmatrix(unsigned int rows, unsigned int cols);
void free_fvector(float *v);
void free_fmatrix(float **m, unsigned int rows, unsigned int cols);
void zero_fvector(float *v, unsigned int size);
void zero_fmatrix(float **m, unsigned int rows, unsigned int cols);
void print_fvector(float *v, unsigned int size);
void print_fmatrix(float **m, unsigned int rows, unsigned int cols);
float **copy_fmatrix(float **input, unsigned int rows, unsigned int cols);
void add_fmatrix(float **res, float **a, float **b, unsigned int rows, unsigned int cols);
void add_fvector(float *res, float *a, float*b, unsigned int size);
void multiply_fmatrix_fvector(float *res, float **m, float *v,
unsigned int rows, unsigned int cols);
void multiply_fmatrix_scalar(float **res, float **m, float s,
unsigned int rows, unsigned int cols);
/*
* Wrapper for inverting matrix using nr
*/
float **inv_3x3_fmatrix(float **input);
//float** invert_fmatrix(float **input, unsigned int size);
#endif
See more files for this project here