kfrlib / kfr

Fast, modern C++ DSP framework, FFT, Sample Rate Conversion, FIR/IIR/Biquad Filters (SSE, AVX, AVX-512, ARM NEON)
https://www.kfrlib.com
GNU General Public License v2.0
1.65k stars 253 forks source link

Resampling problem ? #24

Closed doumdi closed 6 years ago

doumdi commented 6 years ago
  //Will use namespace kfr
    using namespace kfr;

    constexpr size_t input_sr  = 100;
    constexpr size_t output_sr = 50;

    //1Hz sine signal to be generated
    constexpr fbase frequency = 1.0;
    const univector<fbase, input_sr> o1 = sine(counter(0,1.0/input_sr) * 2.0 * constants<fbase>::pi * frequency);

    println("input_signal");
    println(o1.size());
    println(o1);

    //allocation of output vector
    univector<fbase> resampled(o1.size() * output_sr / input_sr);

    //Resampler
    auto r = resampler<fbase>(resample_quality::normal, output_sr, input_sr, 1.0, 0.496);

    println("output_signal");
    //Resample & get size
    const size_t destsize = r(resampled.data(), o1);
    println(destsize);
    println(resampled); 

I am trying to resample a 1Hz signal from sampling rate 100 to sampling rate 50.The sine wave is properly generated :

input_signal 100 0 0.0627905 0.125333 0.187381 0.24869 0.309017 0.368125 0.42578 0.481754 0.535827 0.587786 0.637425 0.684548 0.728969 0.770513 0.809017 0.844327 0.876306 0.904826 0.929776 0.951056 0.968583 0.982288 0.992116 0.998027 0.999999 0.998027 0.992116 0.982288 0.968583 0.951056 0.929776 0.904826 0.876306 0.844327 0.809017 0.770513 0.728969 0.684548 0.637425 0.587786 0.535827 0.481754 0.42578 0.368125 0.309017 0.24869 0.187381 0.125333 0.0627905 0 -0.063 -0.125333 -0.187381 -0.24869 -0.309017 -0.368125 -0.42578 -0.481754 -0.535827 -0.587786 -0.637425 -0.684548 -0.728969 -0.770513 -0.809017 -0.844327 -0.876306 -0.904826 -0.929776 -0.951056 -0.968583 -0.982288 -0.992116 -0.998027 -0.999999 -0.998027 -0.992116 -0.982288 -0.968583 -0.951056 -0.929776 -0.904826 -0.876306 -0.844327 -0.809017 -0.770513 -0.728969 -0.684548 -0.637425 -0.587786 -0.535827 -0.481754 -0.42578 -0.368125 -0.309017 -0.24869 -0.187381 -0.125333 -0.063

But the resampled data is not correct : output_signal 50 0 -5.4e-11 -8.5e-09 1.8e-08 -3.6e-08 5.5e-08 -8.2e-08 1.1e-07 -1.5e-07 1.9e-07 -2.4e-07 2.9e-07 -3.5e-07 4.2e-07 -4.8e-07 5.6e-07 -6.4e-07 7.3e-07 -8.2e-07 9.3e-07 -1e-06 1.1e-06 -1.3e-06 1.4e-06 -1.5e-06 1.6e-06 -1.8e-06 1.9e-06 -2.1e-06 2.2e-06 -2.4e-06 2.5e-06 -2.7e-06 2.9e-06 -3e-06 3.2e-06 -3.4e-06 3.5e-06 -3.7e-06 3.8e-06 -4e-06 4.1e-06 -4.3e-06 4.4e-06 -4.5e-06 4.6e-06 -4.7e-06 4.8e-06 -4.9e-06 4.9e-06

The code is based on the sample_rate_conversion.cpp example. I am doing something wrong ?

dancazarin commented 6 years ago

Hi,

Have you tried to run tests particularly sample rate conversion tests on your machine?

What compiler/OS/compiler arguments do you use?

doumdi commented 6 years ago

The sample_rate_conversion example works fine. All the tests are successful.

I have put the code above in the empty_test.cpp file for testing with same errors as above.

Compiler: Apple LLVM version 9.0.0 (clang-900.0.39.2) Target: x86_64-apple-darwin17.4.0

Compile trace (trying to use the library for another project called OpenIMU) :

[ 85%] Building CXX object third_party/kfr/examples/CMakeFiles/sample_rate_conversion.dir/sample_rate_conversion.cpp.o
cd /Users/dominic/Documents/working_area/build-OpenIMU.git-Desktop_Qt_5_9_1_clang_64bit2-Default/third_party/kfr/examples && /usr/bin/clang++   -I/Users/dominic/Documents/working_area/OpenIMU.git/third_party/kfr/examples/../include  -std=c++1y -fno-exceptions -fno-rtti -march=native -std=gnu++14 -o CMakeFiles/sample_rate_conversion.dir/sample_rate_conversion.cpp.o -c /Users/dominic/Documents/working_area/OpenIMU.git/third_party/kfr/examples/sample_rate_conversion.cpp
[ 85%] Linking CXX executable sample_rate_conversion
cd /Users/dominic/Documents/working_area/build-OpenIMU.git-Desktop_Qt_5_9_1_clang_64bit2-Default/third_party/kfr/examples && /Applications/CMake.app/Contents/bin/cmake -E cmake_link_script CMakeFiles/sample_rate_conversion.dir/link.txt --verbose=1
/usr/bin/clang++               -Wl,-search_paths_first -Wl,-headerpad_max_install_names  CMakeFiles/sample_rate_conversion.dir/sample_rate_conversion.cpp.o  -o sample_rate_conversion -lstdc++ -lpthread -lm 
doumdi commented 6 years ago

I just found that resampling quality=normal sets the length / order of the filter when resampling and its length when in normal quality is 512. That is perfectly normal that we get nothing in the output vector when the input vector length is 100, because of the filter delay.

dancazarin commented 6 years ago

Yes, this is true.