diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..779abc6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.o +*.so +*.dll \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0a04128 --- /dev/null +++ b/LICENSE @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3c0cad8 --- /dev/null +++ b/Makefile @@ -0,0 +1,38 @@ + + + + +ifeq ($(OS),Windows_NT) + MAKE = mingw32-make +else + UNAME_S := $(shell uname -s) + ifeq ($(UNAME_S),Linux) + MAKE = make + endif +endif + +include Makefile.dirs + + + + +all: + $(MAKE) -f Makefile.dspl + cp -r include/dspl.h release/include/dspl.h + cp -r include/dspl.c release/include/dspl.c + $(MAKE) -f Makefile.test + cp -r $(RELEASE_DIR)/$(DSPL_LIBNAME) test/bin/$(DSPL_LIBNAME) + + + + +clean: + $(MAKE) -f Makefile.dspl clean + $(MAKE) -f Makefile.test clean + + + + + + + diff --git a/Makefile.dirs b/Makefile.dirs new file mode 100644 index 0000000..e998cf9 --- /dev/null +++ b/Makefile.dirs @@ -0,0 +1,39 @@ +CC = gcc +INC_DIR = include + +ifeq ($(OS),Windows_NT) + DSPL_LIBNAME = libdspl.dll + DEF_OS = WIN_OS + LFLAGS = -lm + ifeq ($(PROCESSOR_ARCHITEW6432),AMD64) + RELEASE_DIR = release/lib/win64 + EXTLIB_DIR = ext/win64 + else + ifeq ($(PROCESSOR_ARCHITECTURE),AMD64) + RELEASE_DIR = release/lib/win64 + EXTLIB_DIR = ext/win64 + endif + ifeq ($(PROCESSOR_ARCHITECTURE),x86) + RELEASE_DIR = release/lib/win32 + EXTLIB_DIR = ext/win32 + endif + endif +else + UNAME_S := $(shell uname -s) + UNAME_P := $(shell uname -p) + ifeq ($(UNAME_S),Linux) + DSPL_LIBNAME = libdspl.so + DEF_OS = LINUX_OS + LFLAGS = -lm -ldl + ifeq ($(UNAME_P),x86_64) + RELEASE_DIR = release/lib/linux64 + EXTLIB_DIR = ext/linux64 + endif + ifneq ($(filter %86,$(UNAME_P)),) + RELEASE_DIR = release/lib/linux32 + EXTLIB_DIR = ext/linux32 + endif + endif +endif + + diff --git a/Makefile.dspl b/Makefile.dspl new file mode 100644 index 0000000..11fae30 --- /dev/null +++ b/Makefile.dspl @@ -0,0 +1,31 @@ +LIB_DIR = dspl + +include Makefile.dirs + + +SRC_DIR = $(LIB_DIR)/src +OBJ_DIR = $(LIB_DIR)/obj + +COMMON_SRC_DIR = $(COMMON_DIR)/src + + +LIB_NAME = $(DSPL_LIBNAME) + +CFLAGS = -c -fPIC -Wall -O3 -I$(INC_DIR) -DBUILD_LIB -D$(DEF_OS) + +SRC_FILES = $(wildcard $(SRC_DIR)/*.c) +OBJ_FILES = $(addprefix $(OBJ_DIR)/,$(notdir $(SRC_FILES:.c=.o))) + + +all: $(RELEASE_DIR)/$(LIB_NAME) + + +$(RELEASE_DIR)/$(LIB_NAME): $(OBJ_FILES) + $(CC) -shared -o $(RELEASE_DIR)/$(LIB_NAME) $(OBJ_FILES) -L$(EXTLIB_DIR) -lfftw3 -lblas -lm + +$(OBJ_DIR)/%.o:$(SRC_DIR)/%.c + $(CC) $(CFLAGS) $< -o $@ -L$(EXTLIB_DIR) -lfftw3 -lblas -llapack -lgfortran -lm + +clean: + rm -f $(OBJ_DIR)/*.o + rm -f $(RELEASE_DIR)/$(LIB_NAME) diff --git a/Makefile.test b/Makefile.test new file mode 100644 index 0000000..334fecb --- /dev/null +++ b/Makefile.test @@ -0,0 +1,29 @@ +PRJ_DIR = test + +SRC_DIR = $(PRJ_DIR)/src +BIN_DIR = $(PRJ_DIR)/bin + +include Makefile.dirs + +DSPL_C_FILE = $(INC_DIR)/dspl.c +DSPL_O_FILE = $(PRJ_DIR)/obj/dspl.o + +SRC_FILES = $(wildcard $(SRC_DIR)/*.c) +BIN_FILES = $(addprefix $(BIN_DIR)/,$(notdir $(SRC_FILES:.c=.exe))) + + +CFLAGS = -Wall -O3 -I$(INC_DIR) -D$(DEF_OS) + +all: $(BIN_FILES) + +$(BIN_DIR)/%.exe: $(SRC_DIR)/%.c $(DSPL_O_FILE) + $(CC) $(CFLAGS) $< $(DSPL_O_FILE) -o $@ $(LFLAGS) + +$(DSPL_O_FILE):$(DSPL_C_FILE) + $(CC) -c $(CFLAGS) $(DSPL_C_FILE) -o $(DSPL_O_FILE) $(LFLAGS) + +clean: + rm -f $(BIN_DIR)/*.exe + rm -f $(BIN_DIR)/$(DSPL_LIBNAME) + rm -f $(DSPL_O_FILE) + diff --git a/dspl/obj/.gitignore b/dspl/obj/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/dspl/src/blas_lev1.c b/dspl/src/blas_lev1.c new file mode 100644 index 0000000..161ec5f --- /dev/null +++ b/dspl/src/blas_lev1.c @@ -0,0 +1,58 @@ +/* +* Copyright (c) 2015-2018 Sergey Bakhurin +* Digital Signal Processing Library [http://dsplib.org] +* +* This file is part of libdspl-2.0. +* +* is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DSPL is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with Foobar. If not, see . +*/ + + +#include +#include +#include +#include "dspl.h" + + + +void dscal_(int*, double*, double*, int*); + + + + +/************************************************************************************************** +DSCAL scales a vector by a constant +***************************************************************************************************/ +int DSPL_API blas_dscal(int n, double a, double* x, int incx) +{ + if(!x) + return ERROR_PTR; + if(n < 1) + return ERROR_SIZE; + if(incx < 1) + return ERROR_INC_SIZE; + + dscal_(&n, &a, x, &incx); + + return RES_OK; +} + + + + + + + + + diff --git a/dspl/src/dft.c b/dspl/src/dft.c new file mode 100644 index 0000000..ccf26ef --- /dev/null +++ b/dspl/src/dft.c @@ -0,0 +1,94 @@ +/* +* Copyright (c) 2015-2018 Sergey Bakhurin +* Digital Signal Processing Library [http://dsplib.org] +* +* This file is part of libdspl-2.0. +* +* is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DSPL is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with Foobar. If not, see . +*/ + + +#include +#include +#include "dspl.h" + + + +/************************************************************************************************** +Real vector DFT +***************************************************************************************************/ +int DSPL_API dft(double* x, int n, complex_t *y) +{ + int k; + int m; + double divn; + double phi; + + + if(!x || !y) + return ERROR_PTR; + + if(n<1) + return ERROR_SIZE; + + divn = 1.0 / (double)n; + + for(k = 0; k < n; k++) + { + RE(y[k]) = IM(y[k]) = 0.0; + for(m = 0; m < n; m++) + { + phi = -M_2PI * divn * (double)k * (double)m; + RE(y[k]) += x[m] * cos(phi); + IM(y[k]) += x[m] * sin(phi); + } + } + return RES_OK; +} + + + +/************************************************************************************************** +Complex vector DFT +***************************************************************************************************/ +int DSPL_API dft_cmplx(complex_t* x, int n, complex_t *y) +{ + int k; + int m; + double divn; + double phi; + complex_t e; + + if(!x || !y) + return ERROR_PTR; + + if(n<1) + return ERROR_SIZE; + + divn = 1.0 / (double)n; + + for(k = 0; k < n; k++) + { + RE(y[k]) = IM(y[k]) = 0.0; + for(m = 0; m < n; m++) + { + phi = -M_2PI * divn * (double)k * (double)m; + RE(e) = cos(phi); + IM(e) = sin(phi); + RE(y[k]) += CMRE(x[m], e); + IM(y[k]) += CMIM(x[m], e); + } + } + return RES_OK; +} diff --git a/dspl/src/fft.c b/dspl/src/fft.c new file mode 100644 index 0000000..0b4adc7 --- /dev/null +++ b/dspl/src/fft.c @@ -0,0 +1,167 @@ +/* +* Copyright (c) 2015-2018 Sergey Bakhurin +* Digital Signal Processing Library [http://dsplib.org] +* +* This file is part of libdspl-2.0. +* +* is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DSPL is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with Foobar. If not, see . +*/ + +#include +#include +#include +#include "dspl.h" +#include "fftw3.h" + + + +/************************************************************************************************** +Create FFT object +***************************************************************************************************/ +int DSPL_API fft_create( fft_t *pfft, int n) +{ + if(!pfft) + return ERROR_PTR; + if(n<1) + return ERROR_SIZE; + + printf("1\n"); + if(pfft->in) + { + if(pfft->size != n) + pfft->in = (complex_t*) realloc(pfft->in, n*sizeof(complex_t)); + } + else + pfft->in = (complex_t*) malloc(n*sizeof(complex_t)); + + if(pfft->out) + { + if(pfft->size != n) + pfft->out = (complex_t*) realloc(pfft->out, n*sizeof(complex_t)); + } + else + pfft->out = (complex_t*) malloc(n*sizeof(complex_t)); + + pfft->size = n; + printf("2\n"); + + if(pfft->pfftw) + fftw_destroy_plan(pfft->pfftw); + + printf("3\n"); + pfft->pfftw = (void*)fftw_plan_dft_1d(n, pfft->in, pfft->out, FFTW_FORWARD, FFTW_ESTIMATE); + printf("4\n"); + + if(!pfft->pfftw) + return ERROR_FFT_CREATE; + + return RES_OK; +} + + + +/************************************************************************************************** +Destroy FFT object +***************************************************************************************************/ +void DSPL_API fft_destroy(fft_t *pfft) +{ + if(pfft) + return; + + if(pfft->pfftw) + fftw_destroy_plan(pfft->pfftw); + + if(pfft->in) + free(pfft->in); + + if(pfft->out) + free(pfft->out); + + pfft->size = 0; +} + + + +/************************************************************************************************** +Destroy FFT object +***************************************************************************************************/ +int DSPL_API fft_cmplx(complex_t *x, int n, fft_t* pfft, complex_t* y) +{ + if(!x || !y || !pfft) + return ERROR_PTR; + + if(n<1) + return ERROR_SIZE; + + if(n != pfft->size) + fft_create(pfft, n); + + memcpy(pfft->in, x, n*sizeof(complex_t)); + + fftw_execute(pfft->pfftw); + + memcpy(y, pfft->out, n*sizeof(complex_t)); + return RES_OK; + +} + + + + +/************************************************************************************************** +FFT shifting +***************************************************************************************************/ +int DSPL_API fft_shift(double* x, int n, double* y) +{ + int n2, r; + int k; + double tmp; + double *buf; + + if(!x || !y) + return ERROR_PTR; + + if(n<1) + return ERROR_SIZE; + + r = n%2; + if(!r) + { + n2 = n>>1; + for(k = 0; k < n2; k++) + { + tmp = x[k]; + y[k] = x[k+n2]; + y[k+n2] = tmp; + } + } + else + { + n2 = (n-1) >> 1; + buf = (double*) malloc(n2*sizeof(double)); + memcpy(buf, x, n2*sizeof(double)); + memcpy(y, x+n2, (n2+1)*sizeof(double)); + memcpy(y+n2+1, buf, n2*sizeof(double)); + free(buf); + } + return RES_OK; +} + + + + + + + + diff --git a/ext/linux32/.gitignore b/ext/linux32/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/ext/linux64/.gitignore b/ext/linux64/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/ext/linux64/libblas.a b/ext/linux64/libblas.a new file mode 100644 index 0000000..e7ab755 Binary files /dev/null and b/ext/linux64/libblas.a differ diff --git a/ext/linux64/libfftw3.a b/ext/linux64/libfftw3.a new file mode 100644 index 0000000..cba3422 Binary files /dev/null and b/ext/linux64/libfftw3.a differ diff --git a/ext/linux64/liblapack.a b/ext/linux64/liblapack.a new file mode 100644 index 0000000..6cab14d Binary files /dev/null and b/ext/linux64/liblapack.a differ diff --git a/ext/win32/.gitignore b/ext/win32/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/ext/win64/.gitignore b/ext/win64/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/ext/win64/libfftw3.a b/ext/win64/libfftw3.a new file mode 100644 index 0000000..64b8e1b Binary files /dev/null and b/ext/win64/libfftw3.a differ diff --git a/include/dspl.c b/include/dspl.c new file mode 100644 index 0000000..4107af2 --- /dev/null +++ b/include/dspl.c @@ -0,0 +1,187 @@ +/* +* Copyright (c) 2015-2018 Sergey Bakhurin +* Digital Signal Processing Library [http://dsplib.org] +* +* This file is part of libdspl-2.0. +* +* is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DSPL is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with Foobar. If not, see . +*/ + + + + +#ifdef WIN_OS +#include +#endif //WIN_OS + +#ifdef LINUX_OS +#include +#endif //LINUX_OS + + +#include +#include "dspl.h" + + +#ifndef BUILD_LIB +p_blas_dscal blas_dscal ; +p_dft dft ; +p_dft_cmplx dft_cmplx ; +p_fft_create fft_create ; +p_fft_destroy fft_destroy ; +p_fft_cmplx fft_cmplx ; +p_fft_shift fft_shift ; + + +#endif //BUILD_LIB + + + + + + + +void* dspl_load() +{ + #ifdef WIN_OS + HINSTANCE handle; + char* fname; + handle = LoadLibrary(TEXT("libdspl.dll")); + if (!handle) + { + printf("libdspl.dll loading ERROR!\n"); + return NULL; + } + + fname = "dft"; + dft = (p_dft)GetProcAddress(handle, fname); + if(!dft) goto exit_label; + + fname = "dft_cmplx"; + dft_cmplx = (p_dft_cmplx)GetProcAddress(handle, fname); + if(!dft_cmplx) goto exit_label; + + + fname = "fft_create"; + fft_create = (p_fft_create)GetProcAddress(handle, fname); + if(!fft_create) goto exit_label; + + fname = "fft_destroy"; + fft_destroy = (p_fft_destroy)GetProcAddress(handle, fname); + if(!fft_destroy) goto exit_label; + + + fname = "fft_cmplx"; + fft_cmplx = (p_fft_cmplx)GetProcAddress(handle, fname); + if(!fft_cmplx) goto exit_label; + + fname = "fft_shift"; + fft_shift = (p_fft_shift)GetProcAddress(handle, fname); + if(!fft_shift) goto exit_label; + + + return (void*)handle; + exit_label: + printf("function %s loading ERROR!\n", fname); + if(handle) + FreeLibrary(handle); + return NULL; + #endif //WIN_OS + + + + + + + #ifdef LINUX_OS + char* error; + void *handle; + char* fname; + + // open the *.so + handle = dlopen ("./libdspl.so", RTLD_LAZY); + if (!handle) + { + printf("libdspl.so loading ERROR!\n"); + return NULL; + } + + + fname = "blas_dscal"; + blas_dscal = (p_blas_dscal)dlsym(handle, fname); + if ((error = dlerror()) != NULL) goto exit_label; + + fname = "dft"; + dft = (p_dft)dlsym(handle, fname); + if ((error = dlerror()) != NULL) goto exit_label; + + + fname = "dft_cmplx"; + dft_cmplx = (p_dft_cmplx)dlsym(handle, fname); + if ((error = dlerror()) != NULL) goto exit_label; + + fname = "fft_create"; + fft_create = (p_fft_create)dlsym(handle, fname); + if ((error = dlerror()) != NULL) goto exit_label; + + + fname = "fft_destroy"; + fft_destroy = (p_fft_destroy)dlsym(handle, fname); + if ((error = dlerror()) != NULL) goto exit_label; + + + fname = "fft_cmplx"; + fft_cmplx = (p_fft_cmplx)dlsym(handle, fname); + if ((error = dlerror()) != NULL) goto exit_label; + + + fname = "fft_shift"; + fft_shift = (p_fft_shift)dlsym(handle, fname); + if ((error = dlerror()) != NULL) goto exit_label; + + + return handle; + + exit_label: + printf("function %s loading ERROR!\n", fname); + if(handle) + dlclose(handle); + return NULL; + #endif //LINUX_OS + +} + + + + + + + +void dspl_free(void* handle) +{ + #ifdef WIN_OS + FreeLibrary((HINSTANCE)handle); + #endif //WIN_OS + + + + #ifdef LINUX_OS + dlclose(handle); + #endif //LINUX_OS + +} + + + + diff --git a/include/dspl.h b/include/dspl.h new file mode 100644 index 0000000..c3b5e0e --- /dev/null +++ b/include/dspl.h @@ -0,0 +1,194 @@ +/* +* Copyright (c) 2015-2018 Sergey Bakhurin +* Digital Signal Processing Library [http://dsplib.org] +* +* This file is part of libdspl-2.0. +* +* is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DSPL is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with Foobar. If not, see . +*/ + + +#ifndef DSPL_H +#define DSPL_H + + + +#include + + +/* math const definition */ +#ifndef M_PI + #define M_PI 3.1415926535897932384626433832795 +#endif +#ifndef M_2PI + #define M_2PI 6.283185307179586476925286766559 +#endif + + + +typedef double complex_t[2]; + + + +typedef struct +{ + void *pfftw; + complex_t *in; + complex_t *out; + size_t size; +} fft_t; + + +#define RE(x) (x[0]) +#define IM(x) (x[1]) + + +#define SQR(x) ((x) * (x)) +#define ABSSQR(x) ((SQR(RE(x))) + (SQR(IM(x)))) +#define ABS(x) sqrt((ABSSQR(x))) + +#define CMRE(a,b) ((RE(a)) * (RE(b)) - (IM(a)) * (IM(b))) +#define CMIM(a,b) ((RE(a)) * (IM(b)) + (IM(a)) * (RE(b))) + +#define CMCONJRE(a, b) ((RE(a)) * (RE(b)) + (IM(a)) * (IM(b))) +#define CMCONJIM(a, b) ((IM(a)) * (RE(b)) - (RE(a)) * (IM(b))) + + + + + +#define RES_OK 0 + +/* Error codes */ +/* A 0x01xxxxxx*/ +/* B 0x02xxxxxx*/ +/* C 0x03xxxxxx*/ +/* D 0x04xxxxxx*/ +#define ERROR_DAT_TYPE 0x04012020 +#define ERROR_DIV_ZERO 0x04102226 +/* E 0x05xxxxxx*/ +#define ERROR_ELLIP_MODULE 0x05121315 +/* F 0x06xxxxxx*/ +#define ERROR_FFT_CREATE 0x06060318 +#define ERROR_FILTER_A0 0x06100100 +#define ERROR_FILTER_ORD 0x06101518 +#define ERROR_FILTER_RP 0x06101816 +#define ERROR_FILTER_RS 0x06101819 +#define ERROR_FNAME 0x06140113 +#define ERROR_FOPEN 0x06151605 +#define ERROR_FWRITE_SIZE 0x06231820 +/* G 0x07xxxxxx*/ +/* H 0x08xxxxxx*/ +/* I 0x09xxxxxx*/ +#define ERROR_INC_SIZE 0x09140319 +/* J 0x10xxxxxx*/ +/* K 0x11xxxxxx*/ +/* L 0x12xxxxxx*/ +/* M 0x13xxxxxx*/ +/* N 0x14xxxxxx*/ +#define ERROR_NEGATIVE 0x14050701 +/* O 0x15xxxxxx*/ +/* P 0x16xxxxxx*/ +#define ERROR_POLY_ORD 0x16151518 +#define ERROR_PTR 0x16201800 +/* Q 0x17xxxxxx*/ +/* R 0x18xxxxxx*/ +#define ERROR_RAND_SIGMA 0x18011909 +#define ERROR_RESAMPLE_RATIO 0x18051801 +#define ERROR_RESAMPLE_FRAC_DELAY 0x18050604 +/* S 0x19xxxxxx*/ +#define ERROR_SIZE 0x19092605 +#define ERROR_SYM_TYPE 0x19251320 +/* T 0x20xxxxxx*/ +/* U 0x21xxxxxx*/ +/* V 0x22xxxxxx*/ +/* W 0x23xxxxxx*/ +#define ERROR_WIN_TYPE 0x23092025 +#define ERROR_WIN_SYM 0x23091925 +/* X 0x24xxxxxx*/ +/* Y 0x25xxxxxx*/ +/* Z 0x26xxxxxx*/ + + +#define DAT_DOUBLE 0 +#define DAT_COMPLEX 1 + + + +#ifdef __cplusplus +extern "C" { +#endif + + +// Declare DSPL_API for Windows OS +#ifdef BUILD_LIB + +#ifdef WIN_OS +#define DSPL_API __declspec(dllexport) +#endif // WIN_OS + +#ifdef LINUX_OS +#define DSPL_API +#endif //LINUX_OS + + +int DSPL_API blas_dscal(int n, double a, double* x, int incx); + +int DSPL_API dft (double* x, int n, complex_t *y); +int DSPL_API dft_cmplx (complex_t* x, int n, complex_t *y); + + +int DSPL_API fft_create ( fft_t *pfft, int n); +void DSPL_API fft_destroy (fft_t *pfft); +int DSPL_API fft_cmplx (complex_t *x, int n, fft_t* pfft, complex_t* y); +int DSPL_API fft_shift (double* x, int n, double* y); + + +#else //BUILD_LIB + + + +typedef int (*p_blas_dscal ) (int n, double a, double* x, int incx); +typedef int (*p_dft ) (double* x, int n, complex_t *y); +typedef int (*p_dft_cmplx ) (complex_t* x, int n, complex_t *y); +typedef int (*p_fft_create ) (fft_t *pfft, int n); +typedef void(*p_fft_destroy ) (fft_t *pfft); +typedef int (*p_fft_cmplx ) (complex_t *x, int n, fft_t* pfft, complex_t* y); +typedef int (*p_fft_shift ) (double* x, int n, double* y); + + + +extern p_blas_dscal blas_dscal ; +extern p_dft dft ; +extern p_dft_cmplx dft_cmplx ; +extern p_fft_create fft_create ; +extern p_fft_destroy fft_destroy ; +extern p_fft_cmplx fft_cmplx ; +extern p_fft_shift fft_shift ; + +#endif //BUILD_DLL + + +#ifdef __cplusplus +} +#endif + + +void* dspl_load(); +void dspl_free(void* handle); + + + +#endif //DSPL_H + diff --git a/include/fftw3.h b/include/fftw3.h new file mode 100644 index 0000000..bfde54e --- /dev/null +++ b/include/fftw3.h @@ -0,0 +1,514 @@ +/* + * Copyright (c) 2003, 2007-14 Matteo Frigo + * Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology + * + * The following statement of license applies *only* to this header file, + * and *not* to the other files distributed with FFTW or derived therefrom: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/***************************** NOTE TO USERS ********************************* + * + * THIS IS A HEADER FILE, NOT A MANUAL + * + * If you want to know how to use FFTW, please read the manual, + * online at http://www.fftw.org/doc/ and also included with FFTW. + * For a quick start, see the manual's tutorial section. + * + * (Reading header files to learn how to use a library is a habit + * stemming from code lacking a proper manual. Arguably, it's a + * *bad* habit in most cases, because header files can contain + * interfaces that are not part of the public, stable API.) + * + ****************************************************************************/ + +#ifndef FFTW3_H +#define FFTW3_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* If is included, use the C99 complex type. Otherwise + define a type bit-compatible with C99 complex */ +#if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I) +# define FFTW_DEFINE_COMPLEX(R, C) typedef R _Complex C +#else +# define FFTW_DEFINE_COMPLEX(R, C) typedef R C[2] +#endif + +#define FFTW_CONCAT(prefix, name) prefix ## name +#define FFTW_MANGLE_DOUBLE(name) FFTW_CONCAT(fftw_, name) +#define FFTW_MANGLE_FLOAT(name) FFTW_CONCAT(fftwf_, name) +#define FFTW_MANGLE_LONG_DOUBLE(name) FFTW_CONCAT(fftwl_, name) +#define FFTW_MANGLE_QUAD(name) FFTW_CONCAT(fftwq_, name) + +/* IMPORTANT: for Windows compilers, you should add a line + #define FFTW_DLL + here and in kernel/ifftw.h if you are compiling/using FFTW as a + DLL, in order to do the proper importing/exporting, or + alternatively compile with -DFFTW_DLL or the equivalent + command-line flag. This is not necessary under MinGW/Cygwin, where + libtool does the imports/exports automatically. */ +#if defined(FFTW_DLL) && (defined(_WIN32) || defined(__WIN32__)) + /* annoying Windows syntax for shared-library declarations */ +# if defined(COMPILING_FFTW) /* defined in api.h when compiling FFTW */ +# define FFTW_EXTERN extern __declspec(dllexport) +# else /* user is calling FFTW; import symbol */ +# define FFTW_EXTERN extern __declspec(dllimport) +# endif +#else +# define FFTW_EXTERN extern +#endif + +/* specify calling convention (Windows only) */ +#if defined(_WIN32) || defined(__WIN32__) +# define FFTW_CDECL __cdecl +#else +# define FFTW_CDECL +#endif + +enum fftw_r2r_kind_do_not_use_me { + FFTW_R2HC=0, FFTW_HC2R=1, FFTW_DHT=2, + FFTW_REDFT00=3, FFTW_REDFT01=4, FFTW_REDFT10=5, FFTW_REDFT11=6, + FFTW_RODFT00=7, FFTW_RODFT01=8, FFTW_RODFT10=9, FFTW_RODFT11=10 +}; + +struct fftw_iodim_do_not_use_me { + int n; /* dimension size */ + int is; /* input stride */ + int os; /* output stride */ +}; + +#include /* for ptrdiff_t */ +struct fftw_iodim64_do_not_use_me { + ptrdiff_t n; /* dimension size */ + ptrdiff_t is; /* input stride */ + ptrdiff_t os; /* output stride */ +}; + +typedef void (FFTW_CDECL *fftw_write_char_func_do_not_use_me)(char c, void *); +typedef int (FFTW_CDECL *fftw_read_char_func_do_not_use_me)(void *); + +/* + huge second-order macro that defines prototypes for all API + functions. We expand this macro for each supported precision + + X: name-mangling macro + R: real data type + C: complex data type +*/ + +#define FFTW_DEFINE_API(X, R, C) \ + \ +FFTW_DEFINE_COMPLEX(R, C); \ + \ +typedef struct X(plan_s) *X(plan); \ + \ +typedef struct fftw_iodim_do_not_use_me X(iodim); \ +typedef struct fftw_iodim64_do_not_use_me X(iodim64); \ + \ +typedef enum fftw_r2r_kind_do_not_use_me X(r2r_kind); \ + \ +typedef fftw_write_char_func_do_not_use_me X(write_char_func); \ +typedef fftw_read_char_func_do_not_use_me X(read_char_func); \ + \ +FFTW_EXTERN void \ +FFTW_CDECL X(execute)(const X(plan) p); \ + \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_dft)(int rank, const int *n, \ + C *in, C *out, int sign, unsigned flags); \ + \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_dft_1d)(int n, C *in, C *out, int sign, \ + unsigned flags); \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_dft_2d)(int n0, int n1, \ + C *in, C *out, int sign, unsigned flags); \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_dft_3d)(int n0, int n1, int n2, \ + C *in, C *out, int sign, unsigned flags); \ + \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_many_dft)(int rank, const int *n, \ + int howmany, \ + C *in, const int *inembed, \ + int istride, int idist, \ + C *out, const int *onembed, \ + int ostride, int odist, \ + int sign, unsigned flags); \ + \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_guru_dft)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + C *in, C *out, \ + int sign, unsigned flags); \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_guru_split_dft)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + R *ri, R *ii, R *ro, R *io, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_guru64_dft)(int rank, \ + const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + C *in, C *out, \ + int sign, unsigned flags); \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_guru64_split_dft)(int rank, \ + const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + R *ri, R *ii, R *ro, R *io, \ + unsigned flags); \ + \ +FFTW_EXTERN void \ +FFTW_CDECL X(execute_dft)(const X(plan) p, C *in, C *out); \ + \ +FFTW_EXTERN void \ +FFTW_CDECL X(execute_split_dft)(const X(plan) p, R *ri, R *ii, \ + R *ro, R *io); \ + \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_many_dft_r2c)(int rank, const int *n, \ + int howmany, \ + R *in, const int *inembed, \ + int istride, int idist, \ + C *out, const int *onembed, \ + int ostride, int odist, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_dft_r2c)(int rank, const int *n, \ + R *in, C *out, unsigned flags); \ + \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_dft_r2c_1d)(int n,R *in,C *out,unsigned flags); \ + \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_dft_r2c_2d)(int n0, int n1, \ + R *in, C *out, unsigned flags); \ + \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_dft_r2c_3d)(int n0, int n1, \ + int n2, \ + R *in, C *out, unsigned flags); \ + \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_many_dft_c2r)(int rank, const int *n, \ + int howmany, \ + C *in, const int *inembed, \ + int istride, int idist, \ + R *out, const int *onembed, \ + int ostride, int odist, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_dft_c2r)(int rank, const int *n, \ + C *in, R *out, unsigned flags); \ + \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_dft_c2r_1d)(int n,C *in,R *out,unsigned flags); \ + \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_dft_c2r_2d)(int n0, int n1, \ + C *in, R *out, unsigned flags); \ + \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_dft_c2r_3d)(int n0, int n1, \ + int n2, \ + C *in, R *out, unsigned flags); \ + \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_guru_dft_r2c)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + R *in, C *out, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_guru_dft_c2r)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + C *in, R *out, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_guru_split_dft_r2c)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + R *in, R *ro, R *io, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_guru_split_dft_c2r)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + R *ri, R *ii, R *out, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_guru64_dft_r2c)(int rank, \ + const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + R *in, C *out, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_guru64_dft_c2r)(int rank, \ + const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + C *in, R *out, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_guru64_split_dft_r2c)(int rank, const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + R *in, R *ro, R *io, \ + unsigned flags); \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_guru64_split_dft_c2r)(int rank, const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + R *ri, R *ii, R *out, \ + unsigned flags); \ + \ +FFTW_EXTERN void \ +FFTW_CDECL X(execute_dft_r2c)(const X(plan) p, R *in, C *out); \ + \ +FFTW_EXTERN void \ +FFTW_CDECL X(execute_dft_c2r)(const X(plan) p, C *in, R *out); \ + \ +FFTW_EXTERN void \ +FFTW_CDECL X(execute_split_dft_r2c)(const X(plan) p, \ + R *in, R *ro, R *io); \ + \ +FFTW_EXTERN void \ +FFTW_CDECL X(execute_split_dft_c2r)(const X(plan) p, \ + R *ri, R *ii, R *out); \ + \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_many_r2r)(int rank, const int *n, \ + int howmany, \ + R *in, const int *inembed, \ + int istride, int idist, \ + R *out, const int *onembed, \ + int ostride, int odist, \ + const X(r2r_kind) *kind, unsigned flags); \ + \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_r2r)(int rank, const int *n, R *in, R *out, \ + const X(r2r_kind) *kind, unsigned flags); \ + \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_r2r_1d)(int n, R *in, R *out, \ + X(r2r_kind) kind, unsigned flags); \ + \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_r2r_2d)(int n0, int n1, R *in, R *out, \ + X(r2r_kind) kind0, X(r2r_kind) kind1, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_r2r_3d)(int n0, int n1, int n2, \ + R *in, R *out, X(r2r_kind) kind0, \ + X(r2r_kind) kind1, X(r2r_kind) kind2, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_guru_r2r)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + R *in, R *out, \ + const X(r2r_kind) *kind, unsigned flags); \ + \ +FFTW_EXTERN X(plan) \ +FFTW_CDECL X(plan_guru64_r2r)(int rank, const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + R *in, R *out, \ + const X(r2r_kind) *kind, unsigned flags); \ + \ +FFTW_EXTERN void \ +FFTW_CDECL X(execute_r2r)(const X(plan) p, R *in, R *out); \ + \ +FFTW_EXTERN void \ +FFTW_CDECL X(destroy_plan)(X(plan) p); \ + \ +FFTW_EXTERN void \ +FFTW_CDECL X(forget_wisdom)(void); \ +FFTW_EXTERN void \ +FFTW_CDECL X(cleanup)(void); \ + \ +FFTW_EXTERN void \ +FFTW_CDECL X(set_timelimit)(double t); \ + \ +FFTW_EXTERN void \ +FFTW_CDECL X(plan_with_nthreads)(int nthreads); \ + \ +FFTW_EXTERN int \ +FFTW_CDECL X(init_threads)(void); \ + \ +FFTW_EXTERN void \ +FFTW_CDECL X(cleanup_threads)(void); \ + \ +FFTW_EXTERN void \ +FFTW_CDECL X(make_planner_thread_safe)(void); \ + \ +FFTW_EXTERN int \ +FFTW_CDECL X(export_wisdom_to_filename)(const char *filename); \ + \ +FFTW_EXTERN void \ +FFTW_CDECL X(export_wisdom_to_file)(FILE *output_file); \ + \ +FFTW_EXTERN char * \ +FFTW_CDECL X(export_wisdom_to_string)(void); \ + \ +FFTW_EXTERN void \ +FFTW_CDECL X(export_wisdom)(X(write_char_func) write_char, \ + void *data); \ +FFTW_EXTERN int \ +FFTW_CDECL X(import_system_wisdom)(void); \ + \ +FFTW_EXTERN int \ +FFTW_CDECL X(import_wisdom_from_filename)(const char *filename); \ + \ +FFTW_EXTERN int \ +FFTW_CDECL X(import_wisdom_from_file)(FILE *input_file); \ + \ +FFTW_EXTERN int \ +FFTW_CDECL X(import_wisdom_from_string)(const char *input_string); \ + \ +FFTW_EXTERN int \ +FFTW_CDECL X(import_wisdom)(X(read_char_func) read_char, void *data); \ + \ +FFTW_EXTERN void \ +FFTW_CDECL X(fprint_plan)(const X(plan) p, FILE *output_file); \ + \ +FFTW_EXTERN void \ +FFTW_CDECL X(print_plan)(const X(plan) p); \ + \ +FFTW_EXTERN char * \ +FFTW_CDECL X(sprint_plan)(const X(plan) p); \ + \ +FFTW_EXTERN void * \ +FFTW_CDECL X(malloc)(size_t n); \ + \ +FFTW_EXTERN R * \ +FFTW_CDECL X(alloc_real)(size_t n); \ +FFTW_EXTERN C * \ +FFTW_CDECL X(alloc_complex)(size_t n); \ + \ +FFTW_EXTERN void \ +FFTW_CDECL X(free)(void *p); \ + \ +FFTW_EXTERN void \ +FFTW_CDECL X(flops)(const X(plan) p, \ + double *add, double *mul, double *fmas); \ +FFTW_EXTERN double \ +FFTW_CDECL X(estimate_cost)(const X(plan) p); \ + \ +FFTW_EXTERN double \ +FFTW_CDECL X(cost)(const X(plan) p); \ + \ +FFTW_EXTERN int \ +FFTW_CDECL X(alignment_of)(R *p); \ + \ +FFTW_EXTERN const char X(version)[]; \ +FFTW_EXTERN const char X(cc)[]; \ +FFTW_EXTERN const char X(codelet_optim)[]; + + +/* end of FFTW_DEFINE_API macro */ + +FFTW_DEFINE_API(FFTW_MANGLE_DOUBLE, double, fftw_complex) +FFTW_DEFINE_API(FFTW_MANGLE_FLOAT, float, fftwf_complex) +FFTW_DEFINE_API(FFTW_MANGLE_LONG_DOUBLE, long double, fftwl_complex) + +/* __float128 (quad precision) is a gcc extension on i386, x86_64, and ia64 + for gcc >= 4.6 (compiled in FFTW with --enable-quad-precision) */ +#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) \ + && !(defined(__ICC) || defined(__INTEL_COMPILER) || defined(__CUDACC__) || defined(__PGI)) \ + && (defined(__i386__) || defined(__x86_64__) || defined(__ia64__)) +# if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I) +/* note: __float128 is a typedef, which is not supported with the _Complex + keyword in gcc, so instead we use this ugly __attribute__ version. + However, we can't simply pass the __attribute__ version to + FFTW_DEFINE_API because the __attribute__ confuses gcc in pointer + types. Hence redefining FFTW_DEFINE_COMPLEX. Ugh. */ +# undef FFTW_DEFINE_COMPLEX +# define FFTW_DEFINE_COMPLEX(R, C) typedef _Complex float __attribute__((mode(TC))) C +# endif +FFTW_DEFINE_API(FFTW_MANGLE_QUAD, __float128, fftwq_complex) +#endif + +#define FFTW_FORWARD (-1) +#define FFTW_BACKWARD (+1) + +#define FFTW_NO_TIMELIMIT (-1.0) + +/* documented flags */ +#define FFTW_MEASURE (0U) +#define FFTW_DESTROY_INPUT (1U << 0) +#define FFTW_UNALIGNED (1U << 1) +#define FFTW_CONSERVE_MEMORY (1U << 2) +#define FFTW_EXHAUSTIVE (1U << 3) /* NO_EXHAUSTIVE is default */ +#define FFTW_PRESERVE_INPUT (1U << 4) /* cancels FFTW_DESTROY_INPUT */ +#define FFTW_PATIENT (1U << 5) /* IMPATIENT is default */ +#define FFTW_ESTIMATE (1U << 6) +#define FFTW_WISDOM_ONLY (1U << 21) + +/* undocumented beyond-guru flags */ +#define FFTW_ESTIMATE_PATIENT (1U << 7) +#define FFTW_BELIEVE_PCOST (1U << 8) +#define FFTW_NO_DFT_R2HC (1U << 9) +#define FFTW_NO_NONTHREADED (1U << 10) +#define FFTW_NO_BUFFERING (1U << 11) +#define FFTW_NO_INDIRECT_OP (1U << 12) +#define FFTW_ALLOW_LARGE_GENERIC (1U << 13) /* NO_LARGE_GENERIC is default */ +#define FFTW_NO_RANK_SPLITS (1U << 14) +#define FFTW_NO_VRANK_SPLITS (1U << 15) +#define FFTW_NO_VRECURSE (1U << 16) +#define FFTW_NO_SIMD (1U << 17) +#define FFTW_NO_SLOW (1U << 18) +#define FFTW_NO_FIXED_RADIX_LARGE_N (1U << 19) +#define FFTW_ALLOW_PRUNING (1U << 20) + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* FFTW3_H */ diff --git a/instruction.txt b/instruction.txt new file mode 100644 index 0000000..5fcc182 --- /dev/null +++ b/instruction.txt @@ -0,0 +1,7 @@ +Сборка FFTW для LINUX +Для того чтобы разрешить позиционно-независимый код необходимо FFTW3 конфигурировать с флагом --enable-shared + +./configure --enable-shared +make + +После этого в скрытой дириктории .lib появится so файл и a файл. Статический файл a можно ликновать с so и подключать в so библиотеку. diff --git a/release/include/dspl.c b/release/include/dspl.c new file mode 100644 index 0000000..23bde1c --- /dev/null +++ b/release/include/dspl.c @@ -0,0 +1,164 @@ +#ifdef WIN_OS +#include +#endif //WIN_OS + +#ifdef LINUX_OS +#include +#endif //LINUX_OS + + +#include +#include "dspl.h" + + +#ifndef BUILD_LIB +p_blas_dscal blas_dscal ; +p_dft dft ; +p_dft_cmplx dft_cmplx ; +p_fft_create fft_create ; +p_fft_destroy fft_destroy ; +p_fft_cmplx fft_cmplx ; +p_fft_shift fft_shift ; + + +#endif //BUILD_LIB + + + + + + + +void* dspl_load() +{ + #ifdef WIN_OS + HINSTANCE handle; + char* fname; + handle = LoadLibrary(TEXT("libdspl.dll")); + if (!handle) + { + printf("libdspl.dll loading ERROR!\n"); + return NULL; + } + + fname = "dft"; + dft = (p_dft)GetProcAddress(handle, fname); + if(!dft) goto exit_label; + + fname = "dft_cmplx"; + dft_cmplx = (p_dft_cmplx)GetProcAddress(handle, fname); + if(!dft_cmplx) goto exit_label; + + + fname = "fft_create"; + fft_create = (p_fft_create)GetProcAddress(handle, fname); + if(!fft_create) goto exit_label; + + fname = "fft_destroy"; + fft_destroy = (p_fft_destroy)GetProcAddress(handle, fname); + if(!fft_destroy) goto exit_label; + + + fname = "fft_cmplx"; + fft_cmplx = (p_fft_cmplx)GetProcAddress(handle, fname); + if(!fft_cmplx) goto exit_label; + + fname = "fft_shift"; + fft_shift = (p_fft_shift)GetProcAddress(handle, fname); + if(!fft_shift) goto exit_label; + + + return (void*)handle; + exit_label: + printf("function %s loading ERROR!\n", fname); + if(handle) + FreeLibrary(handle); + return NULL; + #endif //WIN_OS + + + + + + + #ifdef LINUX_OS + char* error; + void *handle; + char* fname; + + // open the *.so + handle = dlopen ("./libdspl.so", RTLD_LAZY); + if (!handle) + { + printf("libdspl.so loading ERROR!\n"); + return NULL; + } + + + fname = "blas_dscal"; + blas_dscal = (p_blas_dscal)dlsym(handle, fname); + if ((error = dlerror()) != NULL) goto exit_label; + + fname = "dft"; + dft = (p_dft)dlsym(handle, fname); + if ((error = dlerror()) != NULL) goto exit_label; + + + fname = "dft_cmplx"; + dft_cmplx = (p_dft_cmplx)dlsym(handle, fname); + if ((error = dlerror()) != NULL) goto exit_label; + + fname = "fft_create"; + fft_create = (p_fft_create)dlsym(handle, fname); + if ((error = dlerror()) != NULL) goto exit_label; + + + fname = "fft_destroy"; + fft_destroy = (p_fft_destroy)dlsym(handle, fname); + if ((error = dlerror()) != NULL) goto exit_label; + + + fname = "fft_cmplx"; + fft_cmplx = (p_fft_cmplx)dlsym(handle, fname); + if ((error = dlerror()) != NULL) goto exit_label; + + + fname = "fft_shift"; + fft_shift = (p_fft_shift)dlsym(handle, fname); + if ((error = dlerror()) != NULL) goto exit_label; + + + return handle; + + exit_label: + printf("function %s loading ERROR!\n", fname); + if(handle) + dlclose(handle); + return NULL; + #endif //LINUX_OS + +} + + + + + + + +void dspl_free(void* handle) +{ + #ifdef WIN_OS + FreeLibrary((HINSTANCE)handle); + #endif //WIN_OS + + + + #ifdef LINUX_OS + dlclose(handle); + #endif //LINUX_OS + +} + + + + diff --git a/release/include/dspl.h b/release/include/dspl.h new file mode 100644 index 0000000..53f4b55 --- /dev/null +++ b/release/include/dspl.h @@ -0,0 +1,172 @@ +#ifndef DSPL_H +#define DSPL_H + + + +#include + + +/* math const definition */ +#ifndef M_PI + #define M_PI 3.1415926535897932384626433832795 +#endif +#ifndef M_2PI + #define M_2PI 6.283185307179586476925286766559 +#endif + + +typedef double complex_t[2]; + + + +typedef struct +{ + void *pfftw; + complex_t *in; + complex_t *out; + size_t size; +} fft_t; + + +#define RE(x) (x[0]) +#define IM(x) (x[1]) + + +#define SQR(x) ((x) * (x)) +#define ABSSQR(x) ((SQR(RE(x))) + (SQR(IM(x)))) +#define ABS(x) sqrt((ABSSQR(x))) + +#define CMRE(a,b) ((RE(a)) * (RE(b)) - (IM(a)) * (IM(b))) +#define CMIM(a,b) ((RE(a)) * (IM(b)) + (IM(a)) * (RE(b))) + +#define CMCONJRE(a, b) ((RE(a)) * (RE(b)) + (IM(a)) * (IM(b))) +#define CMCONJIM(a, b) ((IM(a)) * (RE(b)) - (RE(a)) * (IM(b))) + + + + + +#define RES_OK 0 + +/* Error codes */ +/* A 0x01xxxxxx*/ +/* B 0x02xxxxxx*/ +/* C 0x03xxxxxx*/ +/* D 0x04xxxxxx*/ +#define ERROR_DAT_TYPE 0x04012020 +#define ERROR_DIV_ZERO 0x04102226 +/* E 0x05xxxxxx*/ +#define ERROR_ELLIP_MODULE 0x05121315 +/* F 0x06xxxxxx*/ +#define ERROR_FFT_CREATE 0x06060318 +#define ERROR_FILTER_A0 0x06100100 +#define ERROR_FILTER_ORD 0x06101518 +#define ERROR_FILTER_RP 0x06101816 +#define ERROR_FILTER_RS 0x06101819 +#define ERROR_FNAME 0x06140113 +#define ERROR_FOPEN 0x06151605 +#define ERROR_FWRITE_SIZE 0x06231820 +/* G 0x07xxxxxx*/ +/* H 0x08xxxxxx*/ +/* I 0x09xxxxxx*/ +/* J 0x10xxxxxx*/ +/* K 0x11xxxxxx*/ +/* L 0x12xxxxxx*/ +/* M 0x13xxxxxx*/ +/* N 0x14xxxxxx*/ +#define ERROR_NEGATIVE 0x14050701 +/* O 0x15xxxxxx*/ +/* P 0x16xxxxxx*/ +#define ERROR_POLY_ORD 0x16151518 +#define ERROR_PTR 0x16201800 +/* Q 0x17xxxxxx*/ +/* R 0x18xxxxxx*/ +#define ERROR_RAND_SIGMA 0x18011909 +#define ERROR_RESAMPLE_RATIO 0x18051801 +#define ERROR_RESAMPLE_FRAC_DELAY 0x18050604 +/* S 0x19xxxxxx*/ +#define ERROR_SIZE 0x19092605 +#define ERROR_SYM_TYPE 0x19251320 +/* T 0x20xxxxxx*/ +/* U 0x21xxxxxx*/ +/* V 0x22xxxxxx*/ +/* W 0x23xxxxxx*/ +#define ERROR_WIN_TYPE 0x23092025 +#define ERROR_WIN_SYM 0x23091925 +/* X 0x24xxxxxx*/ +/* Y 0x25xxxxxx*/ +/* Z 0x26xxxxxx*/ + + +#define DAT_DOUBLE 0 +#define DAT_COMPLEX 1 + + + +#ifdef __cplusplus +extern "C" { +#endif + + +// Declare DSPL_API for Windows OS +#ifdef BUILD_LIB + +#ifdef WIN_OS +#define DSPL_API __declspec(dllexport) +#endif // WIN_OS + +#ifdef LINUX_OS +#define DSPL_API +#endif //LINUX_OS + + +void DSPL_API blas_dscal(int n, double a, double* x, int incx); + +int DSPL_API dft (double* x, int n, complex_t *y); +int DSPL_API dft_cmplx (complex_t* x, int n, complex_t *y); + + +int DSPL_API fft_create ( fft_t *pfft, int n); +void DSPL_API fft_destroy (fft_t *pfft); +int DSPL_API fft_cmplx (complex_t *x, int n, fft_t* pfft, complex_t* y); +int DSPL_API fft_shift (double* x, int n, double* y); + + +#else //BUILD_LIB + + + +typedef void (*p_blas_dscal)(int n, double a, double* x, int incx); + +typedef int (*p_dft ) (double* x, int n, complex_t *y); +typedef int (*p_dft_cmplx ) (complex_t* x, int n, complex_t *y); +typedef int (*p_fft_create ) (fft_t *pfft, int n); +typedef void(*p_fft_destroy ) (fft_t *pfft); +typedef int (*p_fft_cmplx ) (complex_t *x, int n, fft_t* pfft, complex_t* y); +typedef int (*p_fft_shift ) (double* x, int n, double* y); + + + +extern p_blas_dscal blas_dscal ; +extern p_dft dft ; +extern p_dft_cmplx dft_cmplx ; +extern p_fft_create fft_create ; +extern p_fft_destroy fft_destroy ; +extern p_fft_cmplx fft_cmplx ; +extern p_fft_shift fft_shift ; + +#endif //BUILD_DLL + + +#ifdef __cplusplus +} +#endif + + +void* dspl_load(); +void dspl_free(void* handle); + + + +#endif //DSPL_H + diff --git a/release/lib/linux32/.gitignore b/release/lib/linux32/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/release/lib/linux64/.gitignore b/release/lib/linux64/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/release/lib/win32/.gitignore b/release/lib/win32/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/release/lib/win64/.gitignore b/release/lib/win64/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/test/bin/.gitignore b/test/bin/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/test/obj/.gitignore b/test/obj/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/test/src/blas_test.c b/test/src/blas_test.c new file mode 100644 index 0000000..bb4fb1b --- /dev/null +++ b/test/src/blas_test.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include "dspl.h" + +#define N 16 +int main() +{ + void* handle; + handle = dspl_load(); + + double x[N]; + double a = 2.0; + + for(int k = 0; k < N; k++) + x[k] = (double)k; + + blas_dscal(N, a, x, 1); + + for(int k = 0; k < N; k++) + printf("x[%2d] = %9.3f \n", k, x[k]); + + // remember to free the resource + dspl_free(handle); + return 0; +} + + diff --git a/test/src/dft_test.c b/test/src/dft_test.c new file mode 100644 index 0000000..1053642 --- /dev/null +++ b/test/src/dft_test.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include "dspl.h" + +#define N 16 +int main() +{ + void* handle; + handle = dspl_load(); + + complex_t x[N]; + complex_t y[N]; + complex_t z[N]; + + + for(int k = 0; k < N; k++) + { + RE(x[k]) = (double)k; + IM(x[k]) = 0.0; + } + + dft_cmplx(x,N,y); + + fft_t pfft; + memset(&pfft, 0, sizeof(fft_t)); + // + fft_create(&pfft,N); + fft_cmplx(x, N, &pfft, z); + + for(int k = 0; k < N; k++) + printf("y[%2d] = %9.3f%9.3f z[%2d] = %9.3f%9.3f \n", k, RE(y[k]), IM(y[k]), k, RE(z[k]), IM(z[k])); + + + fft_destroy(&pfft); + // remember to free the resource + dspl_free(handle); + return 0; +} + +