Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CPP support #8

Open
puzrin opened this issue Oct 23, 2021 · 3 comments
Open

CPP support #8

puzrin opened this issue Oct 23, 2021 · 3 comments

Comments

@puzrin
Copy link

puzrin commented Oct 23, 2021

I have cpp project, and need to include fft.h into multiple files. Got build error:

.pio/build/hw_v1_stm32g030f6/src/app.o: In function `sine_init()':
/home/vitaly/Dropbox/Coding/dc_sc_grinder/lib/SYLT-FFT/include/fpmath.h:63: multiple definition of `sine_init()'
.pio/build/hw_v1_stm32g030f6/hal/stm32g030f6/app_hal.o:/home/vitaly/Dropbox/Coding/dc_sc_grinder/lib/SYLT-FFT/include/fpmath.h:63: first defined here
.pio/build/hw_v1_stm32g030f6/src/meter.o: In function `sine_init()':
/home/vitaly/Dropbox/Coding/dc_sc_grinder/lib/SYLT-FFT/include/fpmath.h:63: multiple definition of `sine_init()'
.pio/build/hw_v1_stm32g030f6/hal/stm32g030f6/app_hal.o:/home/vitaly/Dropbox/Coding/dc_sc_grinder/lib/SYLT-FFT/include/fpmath.h:63: first defined here
collect2: error: ld returned 1 exit status

And the same for multiple function.

Temporary fixed by add __INLINE to all fn declarations. But not sure how correct is that.

I understand (and agree with) your wish to keep everything in .h for simple use. Could you suggest a right fix?


Also, not sure, but probably worth to add

#ifdef __cplusplus
extern "C" {
#endif

// C code here

#ifdef __cplusplus
}
#endif

Into all header files

@stg
Copy link
Owner

stg commented Oct 23, 2021

It was designed to be included only once, in a source file that in turn provides a less primitive interface to the rest of the application.

This is not really a common way of doing things, but something I personally like for libraries having mostly low-level primitives that are typically never called alone in any given application.

So one correct way of doing it would be like I use it - import it once and build interfaces more specific to your application that are then used elsewhere.

Another (probably more correct) way would be to refactor the project to have methods in .c files. I think this is the only way to make the library widely compatible with various environments.

@puzrin
Copy link
Author

puzrin commented Oct 23, 2021

So one correct way of doing it would be like I use it - import it once and build interfaces more specific to your application that are then used elsewhere.

Actually, that means create proxy-methods for all your function. Possible, but strange. I'm ready to use this approach as "plan B" if nothing better possible.

Note, i don't like to create fork. I wish to improve usability of this repo as much as possible (as much as we can have consensus), and then will do the rest at my side.

Another (probably more correct) way would be to refactor the project to have methods in .c files. I think this is the only way to make the library widely compatible with various environments.

How is that acceptable for you? If yes - that would be ideal.

One more idea. You can split out functions to .c and create single_file_fft.h with this content:

#include "fft.h"
#include "../src/fft.c"

If anyone wish to use lib as single .h file - alternate header will satisfy such needs. And users with any preferences will be happy.

@stg
Copy link
Owner

stg commented Oct 23, 2021

No, not proxy functions - not the way that I use it.

For a specific application, one will typically use some sequence involving multiple SYLT-FFT primitives, and that algorithm is what I export from my "allthingsfft.c" which includes fft.h but is custom-built for each application. None of the primitive fft.h functions are exported since they are seldom directly useful to the application.

As an example - you are writing an application that needs to do something as common as FFT on real data for visualization purposes. Here, FFT output data is not immediately useful, but must be converted from vectors to phase+magnitude, while input data must be processed into complex form before an FFT can be performed.
So a function is constructed that converts input real data to complex form using a helper function, then performs the forward FFT and finally calculates phase+magnitude on each bin in the response using further helper functions before returning.
Again, no fft.h functions are exported to, or needed by, the application - only the one application-specific audio_to_spectrum() function is exported.
By using only .h files all FFT-related code is compiled as a single unit, allowing certain optimizations and inlining that would otherwise not be made unless using the sometimes problematic/buggy -flto.
This saves a few ROM bytes and CPU cycles on calls and stack management here and there and keeps the application's namespace free from all things related to SYLT-FFT. But - none of this is a big deal TBH and is all just my kind of curios way of implementing things.

I don't mind refactoring the project to make it more useful or standard, the pros outweigh the cons. I mean, the reason I put this up at all is that I want people to benefit from it, and making that easier is a good thing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants