From 17cf61bf77e1de0c15b8fbde3e7d3f722c2d1d42 Mon Sep 17 00:00:00 2001 From: Henk Muller Date: Wed, 26 Jan 2022 10:44:02 +0000 Subject: [PATCH 1/3] Assembly Floating point FFT (single precision) --- lib_dsp/api/dsp_complex.h | 8 + lib_dsp/api/dsp_fft_float4.h | 116 ++ lib_dsp/src/dsp_tables.c | 1071 +++++++++++++++++ lib_dsp/src/fft/dsp_fft_float4.xc | 58 + lib_dsp/src/fft/dsp_fft_float4_forward.S | 184 +++ lib_dsp/src/fft/dsp_fft_float4_inverse.S | 183 +++ .../src/fft/dsp_fft_float4_merge_spectra.S | 86 ++ .../src/fft/dsp_fft_float4_split_spectrum.S | 89 ++ lib_dsp/src/gen/generatesine_float.sh | 32 + tests/test_fft_float/Makefile | 8 + tests/test_fft_float/config.xscope | 23 + tests/test_fft_float/src/test.xc | 100 ++ tests/test_fft_float/wscript | 10 + 13 files changed, 1968 insertions(+) create mode 100644 lib_dsp/api/dsp_fft_float4.h create mode 100644 lib_dsp/src/fft/dsp_fft_float4.xc create mode 100644 lib_dsp/src/fft/dsp_fft_float4_forward.S create mode 100644 lib_dsp/src/fft/dsp_fft_float4_inverse.S create mode 100644 lib_dsp/src/fft/dsp_fft_float4_merge_spectra.S create mode 100644 lib_dsp/src/fft/dsp_fft_float4_split_spectrum.S create mode 100644 lib_dsp/src/gen/generatesine_float.sh create mode 100644 tests/test_fft_float/Makefile create mode 100644 tests/test_fft_float/config.xscope create mode 100755 tests/test_fft_float/src/test.xc create mode 100644 tests/test_fft_float/wscript diff --git a/lib_dsp/api/dsp_complex.h b/lib_dsp/api/dsp_complex.h index 33a3c478..46768bae 100644 --- a/lib_dsp/api/dsp_complex.h +++ b/lib_dsp/api/dsp_complex.h @@ -33,6 +33,14 @@ typedef struct { double im; } dsp_complex_float_t; +/** Type that represents a complex number. Both the real and imaginary + * parts are represented as single precision values. + */ +typedef struct { + float re; + float im; +} dsp_complex_float4_t; + /** * Struct containing the sample data of two channels. Both channels * are represented as 32-bit fixed point values, with a Q value that diff --git a/lib_dsp/api/dsp_fft_float4.h b/lib_dsp/api/dsp_fft_float4.h new file mode 100644 index 00000000..ca1c0e38 --- /dev/null +++ b/lib_dsp/api/dsp_fft_float4.h @@ -0,0 +1,116 @@ +// Copyright (c) 2022, XMOS Ltd, All rights reserved + +#ifndef DSP_FFT_FLOAT4_H_ +#define DSP_FFT_FLOAT4_H_ + +#include +#include +#include // for bitreverse + +extern const float dsp_sine_float4_4[]; +extern const float dsp_sine_float4_8[]; +extern const float dsp_sine_float4_16[]; +extern const float dsp_sine_float4_32[]; +extern const float dsp_sine_float4_64[]; +extern const float dsp_sine_float4_128[]; +extern const float dsp_sine_float4_256[]; +extern const float dsp_sine_float4_512[]; +extern const float dsp_sine_float4_1024[]; +extern const float dsp_sine_float4_2048[]; +extern const float dsp_sine_float4_4096[]; +extern const float dsp_sine_float4_8192[]; +extern const float dsp_sine_float4_16384[]; + +#define FFT_FLOAT_SINE0(N) dsp_sine_float4_ ## N +#define FFT_FLOAT_SINE(N) FFT_FLOAT_SINE0(N) + +/** This function splits the spectrum of the FFT of two real sequences. Takes + * the result of a double-packed dsp_complex_float4_t array that has undergone + * an FFT. This function splits the result into two arrays, one for each real + * sequence, of length N/2. + * It is expected that the output will be cast by: + * dsp_complex_float4_t (* restrict w)[2] = (dsp_complex_float4_t (*)[2])pts; + * or a C equivalent. The 2 dimensional array w[2][N/2] can now be used to access + * the frequency information of the two real sequences independently, with the + * first index denoting the corresponding real sequence and the second index denoting + * the FFT frequency bin. + * Note that the DC component of the imaginary output spectrum (index zero) will + * contain the real component for the Nyquest rate. + * + * \param[in,out] pts Array of dsp_complex_t elements. + * \param[in] N Number of points. Must be a power of two. + * \param[in] mul_0_5 multiplier, set to 0.5 to get the normal + * behaviour + */ +void dsp_fft_float4_split_spectrum( dsp_complex_float4_t pts[], + const uint32_t N, + float m_0_5); + +/** This function merges two split spectra. It is the exact inverse operation of + * dsp_fft_float4_split_spectrum. + * + * \param[in,out] pts Array of dsp_complex_t elements. + * \param[in] N Number of points. Must be a power of two. + */ +void dsp_fft_float4_merge_spectra( dsp_complex_float4_t pts[], const uint32_t N ); + +/** This function preforms index bit reversing on the the arrays around prior to computing an FFT. A + * calling sequence for a forward FFT involves dsp_fft_float4_bit_reverse() followed by + * dsp_fft_forward(), and for an inverse FFT it involves dsp_fft_float4_bit_reverse() followed + * by dsp_fft_inverse(). In some cases bit reversal can be avoided, for example + * when computing a convolution. + * + * \param[in,out] pts Array of dsp_complex_t elements. + * \param[in] N Number of points. Must be a power of two. + */ +static inline void dsp_fft_float4_bit_reverse( dsp_complex_float4_t pts[], + const uint32_t N ) { +#ifdef __XC__ + dsp_fft_bit_reverse((pts, dsp_complex_t[]), N); +#else + dsp_fft_bit_reverse((dsp_complex_t*) pts, N); +#endif +} + +/** This function computes a forward FFT. The complex input signal is + * supplied in an array of real and imaginary floating-point values. + * The same array is also used to store the output. + * The number of points must be a power of 2, and the array of sine values should contain a quarter sine-wave. + * Use one of the dsp_sine_float4_N tables. The function does not perform bit reversed indexing of the input data. + * If required then dsp_fft_float4_bit_reverse() should be called beforehand. + * + * \param[in,out] pts Array of dsp_complex_float4_t elements. + * \param[in] N Number of points. Must be a power of two. + * \param[in] sine Array of N/4+1 sine values, each represented as a sign bit, + * and a 31 bit fraction. 1 should be represented as 0x7fffffff. + * Arrays are provided in dsp_tables.c; for example, for a 1024 point + * FFT use dsp_sine_1024. + */ +void dsp_fft_float4_forward ( + dsp_complex_float4_t pts[], + const uint32_t N, + const float sine[] ); + + +/** This function computes an inverse FFT. The input is a complex float array. + * The number of points must be a power of 2, and the + * array of sine values should contain a quarter sine-wave. Use one of the + * dsp_sine_float4_N tables. The function does not perform bit reversed indexing of the input data. + * if required then dsp_fft_float4_bit_reverse() should be called beforehand. + * + * Only available on XS3. + * + * \param[in,out] pts Array of dsp_complex_float4_t elements. + * \param[in] N Number of points. Must be a power of two. + * + * \param[in] sine Array of N/4+1 sine values. + * Arrays are provided in dsp_tables.c; for example, for a 1024 point + * FFT use dsp_sine_float4_1024. + */ + +void dsp_fft_float4_inverse ( + dsp_complex_float4_t pts[], + const uint32_t N, + const float sine[] ); + +#endif diff --git a/lib_dsp/src/dsp_tables.c b/lib_dsp/src/dsp_tables.c index 14586795..71d9f044 100644 --- a/lib_dsp/src/dsp_tables.c +++ b/lib_dsp/src/dsp_tables.c @@ -2101,3 +2101,1074 @@ const int32_t dsp_sine_16384[4097] = { 2147483647, }; +const float dsp_sine_float4_4[2] = { + 0.000000000000000000, 1.000000000000000000, +}; + +const float dsp_sine_float4_8[3] = { + 0.000000000000000000, 0.707106781170674159, 1.000000000000000000, +}; + +const float dsp_sine_float4_16[5] = { + 0.000000000000000000, 0.382683432354720021, 0.707106781170674159, 0.923879532498400824, + 1.000000000000000000, +}; + +const float dsp_sine_float4_32[9] = { + 0.000000000000000000, 0.195090322010624040, 0.382683432354720021, 0.555570233005603376, + 0.707106781170674159, 0.831469612286955706, 0.923879532498400824, 0.980785280395566450, + 1.000000000000000000, +}; + +const float dsp_sine_float4_64[17] = { + 0.000000000000000000, 0.098017140326768074, 0.195090322010624040, 0.290284677246406719, + 0.382683432354720021, 0.471396736813624151, 0.555570233005603376, 0.634393284148461856, + 0.707106781170674159, 0.773010453346715698, 0.831469612286955706, 0.881921264333804689, + 0.923879532498400824, 0.956940335721619739, 0.980785280395566450, 0.995184726668071340, + 1.000000000000000000, +}; + +const float dsp_sine_float4_128[33] = { + 0.000000000000000000, 0.049067674326016684, 0.098017140326768074, 0.146730474451198245, + 0.195090322010624040, 0.242980179896459036, 0.290284677246406719, 0.336889853382973059, + 0.382683432354720021, 0.427555093418867271, 0.471396736813624151, 0.514102744179984250, + 0.555570233005603376, 0.595699304477783409, 0.634393284148461856, 0.671558954831424915, + 0.707106781170674159, 0.740951125338941474, 0.773010453346715698, 0.803207531464765090, + 0.831469612286955706, 0.857728609985124901, 0.881921264333804689, 0.903989293109646375, + 0.923879532498400824, 0.941544065171204148, 0.956940335721619739, 0.970031253185339559, + 0.980785280395566450, 0.989176509958810901, 0.995184726668071340, 0.998795456203038223, + 1.000000000000000000, +}; + +const float dsp_sine_float4_256[65] = { + 0.000000000000000000, 0.024541228522210991, 0.049067674326016684, 0.073564563597568591, + 0.098017140326768074, 0.122410675195735036, 0.146730474451198245, 0.170961888755462976, + 0.195090322010624040, 0.219101240150709614, 0.242980179896459036, 0.266712757467461314, + 0.290284677246406719, 0.313681740390232111, 0.336889853382973059, 0.359895036525170631, + 0.382683432354720021, 0.405241313994087304, 0.427555093418867271, 0.449611329642701119, + 0.471396736813624151, 0.492898192216966236, 0.514102744179984250, 0.534997619873465724, + 0.555570233005603376, 0.575808191403506697, 0.595699304477783409, 0.615231590565694986, + 0.634393284148461856, 0.653172842938372300, 0.671558954831424915, 0.689540544721316873, + 0.707106781170674159, 0.724247082935504105, 0.740951125338941474, 0.757208846490447174, + 0.773010453346715698, 0.788346427610637446, 0.803207531464765090, 0.817584813135830202, + 0.831469612286955706, 0.844853565234319537, 0.857728609985124901, 0.870086991093843243, + 0.881921264333804689, 0.893224301181322011, 0.903989293109646375, 0.914209755690169490, + 0.923879532498400824, 0.932992798822367853, 0.941544065171204148, 0.949528180581814096, + 0.956940335721619739, 0.963776065785523439, 0.970031253185339559, 0.975702130030074888, + 0.980785280395566450, 0.985277642382105134, 0.989176509958810901, 0.992479534593643575, + 0.995184726668071340, 0.997290456675542281, 0.998795456203038223, 0.999698818695119673, + 1.000000000000000000, +}; + +const float dsp_sine_float4_512[129] = { + 0.000000000000000000, 0.012271538285369197, 0.024541228522210991, 0.036807222940307284, + 0.049067674326016684, 0.061320736300458104, 0.073564563597568591, 0.085797312341993670, + 0.098017140326768074, 0.110222207290745500, 0.122410675195735036, 0.134580708503303004, + 0.146730474451198245, 0.158858143329359519, 0.170961888755462976, 0.183039887949968533, + 0.195090322010624040, 0.207111376186385004, 0.219101240150709614, 0.231058108274187129, + 0.242980179896459036, 0.254865659597391991, 0.266712757467461314, 0.278519689377304980, + 0.290284677246406719, 0.302005949310868660, 0.313681740390232111, 0.325310292153307645, + 0.336889853382973059, 0.348418680239900080, 0.359895036525170631, 0.371317193941741563, + 0.382683432354720021, 0.393992040050409442, 0.405241313994087304, 0.416429560086475858, + 0.427555093418867271, 0.438616238526864710, 0.449611329642701119, 0.460538710946097607, + 0.471396736813624151, 0.482183772066524075, 0.492898192216966236, 0.503538383712686777, + 0.514102744179984250, 0.524589682665031143, 0.534997619873465724, 0.545324988408227851, + 0.555570233005603376, 0.565731810769441013, 0.575808191403506697, 0.585797857441941017, + 0.595699304477783409, 0.605511041389530824, 0.615231590565694986, 0.624859488127324725, + 0.634393284148461856, 0.643831542874493512, 0.653172842938372300, 0.662415777574668740, + 0.671558954831424915, 0.680600997779777117, 0.689540544721316873, 0.698376249393157011, + 0.707106781170674159, 0.715730825267896331, 0.724247082935504105, 0.732654271656418277, + 0.740951125338941474, 0.749136394507427417, 0.757208846490447174, 0.765167265606425118, + 0.773010453346715698, 0.780737228556094953, 0.788346427610637446, 0.795836904592954530, + 0.803207531464765090, 0.810457198236773424, 0.817584813135830202, 0.824589302769349053, + 0.831469612286955706, 0.838224705539344694, 0.844853565234319537, 0.851355193089992968, + 0.857728609985124901, 0.863972856106574150, 0.870086991093843243, 0.876070094180692371, + 0.881921264333804689, 0.887639620388477213, 0.893224301181322011, 0.898674465679953793, + 0.903989293109646375, 0.909167983076938357, 0.914209755690169490, 0.919113851676929272, + 0.923879532498400824, 0.928506080460582250, 0.932992798822367853, 0.937339011900476193, + 0.941544065171204148, 0.945607325368996832, 0.949528180581814096, 0.953306040343283034, + 0.956940335721619739, 0.960430519405308214, 0.963776065785523439, 0.966976471035286833, + 0.970031253185339559, 0.972939952196726243, 0.975702130030074888, 0.978317370711563994, + 0.980785280395566450, 0.983105487423961533, 0.985277642382105134, 0.987301418151450561, + 0.989176509958810901, 0.990902635422257094, 0.992479534593643575, 0.993906969997755407, + 0.995184726668071340, 0.996312612179136692, 0.997290456675542281, 0.998118112897503629, + 0.998795456203038223, 0.999322384586735724, 0.999698818695119673, 0.999924701838597940, + 1.000000000000000000, +}; + +const float dsp_sine_float4_1024[257] = { + 0.000000000000000000, 0.006135884648979102, 0.012271538285369197, 0.018406729905278779, + 0.024541228522210991, 0.030674803175760153, 0.036807222940307284, 0.042938256933714315, + 0.049067674326016684, 0.055195244348113945, 0.061320736300458104, 0.067443919561739299, + 0.073564563597568591, 0.079682437969157457, 0.085797312341993670, 0.091908956494513208, + 0.098017140326768074, 0.104121633869089361, 0.110222207290745500, 0.116318630908595219, + 0.122410675195735036, 0.128498110790140785, 0.134580708503303004, 0.140658239328855655, + 0.146730474451198245, 0.152797185254110485, 0.158858143329359519, 0.164913120485299547, + 0.170961888755462976, 0.177004220407143142, 0.183039887949968533, 0.189068664144467574, + 0.195090322010624040, 0.201104634836422685, 0.207111376186385004, 0.213110319910094159, + 0.219101240150709614, 0.225083911353470389, 0.231058108274187129, 0.237023605987722402, + 0.242980179896459036, 0.248927605738756053, 0.254865659597391991, 0.260794117907995282, + 0.266712757467461314, 0.272621355442355939, 0.278519689377304980, 0.284407537203369531, + 0.290284677246406719, 0.296150888235415799, 0.302005949310868660, 0.307849640033025007, + 0.313681740390232111, 0.319502030807207849, 0.325310292153307645, 0.331106305750774710, + 0.336889853382973059, 0.342660717302603113, 0.348418680239900080, 0.354163525410813806, + 0.359895036525170631, 0.365612997794816541, 0.371317193941741563, 0.377007410206184779, + 0.382683432354720021, 0.388345046688321482, 0.393992040050409442, 0.399624199834875571, + 0.405241313994087304, 0.410843171046871347, 0.416429560086475858, 0.422000270788510934, + 0.427555093418867271, 0.433093818841612410, 0.438616238526864710, 0.444122144558644349, + 0.449611329642701119, 0.455083587114319177, 0.460538710946097607, 0.465976495755707487, + 0.471396736813624151, 0.476799230050835243, 0.482183772066524075, 0.487550160135726884, + 0.492898192216966236, 0.498227666959856708, 0.503538383712686777, 0.508830142529972052, + 0.514102744179984250, 0.519355990152251090, 0.524589682665031143, 0.529803624672759210, + 0.534997619873465724, 0.540171472716167056, 0.545324988408227851, 0.550457972922695271, + 0.555570233005603376, 0.560661576183249744, 0.565731810769441013, 0.570780745872710993, + 0.575808191403506697, 0.580813958081345505, 0.585797857441941017, 0.590759701844299490, + 0.595699304477783409, 0.600616479369145750, 0.605511041389530824, 0.610382806261445254, + 0.615231590565694986, 0.620057211748291537, 0.624859488127324725, 0.629638238899803415, + 0.634393284148461856, 0.639124444848533924, 0.643831542874493512, 0.648514401006760277, + 0.653172842938372300, 0.657806693281623889, 0.662415777574668740, 0.666999922288088243, + 0.671558954831424915, 0.676092703559680208, 0.680600997779777117, 0.685083667756986370, + 0.689540544721316873, 0.693971460873869961, 0.698376249393157011, 0.702754744441379642, + 0.707106781170674159, 0.711432195729317485, 0.715730825267896331, 0.720002507945437964, + 0.724247082935504105, 0.728464390432245423, 0.732654271656418277, 0.736816568861362708, + 0.740951125338941474, 0.745057785425440100, 0.749136394507427417, 0.753186799027576792, + 0.757208846490447174, 0.761202385468225273, 0.765167265606425118, 0.769103337629551076, + 0.773010453346715698, 0.776888465657220917, 0.780737228556094953, 0.784556597139589806, + 0.788346427610637446, 0.792106577284262259, 0.795836904592954530, 0.799537269091999514, + 0.803207531464765090, 0.806847553527947570, 0.810457198236773424, 0.814036329690159821, + 0.817584813135830202, 0.821102514975388553, 0.824589302769349053, 0.828045045242121636, + 0.831469612286955706, 0.834862874970837443, 0.838224705539344694, 0.841554977421456685, + 0.844853565234319537, 0.848120344787966163, 0.851355193089992968, 0.854557988350189590, + 0.857728609985124901, 0.860866938622686151, 0.863972856106574150, 0.867046245500750934, + 0.870086991093843243, 0.873094978403497701, 0.876070094180692371, 0.879012226414000009, + 0.881921264333804689, 0.884797098416473027, 0.887639620388477213, 0.890448723230471750, + 0.893224301181322011, 0.895966249742087273, 0.898674465679953793, 0.901348847032122258, + 0.903989293109646375, 0.906595704501223620, 0.909167983076938357, 0.911706031991956101, + 0.914209755690169490, 0.916679059907796634, 0.919113851676929272, 0.921514039329033530, + 0.923879532498400824, 0.926210242125550476, 0.928506080460582250, 0.930766961066480270, + 0.932992798822367853, 0.935183509926711398, 0.937339011900476193, 0.939459223590231041, + 0.941544065171204148, 0.943593458150288611, 0.945607325368996832, 0.947585591006366412, + 0.949528180581814096, 0.951435020957940414, 0.953306040343283034, 0.955141168295019494, + 0.956940335721619739, 0.958703474885446938, 0.960430519405308214, 0.962121404258953317, + 0.963776065785523439, 0.965394441687947302, 0.966976471035286833, 0.968522094265031219, + 0.970031253185339559, 0.971503890977231443, 0.972939952196726243, 0.974339382776930885, + 0.975702130030074888, 0.977028142649494558, 0.978317370711563994, 0.979569765677575477, + 0.980785280395566450, 0.981963869102094655, 0.983105487423961533, 0.984210092379882440, + 0.985277642382105134, 0.986308097237975523, 0.987301418151450561, 0.988257567724559305, + 0.989176509958810901, 0.990058210256549387, 0.990902635422257094, 0.991709753663803650, + 0.992479534593643575, 0.993211949229959812, 0.993906969997755407, 0.994564570729891129, + 0.995184726668071340, 0.995767414463775147, 0.996312612179136692, 0.996820299287769940, + 0.997290456675542281, 0.997723066641293732, 0.998118112897503629, 0.998475580570903798, + 0.998795456203038223, 0.999077727750770306, 0.999322384586735724, 0.999529417499742889, + 0.999698818695119673, 0.999830581795006723, 0.999924701838597940, 0.999981175282326773, + 1.000000000000000000, +}; + +const float dsp_sine_float4_2048[513] = { + 0.000000000000000000, 0.003067956762878288, 0.006135884648979102, 0.009203754781796764, + 0.012271538285369197, 0.015339206284549710, 0.018406729905278779, 0.021474080274855829, + 0.024541228522210991, 0.027608145778176843, 0.030674803175760153, 0.033741171850413559, + 0.036807222940307284, 0.039872927586600763, 0.042938256933714315, 0.046003182129600695, + 0.049067674326016684, 0.052131704678794639, 0.055195244348113945, 0.058258264498772507, + 0.061320736300458104, 0.064382630928019824, 0.067443919561739299, 0.070504573387602049, + 0.073564563597568591, 0.076623861389845713, 0.079682437969157457, 0.082740264547016218, + 0.085797312341993670, 0.088853552579991696, 0.091908956494513208, 0.094963495326932934, + 0.098017140326768074, 0.101069862751948916, 0.104121633869089361, 0.107172424953757423, + 0.110222207290745500, 0.113270952174340758, 0.116318630908595219, 0.119365214807595960, + 0.122410675195735036, 0.125454983407979420, 0.128498110790140785, 0.131540028699145273, + 0.134580708503303004, 0.137620121582577609, 0.140658239328855655, 0.143695033146215873, + 0.146730474451198245, 0.149764534673073241, 0.152797185254110485, 0.155828397649847739, + 0.158858143329359519, 0.161886393775525633, 0.164913120485299547, 0.167938294969976781, + 0.170961888755462976, 0.173983873382541815, 0.177004220407143142, 0.180022901400610419, + 0.183039887949968533, 0.186055151658191031, 0.189068664144467574, 0.192080397044470941, + 0.195090322010624040, 0.198098410712366779, 0.201104634836422685, 0.204108966087065413, + 0.207111376186385004, 0.210111836874554148, 0.213110319910094159, 0.216106797070140716, + 0.219101240150709614, 0.222093620966962141, 0.225083911353470389, 0.228072083164482436, + 0.231058108274187129, 0.234041958576978931, 0.237023605987722402, 0.240003022442016545, + 0.242980179896459036, 0.245955050328910019, 0.248927605738756053, 0.251897818147173491, + 0.254865659597391991, 0.257831102154957470, 0.260794117907995282, 0.263754678967472622, + 0.266712757467461314, 0.269668325565399936, 0.272621355442355939, 0.275571819303287446, + 0.278519689377304980, 0.281464937917932589, 0.284407537203369531, 0.287347459536750394, + 0.290284677246406719, 0.293219162686126744, 0.296150888235415799, 0.299079826299756657, + 0.302005949310868660, 0.304929229726967677, 0.307849640033025007, 0.310767152741026786, + 0.313681740390232111, 0.316593375547432165, 0.319502030807207849, 0.322407678792188179, + 0.325310292153307645, 0.328209843570063942, 0.331106305750774710, 0.333999651432834943, + 0.336889853382973059, 0.339776884397507528, 0.342660717302603113, 0.345541324954525997, + 0.348418680239900080, 0.351292756075961443, 0.354163525410813806, 0.357030961223682830, + 0.359895036525170631, 0.362755724357509579, 0.365612997794816541, 0.368466829943345453, + 0.371317193941741563, 0.374164062961293065, 0.377007410206184779, 0.379847208913749346, + 0.382683432354720021, 0.385516053833481420, 0.388345046688321482, 0.391170384291681994, + 0.393992040050409442, 0.396809987406005260, 0.399624199834875571, 0.402434650848581432, + 0.405241313994087304, 0.408044162854010961, 0.410843171046871347, 0.413638312227337435, + 0.416429560086475858, 0.419216888351998773, 0.422000270788510934, 0.424779681197756886, + 0.427555093418867271, 0.430326481328605293, 0.433093818841612410, 0.435857079910654088, + 0.438616238526864710, 0.441371268719992604, 0.444122144558644349, 0.446868840150528801, + 0.449611329642701119, 0.452349587221805627, 0.455083587114319177, 0.457813303586793507, + 0.460538710946097607, 0.463259783539659464, 0.465976495755707487, 0.468688822023511642, + 0.471396736813624151, 0.474100214638119688, 0.476799230050835243, 0.479493757647610042, + 0.482183772066524075, 0.484869247988137075, 0.487550160135726884, 0.490226483275527480, + 0.492898192216966236, 0.495565261812900837, 0.498227666959856708, 0.500885382598262541, + 0.503538383712686777, 0.506186645332072249, 0.508830142529972052, 0.511468850424783961, + 0.514102744179984250, 0.516731799004361725, 0.519355990152251090, 0.521975292923766099, + 0.524589682665031143, 0.527199134768414512, 0.529803624672759210, 0.532403127863614323, + 0.534997619873465724, 0.537587076281966558, 0.540171472716167056, 0.542750784850743573, + 0.545324988408227851, 0.547894059159235947, 0.550457972922695271, 0.553016705566073186, + 0.555570233005603376, 0.558118531206513335, 0.560661576183249744, 0.563199343999704616, + 0.565731810769441013, 0.568258952655917082, 0.570780745872710993, 0.573297166683744530, + 0.575808191403506697, 0.578313796397276425, 0.580813958081345505, 0.583308652923239634, + 0.585797857441941017, 0.588281548208108740, 0.590759701844299490, 0.593232295025187262, + 0.595699304477783409, 0.598160706981655577, 0.600616479369145750, 0.603066598525589082, + 0.605511041389530824, 0.607949784952944050, 0.610382806261445254, 0.612810082414511403, + 0.615231590565694986, 0.617647307922838951, 0.620057211748291537, 0.622461279359120101, + 0.624859488127324725, 0.627251815480051267, 0.629638238899803415, 0.632018735924655184, + 0.634393284148461856, 0.636761861221071257, 0.639124444848533924, 0.641481012793313043, + 0.643831542874493512, 0.646176012967990987, 0.648514401006760277, 0.650846684981002288, + 0.653172842938372300, 0.655492852984185581, 0.657806693281623889, 0.660114342051941305, + 0.662415777574668740, 0.664710978187818435, 0.666999922288088243, 0.669282588331064354, + 0.671558954831424915, 0.673829000363141195, 0.676092703559680208, 0.678350043114205437, + 0.680600997779777117, 0.682845546369552858, 0.685083667756986370, 0.687315340876026859, + 0.689540544721316873, 0.691759258348390471, 0.693971460873869961, 0.696177131475662736, + 0.698376249393157011, 0.700568793927417333, 0.702754744441379642, 0.704934080360045123, + 0.707106781170674159, 0.709272826422979286, 0.711432195729317485, 0.713584868764882696, + 0.715730825267896331, 0.717870045039798454, 0.720002507945437964, 0.722128193913261773, + 0.724247082935504105, 0.726359155068374340, 0.728464390432245423, 0.730562769211840157, + 0.732654271656418277, 0.734738878079962410, 0.736816568861362708, 0.738887324444602478, + 0.740951125338941474, 0.743007952119099757, 0.745057785425440100, 0.747100605964150954, + 0.749136394507427417, 0.751165131893652416, 0.753186799027576792, 0.755201376880499708, + 0.757208846490447174, 0.759209188962350789, 0.761202385468225273, 0.763188417247345763, + 0.765167265606425118, 0.767138911919788891, 0.769103337629551076, 0.771060524245788526, + 0.773010453346715698, 0.774953106578857298, 0.776888465657220917, 0.778816512365470004, + 0.780737228556094953, 0.782650596150582967, 0.784556597139589806, 0.786455213583108326, + 0.788346427610637446, 0.790230221421350243, 0.792106577284262259, 0.793975477538397367, + 0.795836904592954530, 0.797690840927473555, 0.799537269091999514, 0.801376171707247176, + 0.803207531464765090, 0.805031331127097571, 0.806847553527947570, 0.808656181572338206, + 0.810457198236773424, 0.812250586569398636, 0.814036329690159821, 0.815814410790962508, + 0.817584813135830202, 0.819347520061061929, 0.821102514975388553, 0.822849781360129873, + 0.824589302769349053, 0.826321062830008057, 0.828045045242121636, 0.829761233778910978, + 0.831469612286955706, 0.833170164686346748, 0.834862874970837443, 0.836547727207993752, + 0.838224705539344694, 0.839893794180531672, 0.841554977421456685, 0.843208239626430545, + 0.844853565234319537, 0.846490938758692413, 0.848120344787966163, 0.849741767985550456, + 0.851355193089992968, 0.852960604915121823, 0.854557988350189590, 0.856147328360015059, + 0.857728609985124901, 0.859301818341893897, 0.860866938622686151, 0.862423956095993427, + 0.863972856106574150, 0.865513624075591625, 0.867046245500750934, 0.868570705956435596, + 0.870086991093843243, 0.871595086641120398, 0.873094978403497701, 0.874586652263422581, + 0.876070094180692371, 0.877545290192587202, 0.879012226414000009, 0.880470889037568538, + 0.881921264333804689, 0.883363338651223740, 0.884797098416473027, 0.886222530134459618, + 0.887639620388477213, 0.889048355840332816, 0.890448723230471750, 0.891840709378102670, + 0.893224301181322011, 0.894599485617236789, 0.895966249742087273, 0.897324580691369000, + 0.898674465679953793, 0.900015892002209994, 0.901348847032122258, 0.902673318223410126, + 0.903989293109646375, 0.905296759304374143, 0.906595704501223620, 0.907886116474028060, + 0.909167983076938357, 0.910441292244537959, 0.911706031991956101, 0.912962190414980279, + 0.914209755690169490, 0.915448716074963920, 0.916679059907796634, 0.917900775608202935, + 0.919113851676929272, 0.920318276696041826, 0.921514039329033530, 0.922701128320931097, + 0.923879532498400824, 0.925049240769853953, 0.926210242125550476, 0.927362525637703605, + 0.928506080460582250, 0.929640895830612490, 0.930766961066480270, 0.931884265569230541, + 0.932992798822367853, 0.934092550391955045, 0.935183509926711398, 0.936265667158110548, + 0.937339011900476193, 0.938403534051079014, 0.939459223590231041, 0.940506070581380249, + 0.941544065171204148, 0.942573197589702372, 0.943593458150288611, 0.944604837249881868, + 0.945607325368996832, 0.946600913071833583, 0.947585591006366412, 0.948561349904431306, + 0.949528180581814096, 0.950486073938336173, 0.951435020957940414, 0.952375012708776225, + 0.953306040343283034, 0.954228095098274331, 0.955141168295019494, 0.956045251339325941, + 0.956940335721619739, 0.957826413017025757, 0.958703474885446938, 0.959571513071643012, + 0.960430519405308214, 0.961280485801147333, 0.962121404258953317, 0.962953266863681323, + 0.963776065785523439, 0.964589793279983176, 0.965394441687947302, 0.966190003435758560, + 0.966976471035286833, 0.967753837083999424, 0.968522094265031219, 0.969281235347252967, + 0.970031253185339559, 0.970772140719837529, 0.971503890977231443, 0.972226497070008855, + 0.972939952196726243, 0.973644249642072190, 0.974339382776930885, 0.975025345058444626, + 0.975702130030074888, 0.976369731321664158, 0.977028142649494558, 0.977677357816347903, + 0.978317370711563994, 0.978948175311097568, 0.979569765677575477, 0.980182135960352530, + 0.980785280395566450, 0.981379193306191944, 0.981963869102094655, 0.982539302280083238, + 0.983105487423961533, 0.983662419204579197, 0.984210092379882440, 0.984748501794962539, + 0.985277642382105134, 0.985797509160837526, 0.986308097237975523, 0.986809401807669628, + 0.987301418151450561, 0.987784141638272883, 0.988257567724559305, 0.988721691954243309, + 0.989176509958810901, 0.989622017457341574, 0.990058210256549387, 0.990485084250821379, + 0.990902635422257094, 0.991310859840705660, 0.991709753663803650, 0.992099313137010275, + 0.992479534593643575, 0.992850414454914176, 0.993211949229959812, 0.993564135515877411, + 0.993906969997755407, 0.994240449448705155, 0.994564570729891129, 0.994879330790560346, + 0.995184726668071340, 0.995480755487921587, 0.995767414463775147, 0.996044700897488755, + 0.996312612179136692, 0.996571145787035984, 0.996820299287769940, 0.997060070336210802, + 0.997290456675542281, 0.997511456137280206, 0.997723066641293732, 0.997925286195823991, + 0.998118112897503629, 0.998301544931374352, 0.998475580570903798, 0.998640218178002415, + 0.998795456203038223, 0.998941293184852031, 0.999077727750770306, 0.999204758616619171, + 0.999322384586735724, 0.999430604553979474, 0.999529417499742889, 0.999618822493960835, + 0.999698818695119673, 0.999769405350264373, 0.999830581795006723, 0.999882347453530551, + 0.999924701838597940, 0.999957644551553115, 0.999981175282326773, 0.999995293809438746, + 1.000000000000000000, +}; + +const float dsp_sine_float4_4096[1025] = { + 0.000000000000000000, 0.001533980186240921, 0.003067956762878288, 0.004601926120317039, + 0.006135884648979102, 0.007669828739311883, 0.009203754781796764, 0.010737659166957599, + 0.012271538285369197, 0.013805388527665828, 0.015339206284549710, 0.016872987946799495, + 0.018406729905278779, 0.019940428550944574, 0.021474080274855829, 0.023007681468181884, + 0.024541228522210991, 0.026074717828358799, 0.027608145778176843, 0.029141508763361038, + 0.030674803175760153, 0.032208025407384336, 0.033741171850413559, 0.035274238897206163, + 0.036807222940307284, 0.038340120372457390, 0.039872927586600763, 0.041405640975893956, + 0.042938256933714315, 0.044470771853668441, 0.046003182129600695, 0.047535484155601666, + 0.049067674326016684, 0.050599749035454271, 0.052131704678794639, 0.053663537651198183, + 0.055195244348113945, 0.056726821165288127, 0.058258264498772507, 0.059789570744933004, + 0.061320736300458104, 0.062851757562367355, 0.064382630928019824, 0.065913352795122615, + 0.067443919561739299, 0.068974327626298446, 0.070504573387602049, 0.072034653244833990, + 0.073564563597568591, 0.075094300845779005, 0.076623861389845713, 0.078153241630565015, + 0.079682437969157457, 0.081211446807276363, 0.082740264547016218, 0.084268887590921202, + 0.085797312341993670, 0.087325535203702495, 0.088853552579991696, 0.090381360875288752, + 0.091908956494513208, 0.093436335843084986, 0.094963495326932934, 0.096490431352503292, + 0.098017140326768074, 0.099543618657233601, 0.101069862751948916, 0.102595869019514216, + 0.104121633869089361, 0.105647153710402286, 0.107172424953757423, 0.108697444010044206, + 0.110222207290745500, 0.111746711207946020, 0.113270952174340758, 0.114794926603243502, + 0.116318630908595219, 0.117842061504972492, 0.119365214807595960, 0.120888087232338778, + 0.122410675195735036, 0.123932975114988159, 0.125454983407979420, 0.126976696493276253, + 0.128498110790140785, 0.130019222718538219, 0.131540028699145273, 0.133060525153358533, + 0.134580708503303004, 0.136100575171840377, 0.137620121582577609, 0.139139344159875167, + 0.140658239328855655, 0.142176803515411954, 0.143695033146215873, 0.145212924648726399, + 0.146730474451198245, 0.148247678982690145, 0.149764534673073241, 0.151281037953039599, + 0.152797185254110485, 0.154312973008644883, 0.155828397649847739, 0.157343455611778565, + 0.158858143329359519, 0.160372457238384197, 0.161886393775525633, 0.163399949378344955, + 0.164913120485299547, 0.166425903535751735, 0.167938294969976781, 0.169450291229171629, + 0.170961888755462976, 0.172473083991915799, 0.173983873382541815, 0.175494253372307590, + 0.177004220407143142, 0.178513770933950128, 0.180022901400610419, 0.181531608255994209, + 0.183039887949968533, 0.184547736933405565, 0.186055151658191031, 0.187562128577232451, + 0.189068664144467574, 0.190574754814872654, 0.192080397044470941, 0.193585587290340699, + 0.195090322010624040, 0.196594597664534687, 0.198098410712366779, 0.199601757615502945, + 0.201104634836422685, 0.202607038838710785, 0.204108966087065413, 0.205610413047306761, + 0.207111376186385004, 0.208611851972388990, 0.210111836874554148, 0.211611327363271234, + 0.213110319910094159, 0.214608810987748755, 0.216106797070140716, 0.217604274632364147, + 0.219101240150709614, 0.220597690102672717, 0.222093620966962141, 0.223589029223508040, + 0.225083911353470389, 0.226578263839247090, 0.228072083164482436, 0.229565365814075190, + 0.231058108274187129, 0.232550307032250964, 0.234041958576978931, 0.235533059398370825, + 0.237023605987722402, 0.238513594837633514, 0.240003022442016545, 0.241491885296104408, + 0.242980179896459036, 0.244467902740979431, 0.245955050328910019, 0.247441619160848891, + 0.248927605738756053, 0.250413006565961438, 0.251897818147173491, 0.253382036988487103, + 0.254865659597391991, 0.256348682482780810, 0.257831102154957470, 0.259312915125645305, + 0.260794117907995282, 0.262274707016594111, 0.263754678967472622, 0.265234030278113819, + 0.266712757467461314, 0.268190857055927045, 0.269668325565399936, 0.271145159519253942, + 0.272621355442355939, 0.274096909861074489, 0.275571819303287446, 0.277046080298390507, + 0.278519689377304980, 0.279992643072486447, 0.281464937917932589, 0.282936570449191516, + 0.284407537203369531, 0.285877834719139856, 0.287347459536750394, 0.288816408198032115, + 0.290284677246406719, 0.291752263226895459, 0.293219162686126744, 0.294685372172344362, + 0.296150888235415799, 0.297615707426840237, 0.299079826299756657, 0.300543241408951833, + 0.302005949310868660, 0.303467946563614144, 0.304929229726967677, 0.306389795362388584, + 0.307849640033025007, 0.309308760303721397, 0.310767152741026786, 0.312224813913202892, + 0.313681740390232111, 0.315137928743825901, 0.316593375547432165, 0.318048077376244132, + 0.319502030807207849, 0.320955232419030512, 0.322407678792188179, 0.323859366508934376, + 0.325310292153307645, 0.326760452311139871, 0.328209843570063942, 0.329658462519522355, + 0.331106305750774710, 0.332553369856906145, 0.333999651432834943, 0.335445147075320860, + 0.336889853382973059, 0.338333766956257997, 0.339776884397507528, 0.341219202310927061, + 0.342660717302603113, 0.344101425980511633, 0.345541324954525997, 0.346980410836424835, + 0.348418680239900080, 0.349856129780564795, 0.351292756075961443, 0.352728555745569494, + 0.354163525410813806, 0.355597661695071954, 0.357030961223682830, 0.358463420623954143, + 0.359895036525170631, 0.361325805558601665, 0.362755724357509579, 0.364184789557157385, + 0.365612997794816541, 0.367040345709775062, 0.368466829943345453, 0.369892447138872649, + 0.371317193941741563, 0.372741066999385307, 0.374164062961293065, 0.375586178479017985, + 0.377007410206184779, 0.378427754798497884, 0.379847208913749346, 0.381265769211826588, + 0.382683432354720021, 0.384100195006531420, 0.385516053833481420, 0.386931005503917458, + 0.388345046688321482, 0.389758174059318063, 0.391170384291681994, 0.392581674062346175, + 0.393992040050409442, 0.395401478937144391, 0.396809987406005260, 0.398217562142635373, + 0.399624199834875571, 0.401029897172771432, 0.402434650848581432, 0.403838457556784269, + 0.405241313994087304, 0.406643216859433887, 0.408044162854010961, 0.409444148681257447, + 0.410843171046871347, 0.412241226658818016, 0.413638312227337435, 0.415034424464952367, + 0.416429560086475858, 0.417823715809019058, 0.419216888351998773, 0.420609074437145514, + 0.422000270788510934, 0.423390474132475658, 0.424779681197756886, 0.426167888715416221, + 0.427555093418867271, 0.428941292043883371, 0.430326481328605293, 0.431710658013548743, + 0.433093818841612410, 0.434475960558085184, 0.435857079910654088, 0.437237173649411892, + 0.438616238526864710, 0.439994271297939721, 0.441371268719992604, 0.442747227552815481, + 0.444122144558644349, 0.445496016502166581, 0.446868840150528801, 0.448240612273344385, + 0.449611329642701119, 0.450980989033168467, 0.452349587221805627, 0.453717120988168909, + 0.455083587114319177, 0.456448982384829671, 0.457813303586793507, 0.459176547509831057, + 0.460538710946097607, 0.461899790690291134, 0.463259783539659464, 0.464618686294008099, + 0.465976495755707487, 0.467333208729700911, 0.468688822023511642, 0.470043332447250717, + 0.471396736813624151, 0.472749031937940822, 0.474100214638119688, 0.475450281734697222, + 0.476799230050835243, 0.478147056412328075, 0.479493757647610042, 0.480839330587763070, + 0.482183772066524075, 0.483527078920292286, 0.484869247988137075, 0.486210276111804784, + 0.487550160135726884, 0.488888896907026804, 0.490226483275527480, 0.491562916093759128, + 0.492898192216966236, 0.494232308503114892, 0.495565261812900837, 0.496897049009756120, + 0.498227666959856708, 0.499557112532130199, 0.500885382598262541, 0.502212474032706191, + 0.503538383712686777, 0.504863108518210479, 0.506186645332072249, 0.507508991039861801, + 0.508830142529972052, 0.510150096693606003, 0.511468850424783961, 0.512786400620350968, + 0.514102744179984250, 0.515417878006200092, 0.516731799004361725, 0.518044504082686097, + 0.519355990152251090, 0.520666254127003736, 0.521975292923766099, 0.523283103462243382, + 0.524589682665031143, 0.525895027457622288, 0.527199134768414512, 0.528502001528717291, + 0.529803624672759210, 0.531104001137695403, 0.532403127863614323, 0.533701001793545293, + 0.534997619873465724, 0.536292979052307994, 0.537587076281966558, 0.538879908517306050, + 0.540171472716167056, 0.541461765839374332, 0.542750784850743573, 0.544038526717088300, + 0.545324988408227851, 0.546610166896993488, 0.547894059159235947, 0.549176662173832764, + 0.550457972922695271, 0.551737988390775369, 0.553016705566073186, 0.554294121439643406, + 0.555570233005603376, 0.556845037261139209, 0.558118531206513335, 0.559390711845071387, + 0.560661576183249744, 0.561931121230581421, 0.563199343999704616, 0.564466241506368482, + 0.565731810769441013, 0.566996048810915254, 0.568258952655917082, 0.569520519332711750, + 0.570780745872710993, 0.572039629310480024, 0.573297166683744530, 0.574553355033397550, + 0.575808191403506697, 0.577061672841320705, 0.578313796397276425, 0.579564559125006595, + 0.580813958081345505, 0.582061990326336542, 0.583308652923239634, 0.584553942938537019, + 0.585797857441941017, 0.587040393506400804, 0.588281548208108740, 0.589521318626508140, + 0.590759701844299490, 0.591996694947447222, 0.593232295025187262, 0.594466499170033247, + 0.595699304477783409, 0.596930708047528125, 0.598160706981655577, 0.599389298385859526, + 0.600616479369145750, 0.601842247043838818, 0.603066598525589082, 0.604289530933379115, + 0.605511041389530824, 0.606731127019712324, 0.607949784952944050, 0.609167012321606194, + 0.610382806261445254, 0.611597163911580588, 0.612810082414511403, 0.614021558916123311, + 0.615231590565694986, 0.616440174515905159, 0.617647307922838951, 0.618852987945994859, + 0.620057211748291537, 0.621259976496073785, 0.622461279359120101, 0.623661117510648788, + 0.624859488127324725, 0.626056388389266250, 0.627251815480051267, 0.628445766586724464, + 0.629638238899803415, 0.630829229613285802, 0.632018735924655184, 0.633206755034888435, + 0.634393284148461856, 0.635578320473357716, 0.636761861221071257, 0.637943903606616569, + 0.639124444848533924, 0.640303482168895655, 0.641481012793313043, 0.642657033950942758, + 0.643831542874493512, 0.645004536800232176, 0.646176012967990987, 0.647345968621173218, + 0.648514401006760277, 0.649681307375317707, 0.650846684981002288, 0.652010531081567923, + 0.653172842938372300, 0.654333617816383217, 0.655492852984185581, 0.656650545713986733, + 0.657806693281623889, 0.658961292966570356, 0.660114342051941305, 0.661265837824501101, + 0.662415777574668740, 0.663564158596525067, 0.664710978187818435, 0.665856233649971818, + 0.666999922288088243, 0.668142041410958010, 0.669282588331064354, 0.670421560364590441, + 0.671558954831424915, 0.672694769055168673, 0.673829000363141195, 0.674961646086386646, + 0.676092703559680208, 0.677222170121534517, 0.678350043114205437, 0.679476319883698943, + 0.680600997779777117, 0.681724074155964144, 0.682845546369552858, 0.683965411781610744, + 0.685083667756986370, 0.686200311664315388, 0.687315340876026859, 0.688428752768349250, + 0.689540544721316873, 0.690650714118775988, 0.691759258348390471, 0.692866174801649026, + 0.693971460873869961, 0.695075113964208735, 0.696177131475662736, 0.697277510815078383, + 0.698376249393157011, 0.699473344624460314, 0.700568793927417333, 0.701662594724330124, + 0.702754744441379642, 0.703845240508632175, 0.704934080360045123, 0.706021261433473102, + 0.707106781170674159, 0.708190637017315439, 0.709272826422979286, 0.710353346841169575, + 0.711432195729317485, 0.712509370548787269, 0.713584868764882696, 0.714658687846852381, + 0.715730825267896331, 0.716801278505171613, 0.717870045039798454, 0.718937122356865910, + 0.720002507945437964, 0.721066199298559418, 0.722128193913261773, 0.723188489290569114, + 0.724247082935504105, 0.725303972357093540, 0.726359155068374340, 0.727412628586400101, + 0.728464390432245423, 0.729514438131013354, 0.730562769211840157, 0.731609381207901532, + 0.732654271656418277, 0.733697438098662391, 0.734738878079962410, 0.735778589149709283, + 0.736816568861362708, 0.737852814772456012, 0.738887324444602478, 0.739920095443501014, + 0.740951125338941474, 0.741980411704811216, 0.743007952119099757, 0.744033744163905331, + 0.745057785425440100, 0.746080073494036267, 0.747100605964150954, 0.748119380434373094, + 0.749136394507427417, 0.750151645790182009, 0.751165131893652416, 0.752176850433007749, + 0.753186799027576792, 0.754194975300852777, 0.755201376880499708, 0.756206001398357364, + 0.757208846490447174, 0.758209909796977888, 0.759209188962350789, 0.760206681635165360, + 0.761202385468225273, 0.762196298118542837, 0.763188417247345763, 0.764178740520082056, + 0.765167265606425118, 0.766153990180280187, 0.767138911919788891, 0.768122028507335242, + 0.769103337629551076, 0.770082836977321050, 0.771060524245788526, 0.772036397134361230, + 0.773010453346715698, 0.773982690590803823, 0.774953106578857298, 0.775921699027393386, + 0.776888465657220917, 0.777853404193444398, 0.778816512365470004, 0.779777787907011688, + 0.780737228556094953, 0.781694832055063182, 0.782650596150582967, 0.783604518593649102, + 0.784556597139589806, 0.785506829548072494, 0.786455213583108326, 0.787401747013058095, + 0.788346427610637446, 0.789289253152921200, 0.790230221421350243, 0.791169330201735188, + 0.792106577284262259, 0.793041960463498619, 0.793975477538397367, 0.794907126312302537, + 0.795836904592954530, 0.796764810192495343, 0.797690840927473555, 0.798614994618849217, + 0.799537269091999514, 0.800457662176723428, 0.801376171707247176, 0.802292795522229207, + 0.803207531464765090, 0.804120377382392726, 0.805031331127097571, 0.805940390555317410, + 0.806847553527947570, 0.807752817910346033, 0.808656181572338206, 0.809557642388222143, + 0.810457198236773424, 0.811354847001250379, 0.812250586569398636, 0.813144414833456564, + 0.814036329690159821, 0.814926329040746578, 0.815814410790962508, 0.816700572851065343, + 0.817584813135830202, 0.818467129564554363, 0.819347520061061929, 0.820225982553709043, + 0.821102514975388553, 0.821977115263535230, 0.822849781360129873, 0.823720511211704975, + 0.824589302769349053, 0.825456153988711638, 0.826321062830008057, 0.827184027258024202, + 0.828045045242121636, 0.828904114756241706, 0.829761233778910978, 0.830616400293245349, + 0.831469612286955706, 0.832320867752351701, 0.833170164686346748, 0.834017501090463576, + 0.834862874970837443, 0.835706284338222027, 0.836547727207993752, 0.837387201600156006, + 0.838224705539344694, 0.839060237054832125, 0.839893794180531672, 0.840725374955003213, + 0.841554977421456685, 0.842382599627757522, 0.843208239626430545, 0.844031895474665173, + 0.844853565234319537, 0.845673246971925363, 0.846490938758692413, 0.847306638670512924, + 0.848120344787966163, 0.848932055196323088, 0.849741767985550456, 0.850549481250316264, + 0.851355193089992968, 0.852158901608662700, 0.852960604915121823, 0.853760301122884924, + 0.854557988350189590, 0.855353664720000739, 0.856147328360015059, 0.856938977402665336, + 0.857728609985124901, 0.858516224249311843, 0.859301818341893897, 0.860085390414292217, + 0.860866938622686151, 0.861646461128017127, 0.862423956095993427, 0.863199421697094182, + 0.863972856106574150, 0.864744257504467262, 0.865513624075591625, 0.866280954009553406, + 0.867046245500750934, 0.867809496748379705, 0.868570705956435596, 0.869329871333719972, + 0.870086991093843243, 0.870842063455229409, 0.871595086641120398, 0.872346058879579944, + 0.873094978403497701, 0.873841843450593792, 0.874586652263422581, 0.875329403089376790, + 0.876070094180692371, 0.876808723794451517, 0.877545290192587202, 0.878279791641887631, + 0.879012226414000009, 0.879742592785434541, 0.880470889037568538, 0.881197113456650749, + 0.881921264333804689, 0.882643339965033635, 0.883363338651223740, 0.884081258698148575, + 0.884797098416473027, 0.885510856121756951, 0.886222530134459618, 0.886932118779943157, + 0.887639620388477213, 0.888345033295241948, 0.889048355840332816, 0.889749586368763778, + 0.890448723230471750, 0.891145764780319927, 0.891840709378102670, 0.892533555388547839, + 0.893224301181322011, 0.893912945131033587, 0.894599485617236789, 0.895283921024435547, + 0.895966249742087273, 0.896646470164606524, 0.897324580691369000, 0.898000579726715098, + 0.898674465679953793, 0.899346236965366308, 0.900015892002209994, 0.900683429214721887, + 0.901348847032122258, 0.902012143888618834, 0.902673318223410126, 0.903332368480688985, + 0.903989293109646375, 0.904644090564475367, 0.905296759304374143, 0.905947297793550210, + 0.906595704501223620, 0.907241977901630858, 0.907886116474028060, 0.908528118702695009, + 0.909167983076938357, 0.909805708091095511, 0.910441292244537959, 0.911074734041674716, + 0.911706031991956101, 0.912335184609876837, 0.912962190414980279, 0.913587047931861296, + 0.914209755690169490, 0.914830312224613529, 0.915448716074963920, 0.916064965786056562, + 0.916679059907796634, 0.917290996995161034, 0.917900775608202935, 0.918508394312054111, + 0.919113851676929272, 0.919717146278128617, 0.920318276696041826, 0.920917241516150842, + 0.921514039329033530, 0.922108668730367120, 0.922701128320931097, 0.923291416706610857, + 0.923879532498400824, 0.924465474312407776, 0.925049240769853953, 0.925630830497080392, + 0.926210242125550476, 0.926787474291852487, 0.927362525637703605, 0.927935394809952352, + 0.928506080460582250, 0.929074581246714604, 0.929640895830612490, 0.930205022879682875, + 0.930766961066480270, 0.931326709068709957, 0.931884265569230541, 0.932439629256058056, + 0.932992798822367853, 0.933543772966498708, 0.934092550391955045, 0.934639129807410707, + 0.935183509926711398, 0.935725689468878352, 0.936265667158110548, 0.936803441723788266, + 0.937339011900476193, 0.937872376427925758, 0.938403534051079014, 0.938932483520070416, + 0.939459223590231041, 0.939983753022090474, 0.940506070581380249, 0.941026175039036850, + 0.941544065171204148, 0.942059739759236736, 0.942573197589702372, 0.943084437454385305, + 0.943593458150288611, 0.944100258479637411, 0.944604837249881868, 0.945107193273698964, + 0.945607325368996832, 0.946105232358916082, 0.946600913071833583, 0.947094366341364791, + 0.947585591006366412, 0.948074585910939294, 0.948561349904431306, 0.949045881841439676, + 0.949528180581814096, 0.950008244990658834, 0.950486073938336173, 0.950961666300468300, + 0.951435020957940414, 0.951906136796903390, 0.952375012708776225, 0.952841647590248364, + 0.953306040343283034, 0.953768189875119243, 0.954228095098274331, 0.954685754930546970, + 0.955141168295019494, 0.955594334120060118, 0.956045251339325941, 0.956493918891765160, + 0.956940335721619739, 0.957384500778427627, 0.957826413017025757, 0.958266071397551711, + 0.958703474885446938, 0.959138622451458756, 0.959571513071643012, 0.960002145727366307, + 0.960430519405308214, 0.960856633097464052, 0.961280485801147333, 0.961702076518991644, + 0.962121404258953317, 0.962538468034313643, 0.962953266863681323, 0.963365799770994458, + 0.963776065785523439, 0.964184063941872727, 0.964589793279983176, 0.964993252845134486, + 0.965394441687947302, 0.965793358864385554, 0.966190003435758560, 0.966584374468723362, + 0.966976471035286833, 0.967366292212807788, 0.967753837083999424, 0.968139104736931211, + 0.968522094265031219, 0.968902804767088011, 0.969281235347252967, 0.969657385115042403, + 0.970031253185339559, 0.970402838678396829, 0.970772140719837529, 0.971139158440658457, + 0.971503890977231443, 0.971866337471305353, 0.972226497070008855, 0.972584368925851539, + 0.972939952196726243, 0.973293246045911387, 0.973644249642072190, 0.973992962159263453, + 0.974339382776930885, 0.974683510679913323, 0.975025345058444626, 0.975364885108155333, + 0.975702130030074888, 0.976037079030633636, 0.976369731321664158, 0.976700086120403377, + 0.977028142649494558, 0.977353900136989084, 0.977677357816347903, 0.977998514926444185, + 0.978317370711563994, 0.978633924421408952, 0.978948175311097568, 0.979260122641167130, + 0.979569765677575477, 0.979877103691702667, 0.980182135960352530, 0.980484861765754889, + 0.980785280395566450, 0.981083391142873240, 0.981379193306191944, 0.981672686189471455, + 0.981963869102094655, 0.982252741358879966, 0.982539302280083238, 0.982823551191398748, + 0.983105487423961533, 0.983385110314348165, 0.983662419204579197, 0.983937413442119935, + 0.984210092379882440, 0.984480455376226748, 0.984748501794962539, 0.985014231005350904, + 0.985277642382105134, 0.985538735305392932, 0.985797509160837526, 0.986053963339518891, + 0.986308097237975523, 0.986559910258205885, 0.986809401807669628, 0.987056571299289143, + 0.987301418151450561, 0.987543941788005641, 0.987784141638272883, 0.988022017137038855, + 0.988257567724559305, 0.988490792846561273, 0.988721691954243309, 0.988950264504277698, + 0.989176509958810901, 0.989400427785465664, 0.989622017457341574, 0.989841278453016948, + 0.990058210256549387, 0.990272812357477328, 0.990485084250821379, 0.990695025437085319, + 0.990902635422257094, 0.991107913717810374, 0.991310859840705660, 0.991511473313391067, + 0.991709753663803650, 0.991905700425370629, 0.992099313137010275, 0.992290591343133355, + 0.992479534593643575, 0.992666142443939248, 0.992850414454914176, 0.993032350192958546, + 0.993211949229959812, 0.993389211143304252, 0.993564135515877411, 0.993736721936065215, + 0.993906969997755407, 0.994074879300337666, 0.994240449448705155, 0.994403680053255523, + 0.994564570729891129, 0.994723121100020924, 0.994879330790560346, 0.995033199433933091, + 0.995184726668071340, 0.995333912136416754, 0.995480755487921587, 0.995625256377049239, + 0.995767414463775147, 0.995907229413587669, 0.996044700897488755, 0.996179828591994498, + 0.996312612179136692, 0.996443051346462494, 0.996571145787035984, 0.996696895199438604, + 0.996820299287769940, 0.996941357761648050, 0.997060070336210802, 0.997176436732115978, + 0.997290456675542281, 0.997402129898189660, 0.997511456137280206, 0.997618435135558923, + 0.997723066641293732, 0.997825350408276579, 0.997925286195823991, 0.998022873768777408, + 0.998118112897503629, 0.998211003357896032, 0.998301544931374352, 0.998389737404885347, + 0.998475580570903798, 0.998559074227432397, 0.998640218178002415, 0.998719012231674363, + 0.998795456203038223, 0.998869549912213994, 0.998941293184852031, 0.999010685852133262, + 0.999077727750770306, 0.999142418723007020, 0.999204758616619171, 0.999264747284915100, + 0.999322384586735724, 0.999377670386454753, 0.999430604553979474, 0.999481186964750634, + 0.999529417499742889, 0.999575296045465134, 0.999618822493960835, 0.999659996742808032, + 0.999698818695119673, 0.999735288259543831, 0.999769405350264373, 0.999801169887000296, + 0.999830581795006723, 0.999857641005074460, 0.999882347453530551, 0.999904701082238501, + 0.999924701838597940, 0.999942349675545072, 0.999957644551553115, 0.999970586430631414, + 0.999981175282326773, 0.999989411081722346, 0.999995293809438746, 0.999998823451633156, + 1.000000000000000000, +}; + +const float dsp_sine_float4_8192[2049] = { + 0.000000000000000000, 0.000766990318720782, 0.001533980186240921, 0.002300969151360039, + 0.003067956762878288, 0.003834942569596618, 0.004601926120317039, 0.005368906963842891, + 0.006135884648979102, 0.006902858724532461, 0.007669828739311883, 0.008436794242128665, + 0.009203754781796764, 0.009970709907133056, 0.010737659166957599, 0.011504602110093904, + 0.012271538285369197, 0.013038467241614688, 0.013805388527665828, 0.014572301692362588, + 0.015339206284549710, 0.016106101853076982, 0.016872987946799495, 0.017639864114577925, + 0.018406729905278779, 0.019173584867774669, 0.019940428550944574, 0.020707260503674121, + 0.021474080274855829, 0.022240887413389376, 0.023007681468181884, 0.023774461988148161, + 0.024541228522210991, 0.025307980619301371, 0.026074717828358799, 0.026841439698331530, + 0.027608145778176843, 0.028374835616861306, 0.029141508763361038, 0.029908164766661978, + 0.030674803175760153, 0.031441423539661943, 0.032208025407384336, 0.032974608327955200, + 0.033741171850413559, 0.034507715523809844, 0.035274238897206163, 0.036040741519676553, + 0.036807222940307284, 0.037573682708197075, 0.038340120372457390, 0.039106535482212712, + 0.039872927586600763, 0.040639296234772825, 0.041405640975893956, 0.042171961359143299, + 0.042938256933714315, 0.043704527248815059, 0.044470771853668441, 0.045236990297512512, + 0.046003182129600695, 0.046769346899202077, 0.047535484155601666, 0.048301593448100658, + 0.049067674326016684, 0.049833726338684110, 0.050599749035454271, 0.051365741965695752, + 0.052131704678794639, 0.052897636724154810, 0.053663537651198183, 0.054429407009364966, + 0.055195244348113945, 0.055961049216922763, 0.056726821165288127, 0.057492559742726129, + 0.058258264498772507, 0.059023934982982869, 0.059789570744933004, 0.060555171334219116, + 0.061320736300458104, 0.062086265193287825, 0.062851757562367355, 0.063617212957377239, + 0.064382630928019824, 0.065148011024019403, 0.065913352795122615, 0.066678655791098579, + 0.067443919561739299, 0.068209143656859789, 0.068974327626298446, 0.069739471019917246, + 0.070504573387602049, 0.071269634279262820, 0.072034653244833990, 0.072799629834274585, + 0.073564563597568591, 0.074329454084725202, 0.075094300845779005, 0.075859103430790414, + 0.076623861389845713, 0.077388574273057564, 0.078153241630565015, 0.078917863012534006, + 0.079682437969157457, 0.080446966050655641, 0.081211446807276363, 0.081975879789295297, + 0.082740264547016218, 0.083504600630771267, 0.084268887590921202, 0.085033124977855729, + 0.085797312341993670, 0.086561449233783269, 0.087325535203702495, 0.088089569802259252, + 0.088853552579991696, 0.089617483087468391, 0.090381360875288752, 0.091145185494083139, + 0.091908956494513208, 0.092672673427272145, 0.093436335843084986, 0.094199943292708768, + 0.094963495326932934, 0.095726991496579483, 0.096490431352503292, 0.097253814445592349, + 0.098017140326768074, 0.098780408546985513, 0.099543618657233601, 0.100306770208535553, + 0.101069862751948916, 0.101832895838566057, 0.102595869019514216, 0.103358781845955983, + 0.104121633869089361, 0.104884424640148188, 0.105647153710402286, 0.106409820631157795, + 0.107172424953757423, 0.107934966229580695, 0.108697444010044206, 0.109459857846601949, + 0.110222207290745500, 0.110984491894004320, 0.111746711207946020, 0.112508864784176585, + 0.113270952174340758, 0.114032972930122115, 0.114794926603243502, 0.115556812745467197, + 0.116318630908595219, 0.117080380644469559, 0.117842061504972492, 0.118603673042026764, + 0.119365214807595960, 0.120126686353684647, 0.120888087232338778, 0.121649416995645798, + 0.122410675195735036, 0.123171861384777898, 0.123932975114988159, 0.124694015938622227, + 0.125454983407979420, 0.126215877075402133, 0.126976696493276253, 0.127737441214031300, + 0.128498110790140785, 0.129258704774122379, 0.130019222718538219, 0.130779664175995208, + 0.131540028699145273, 0.132300315840685467, 0.133060525153358533, 0.133820656189952841, + 0.134580708503303004, 0.135340681646289707, 0.136100575171840377, 0.136860388632929236, + 0.137620121582577609, 0.138379773573854142, 0.139139344159875167, 0.139898832893804920, + 0.140658239328855655, 0.141417563018288200, 0.142176803515411954, 0.142935960373585330, + 0.143695033146215873, 0.144454021386760639, 0.145212924648726399, 0.145971742485669936, + 0.146730474451198245, 0.147489120098968862, 0.148247678982690145, 0.149006150656121383, + 0.149764534673073241, 0.150522830587407952, 0.151281037953039599, 0.152039156323934277, + 0.152797185254110485, 0.153555124297639345, 0.154312973008644883, 0.155070730941304163, + 0.155828397649847739, 0.156585972688559810, 0.157343455611778565, 0.158100845973896204, + 0.158858143329359519, 0.159615347232670068, 0.160372457238384197, 0.161129472901113679, + 0.161886393775525633, 0.162643219416343077, 0.163399949378344955, 0.164156583216366503, + 0.164913120485299547, 0.165669560740092758, 0.166425903535751735, 0.167182148427339555, + 0.167938294969976781, 0.168694342718841983, 0.169450291229171629, 0.170206140056260752, + 0.170961888755462976, 0.171717536882190769, 0.172473083991915799, 0.173228529640169215, + 0.173983873382541815, 0.174739114774684290, 0.175494253372307590, 0.176249288731183146, + 0.177004220407143142, 0.177759047956080662, 0.178513770933950128, 0.179268388896767494, + 0.180022901400610419, 0.180777308001618647, 0.181531608255994209, 0.182285801720001667, + 0.183039887949968533, 0.183793866502285214, 0.184547736933405565, 0.185301498799847086, + 0.186055151658191031, 0.186808695065082880, 0.187562128577232451, 0.188315451751414231, + 0.189068664144467574, 0.189821765313297058, 0.190574754814872654, 0.191327632206230086, + 0.192080397044470941, 0.192833048886763031, 0.193585587290340699, 0.194338011812505040, + 0.195090322010624040, 0.195842517442132963, 0.196594597664534687, 0.197346562235399758, + 0.198098410712366779, 0.198850142653142686, 0.199601757615502945, 0.200353255157291826, + 0.201104634836422685, 0.201855896210878238, 0.202607038838710785, 0.203358062278042401, + 0.204108966087065413, 0.204859749824042425, 0.205610413047306761, 0.206360955315262495, + 0.207111376186385004, 0.207861675219221054, 0.208611851972388990, 0.209361906004579185, + 0.210111836874554148, 0.210861644141148968, 0.211611327363271234, 0.212360886099901669, + 0.213110319910094159, 0.213859628352976172, 0.214608810987748755, 0.215357867373687145, + 0.216106797070140716, 0.216855599636533503, 0.217604274632364147, 0.218352821617206483, + 0.219101240150709614, 0.219849529792598197, 0.220597690102672717, 0.221345720640809707, + 0.222093620966962141, 0.222841390641159459, 0.223589029223508040, 0.224336536274191395, + 0.225083911353470389, 0.225831154021683495, 0.226578263839247090, 0.227325240366655745, + 0.228072083164482436, 0.228818791793378717, 0.229565365814075190, 0.230311804787381585, + 0.231058108274187129, 0.231804275835460621, 0.232550307032250964, 0.233296201425687216, + 0.234041958576978931, 0.234787578047416373, 0.235533059398370825, 0.236278402191294840, + 0.237023605987722402, 0.237768670349269351, 0.238513594837633514, 0.239258379014595068, + 0.240003022442016545, 0.240747524681843517, 0.241491885296104408, 0.242236103846911133, + 0.242980179896459036, 0.243724113007027343, 0.244467902740979431, 0.245211548660762890, + 0.245955050328910019, 0.246698407308037937, 0.247441619160848891, 0.248184685450130532, + 0.248927605738756053, 0.249670379589684577, 0.250413006565961438, 0.251155486230718261, + 0.251897818147173491, 0.252640001878632281, 0.253382036988487103, 0.254123923040217803, + 0.254865659597391991, 0.255607246223665041, 0.256348682482780810, 0.257089967938571362, + 0.257831102154957470, 0.258572084695949111, 0.259312915125645305, 0.260053593008234607, + 0.260794117907995282, 0.261534489389295577, 0.262274707016594111, 0.263014770354439875, + 0.263754678967472622, 0.264494432420423253, 0.265234030278113819, 0.265973472105458075, + 0.266712757467461314, 0.267451885929221034, 0.268190857055927045, 0.268929670412861643, + 0.269668325565399936, 0.270406822079010178, 0.271145159519253942, 0.271883337451786167, + 0.272621355442355939, 0.273359213056806216, 0.274096909861074489, 0.274834445421192619, + 0.275571819303287446, 0.276309031073580957, 0.277046080298390507, 0.277782966544128873, + 0.278519689377304980, 0.279256248364523729, 0.279992643072486447, 0.280728873067991158, + 0.281464937917932589, 0.282200837189302944, 0.282936570449191516, 0.283672137264785296, + 0.284407537203369531, 0.285142769832327170, 0.285877834719139856, 0.286612731431387879, + 0.287347459536750394, 0.288082018603005863, 0.288816408198032115, 0.289550627889806511, + 0.290284677246406719, 0.291018555836010329, 0.291752263226895459, 0.292485798987440981, + 0.293219162686126744, 0.293952353891533680, 0.294685372172344362, 0.295418217097343005, + 0.296150888235415799, 0.296883385155551294, 0.297615707426840237, 0.298347854618476516, + 0.299079826299756657, 0.299811622040080605, 0.300543241408951833, 0.301274683975977398, + 0.302005949310868660, 0.302737036983440955, 0.303467946563614144, 0.304198677621413172, + 0.304929229726967677, 0.305659602450512602, 0.306389795362388584, 0.307119808033041952, + 0.307849640033025007, 0.308579290932996464, 0.309308760303721397, 0.310038047716071852, + 0.310767152741026786, 0.311496074949672463, 0.312224813913202892, 0.312953369202919551, + 0.313681740390232111, 0.314409927046658766, 0.315137928743825901, 0.315865745053468872, + 0.316593375547432165, 0.317320819797669462, 0.318048077376244132, 0.318775147855329233, + 0.319502030807207849, 0.320228725804273584, 0.320955232419030512, 0.321681550224093338, + 0.322407678792188179, 0.323133617696152231, 0.323859366508934376, 0.324584924803595298, + 0.325310292153307645, 0.326035468131356643, 0.326760452311139871, 0.327485244266167708, + 0.328209843570063942, 0.328934249796565326, 0.329658462519522355, 0.330382481312899379, + 0.331106305750774710, 0.331829935407341237, 0.332553369856906145, 0.333276608673891583, + 0.333999651432834943, 0.334722497708388633, 0.335445147075320860, 0.336167599108515625, + 0.336889853382973059, 0.337611909473809479, 0.338333766956257997, 0.339055425405668354, + 0.339776884397507528, 0.340498143507359852, 0.341219202310927061, 0.341940060384028910, + 0.342660717302603113, 0.343381172642705790, 0.344101425980511633, 0.344821476892314183, + 0.345541324954525997, 0.346260969743679092, 0.346980410836424835, 0.347699647809534718, + 0.348418680239900080, 0.349137507704532613, 0.349856129780564795, 0.350574546045249680, + 0.351292756075961443, 0.352010759450195720, 0.352728555745569494, 0.353446144539821927, + 0.354163525410813806, 0.354880697936528489, 0.355597661695071954, 0.356314416264672806, + 0.357030961223682830, 0.357747296150577099, 0.358463420623954143, 0.359179334222536506, + 0.359895036525170631, 0.360610527110827195, 0.361325805558601665, 0.362040871447714130, + 0.362755724357509579, 0.363470363867458734, 0.364184789557157385, 0.364899001006327384, + 0.365612997794816541, 0.366326779502598843, 0.367040345709775062, 0.367753695996572483, + 0.368466829943345453, 0.369179747130575830, 0.369892447138872649, 0.370604929548972895, + 0.371317193941741563, 0.372029239898171771, 0.372741066999385307, 0.373452674826632580, + 0.374164062961293065, 0.374875230984875518, 0.375586178479017985, 0.376296905025488404, + 0.377007410206184779, 0.377717693603135118, 0.378427754798497884, 0.379137593374562598, + 0.379847208913749346, 0.380556600998609718, 0.381265769211826588, 0.381974713136214450, + 0.382683432354720021, 0.383391926450421971, 0.384100195006531420, 0.384808237606392323, + 0.385516053833481420, 0.386223643271408679, 0.386931005503917458, 0.387638140114884677, + 0.388345046688321482, 0.389051724808372801, 0.389758174059318063, 0.390464394025571482, + 0.391170384291681994, 0.391876144442333707, 0.392581674062346175, 0.393286972736674401, + 0.393992040050409442, 0.394696875588778306, 0.395401478937144391, 0.396105849681007760, + 0.396809987406005260, 0.397513891697910682, 0.398217562142635373, 0.398920998326228182, + 0.399624199834875571, 0.400327166254902389, 0.401029897172771432, 0.401732392175084385, + 0.402434650848581432, 0.403136672780141814, 0.403838457556784269, 0.404540004765666816, + 0.405241313994087304, 0.405942384829483638, 0.406643216859433887, 0.407343809671656509, + 0.408044162854010961, 0.408744275994497419, 0.409444148681257447, 0.410143780502573885, + 0.410843171046871347, 0.411542319902716502, 0.412241226658818016, 0.412939890904027052, + 0.413638312227337435, 0.414336490217885878, 0.415034424464952367, 0.415732114557960053, + 0.416429560086475858, 0.417126760640210537, 0.417823715809019058, 0.418520425182900446, + 0.419216888351998773, 0.419913104906602552, 0.420609074437145514, 0.421304796534206771, + 0.422000270788510934, 0.422695496790928438, 0.423390474132475658, 0.424085202404315353, + 0.424779681197756886, 0.425473910104256170, 0.426167888715416221, 0.426861616622987328, + 0.427555093418867271, 0.428248318695101493, 0.428941292043883371, 0.429634013057554609, + 0.430326481328605293, 0.431018696449674110, 0.431710658013548743, 0.432402365613166140, + 0.433093818841612410, 0.433785017292123487, 0.434475960558085184, 0.435166648233033249, + 0.435857079910654088, 0.436547255184784433, 0.437237173649411892, 0.437926834898675288, + 0.438616238526864710, 0.439305384128421683, 0.439994271297939721, 0.440682899630164104, + 0.441371268719992604, 0.442059378162475425, 0.442747227552815481, 0.443434816486368732, + 0.444122144558644349, 0.444809211365304824, 0.445496016502166581, 0.446182559565199754, + 0.446868840150528801, 0.447554857854432553, 0.448240612273344385, 0.448926103003852772, + 0.449611329642701119, 0.450296291786788150, 0.450980989033168467, 0.451665420979052157, + 0.452349587221805627, 0.453033487358951492, 0.453717120988168909, 0.454400487707293799, + 0.455083587114319177, 0.455766418807395213, 0.456448982384829671, 0.457131277445088025, + 0.457813303586793507, 0.458495060408727839, 0.459176547509831057, 0.459857764489201737, + 0.460538710946097607, 0.461219386479935378, 0.461899790690291134, 0.462579923176900665, + 0.463259783539659464, 0.463939371378623289, 0.464618686294008099, 0.465297727886190338, + 0.465976495755707487, 0.466654989503257844, 0.467333208729700911, 0.468011153036057892, + 0.468688822023511642, 0.469366215293406885, 0.470043332447250717, 0.470720173086712379, + 0.471396736813624151, 0.472073023229980904, 0.472749031937940822, 0.473424762539825350, + 0.474100214638119688, 0.474775387835472573, 0.475450281734697222, 0.476124895938770831, + 0.476799230050835243, 0.477473283674197169, 0.478147056412328075, 0.478820547868864965, + 0.479493757647610042, 0.480166685352531430, 0.480839330587763070, 0.481511692957605097, + 0.482183772066524075, 0.482855567519153039, 0.483527078920292286, 0.484198305874908752, + 0.484869247988137075, 0.485539904865279148, 0.486210276111804784, 0.486880361333351996, + 0.487550160135726884, 0.488219672124904025, 0.488888896907026804, 0.489557834088407473, + 0.490226483275527480, 0.490894844075037862, 0.491562916093759128, 0.492230698938681765, + 0.492898192216966236, 0.493565395535943363, 0.494232308503114892, 0.494898930726152930, + 0.495565261812900837, 0.496231301371373223, 0.496897049009756120, 0.497562504336407307, + 0.498227666959856708, 0.498892536488806215, 0.499557112532130199, 0.500221394698875721, + 0.500885382598262541, 0.501549075839684000, 0.502212474032706191, 0.502875576787069289, + 0.503538383712686777, 0.504200894419646550, 0.504863108518210479, 0.505525025618815294, + 0.506186645332072249, 0.506847967268767241, 0.507508991039861801, 0.508169716256492543, + 0.508830142529972052, 0.509490269471788437, 0.510150096693606003, 0.510809623807265467, + 0.511468850424783961, 0.512127776158355474, 0.512786400620350968, 0.513444723423318705, + 0.514102744179984250, 0.514760462503251026, 0.515417878006200092, 0.516074990302091141, + 0.516731799004361725, 0.517388303726628251, 0.518044504082686097, 0.518700399686509050, + 0.519355990152251090, 0.520011275094245051, 0.520666254127003736, 0.521320926865219803, + 0.521975292923766099, 0.522629351917695884, 0.523283103462243382, 0.523936547172823119, + 0.524589682665031143, 0.525242509554644688, 0.525895027457622288, 0.526547235990104778, + 0.527199134768414512, 0.527850723409056366, 0.528502001528717291, 0.529152968744267427, + 0.529803624672759210, 0.530453968931428821, 0.531104001137695403, 0.531753720909161731, + 0.532403127863614323, 0.533052221619023880, 0.533701001793545293, 0.534349468005517969, + 0.534997619873465724, 0.535645457016097781, 0.536292979052307994, 0.536940185601175846, + 0.537587076281966558, 0.538233650714130984, 0.538879908517306050, 0.539525849311314865, + 0.540171472716167056, 0.540816778352059102, 0.541461765839374332, 0.542106434798683146, + 0.542750784850743573, 0.543394815616500826, 0.544038526717088300, 0.544681917773827462, + 0.545324988408227851, 0.545967738241987632, 0.546610166896993488, 0.547252273995321170, + 0.547894059159235947, 0.548535522011191823, 0.549176662173832764, 0.549817479269992693, + 0.550457972922695271, 0.551098142755154674, 0.551737988390775369, 0.552377509453152893, + 0.553016705566073186, 0.553655576353513812, 0.554294121439643406, 0.554932340448822559, + 0.555570233005603376, 0.556207798734730141, 0.556845037261139209, 0.557481948209959666, + 0.558118531206513335, 0.558754785876314664, 0.559390711845071387, 0.560026308738684864, + 0.560661576183249744, 0.561296513805054298, 0.561931121230581421, 0.562565398086507740, + 0.563199343999704616, 0.563832958597237921, 0.564466241506368482, 0.565099192354552415, + 0.565731810769441013, 0.566364096378881077, 0.566996048810915254, 0.567627667693782367, + 0.568258952655917082, 0.568889903325950907, 0.569520519332711750, 0.570150800305224470, + 0.570780745872710993, 0.571410355664590530, 0.572039629310480024, 0.572668566440193816, + 0.573297166683744530, 0.573925429671342857, 0.574553355033397550, 0.575180942400516759, + 0.575808191403506697, 0.576435101673373085, 0.577061672841320705, 0.577687904538753849, + 0.578313796397276425, 0.578939348048692737, 0.579564559125006595, 0.580189429258422540, + 0.580813958081345505, 0.581438145226381153, 0.582061990326336542, 0.582685493014219569, + 0.583308652923239634, 0.583931469686807758, 0.584553942938537019, 0.585176072312242224, + 0.585797857441941017, 0.586419297961852992, 0.587040393506400804, 0.587661143710209832, + 0.588281548208108740, 0.588901606635129693, 0.589521318626508140, 0.590140683817683587, + 0.590759701844299490, 0.591378372342203362, 0.591996694947447222, 0.592614669296288032, + 0.593232295025187262, 0.593849571770811657, 0.594466499170033247, 0.595083076859929339, + 0.595699304477783409, 0.596315181661084548, 0.596930708047528125, 0.597545883275015677, + 0.598160706981655577, 0.598775178805762809, 0.599389298385859526, 0.600003065360674936, + 0.600616479369145750, 0.601229540050416400, 0.601842247043838818, 0.602454599988973549, + 0.603066598525589082, 0.603678242293662404, 0.604289530933379115, 0.604900464085133982, + 0.605511041389530824, 0.606121262487382739, 0.606731127019712324, 0.607340634627752007, + 0.607949784952944050, 0.608558577636941100, 0.609167012321606194, 0.609775088649012753, + 0.610382806261445254, 0.610990164801399005, 0.611597163911580588, 0.612203803234908195, + 0.612810082414511403, 0.613416001093731955, 0.614021558916123311, 0.614626755525451540, + 0.615231590565694986, 0.615836063681044821, 0.616440174515905159, 0.617043922714892945, + 0.617647307922838951, 0.618250329784786889, 0.618852987945994859, 0.619455282051934453, + 0.620057211748291537, 0.620658776680966362, 0.621259976496073785, 0.621860810839943490, + 0.622461279359120101, 0.623061381700363404, 0.623661117510648788, 0.624260486437167028, + 0.624859488127324725, 0.625458122228744862, 0.626056388389266250, 0.626654286256944415, + 0.627251815480051267, 0.627848975707075985, 0.628445766586724464, 0.629042187767919980, + 0.629638238899803415, 0.630233919631733253, 0.630829229613285802, 0.631424168494255422, + 0.632018735924655184, 0.632612931554716096, 0.633206755034888435, 0.633800206015840972, + 0.634393284148461856, 0.634985989083858393, 0.635578320473357716, 0.636170277968506448, + 0.636761861221071257, 0.637353069883038970, 0.637943903606616569, 0.638534362044232084, + 0.639124444848533924, 0.639714151672391540, 0.640303482168895655, 0.640892435991358145, + 0.641481012793313043, 0.642069212228515318, 0.642657033950942758, 0.643244477614794752, + 0.643831542874493512, 0.644418229384683405, 0.645004536800232176, 0.645590464776230166, + 0.646176012967990987, 0.646761181031051846, 0.647345968621173218, 0.647930375394339841, + 0.648514401006760277, 0.649098045114867128, 0.649681307375317707, 0.650264187444993924, + 0.650846684981002288, 0.651428799640674683, 0.652010531081567923, 0.652591878961464533, + 0.653172842938372300, 0.653753422670525275, 0.654333617816383217, 0.654913428034632483, + 0.655492852984185581, 0.656071892324181616, 0.656650545713986733, 0.657228812813194008, + 0.657806693281623889, 0.658384186779324199, 0.658961292966570356, 0.659538011503865595, + 0.660114342051941305, 0.660690284271757133, 0.661265837824501101, 0.661841002371589826, + 0.662415777574668740, 0.662990163095612650, 0.663564158596525067, 0.664137763739739317, + 0.664710978187818435, 0.665283801603555047, 0.665856233649971818, 0.666428273990321673, + 0.666999922288088243, 0.667571178206985305, 0.668142041410958010, 0.668712511564181988, + 0.669282588331064354, 0.669852271376243813, 0.670421560364590441, 0.670990454961206129, + 0.671558954831424915, 0.672127059640812874, 0.672694769055168673, 0.673262082740523460, + 0.673829000363141195, 0.674395521589518876, 0.674961646086386646, 0.675527373520708019, + 0.676092703559680208, 0.676657635870734020, 0.677222170121534517, 0.677786305979980463, + 0.678350043114205437, 0.678913381192577381, 0.679476319883698943, 0.680038858856408024, + 0.680600997779777117, 0.681162736323114637, 0.681724074155964144, 0.682285010948105120, + 0.682845546369552858, 0.683405680090558798, 0.683965411781610744, 0.684524741113432977, + 0.685083667756986370, 0.685642191383468824, 0.686200311664315388, 0.686758028271198140, + 0.687315340876026859, 0.687872249150948800, 0.688428752768349250, 0.688984851400851417, + 0.689540544721316873, 0.690095832402845555, 0.690650714118775988, 0.691205189542685394, + 0.691759258348390471, 0.692312920209946725, 0.692866174801649026, 0.693419021798032054, + 0.693971460873869961, 0.694523491704177376, 0.695075113964208735, 0.695626327329458727, + 0.696177131475662736, 0.696727526078796955, 0.697277510815078383, 0.697827085360965271, + 0.698376249393157011, 0.698925002588594468, 0.699473344624460314, 0.700021275178179025, + 0.700568793927417333, 0.701115900550083881, 0.701662594724330124, 0.702208876128549764, + 0.702754744441379642, 0.703300199341699406, 0.703845240508632175, 0.704389867621544097, + 0.704934080360045123, 0.705477878403989012, 0.706021261433473102, 0.706564229128839538, + 0.707106781170674159, 0.707648917239807718, 0.708190637017315439, 0.708731940184517351, + 0.709272826422979286, 0.709813295414511325, 0.710353346841169575, 0.710892980385255946, + 0.711432195729317485, 0.711970992556148152, 0.712509370548787269, 0.713047329390521289, + 0.713584868764882696, 0.714121988355650883, 0.714658687846852381, 0.715194966922760522, + 0.715730825267896331, 0.716266262567027967, 0.716801278505171613, 0.717335872767591143, + 0.717870045039798454, 0.718403795007553803, 0.718937122356865910, 0.719470026773991966, + 0.720002507945437964, 0.720534565557959028, 0.721066199298559418, 0.721597408854492639, + 0.722128193913261773, 0.722658554162619815, 0.723188489290569114, 0.723717998985363042, + 0.724247082935504105, 0.724775740829746273, 0.725303972357093540, 0.725831777206800921, + 0.726359155068374340, 0.726886105631571300, 0.727412628586400101, 0.727938723623120842, + 0.728464390432245423, 0.728989628704537651, 0.729514438131013354, 0.730038818402940604, + 0.730562769211840157, 0.731086290249485127, 0.731609381207901532, 0.732132041779368414, + 0.732654271656418277, 0.733176070531836532, 0.733697438098662391, 0.734218374050188749, + 0.734738878079962410, 0.735258949881784085, 0.735778589149709283, 0.736297795578047420, + 0.736816568861362708, 0.737334908694474267, 0.737852814772456012, 0.738370286790637209, + 0.738887324444602478, 0.739403927430191787, 0.739920095443501014, 0.740435828180881606, + 0.740951125338941474, 0.741465986614544548, 0.741980411704811216, 0.742494400307118330, + 0.743007952119099757, 0.743521066838646050, 0.744033744163905331, 0.744545983793282407, + 0.745057785425440100, 0.745569148759298805, 0.746080073494036267, 0.746590559329088910, + 0.747100605964150954, 0.747610213099175303, 0.748119380434373094, 0.748628107670214038, + 0.749136394507427417, 0.749644240647000970, 0.750151645790182009, 0.750658609638477081, + 0.751165131893652416, 0.751671212257733923, 0.752176850433007749, 0.752682046122019943, + 0.753186799027576792, 0.753691108852745373, 0.754194975300852777, 0.754698398075487886, + 0.755201376880499708, 0.755703911419999041, 0.756206001398357364, 0.756707646520208499, + 0.757208846490447174, 0.757709601014230794, 0.758209909796977888, 0.758709772544370109, + 0.759209188962350789, 0.759708158757126273, 0.760206681635165360, 0.760704757303200085, + 0.761202385468225273, 0.761699565837498982, 0.762196298118542837, 0.762692582019142140, + 0.763188417247345763, 0.763683803511466808, 0.764178740520082056, 0.764673227982032966, + 0.765167265606425118, 0.765660853102629213, 0.766153990180280187, 0.766646676549278316, + 0.767138911919788891, 0.767630696002242541, 0.768122028507335242, 0.768612909146028978, + 0.769103337629551076, 0.769593313669395207, 0.770082836977321050, 0.770571907265354628, + 0.771060524245788526, 0.771548687631182117, 0.772036397134361230, 0.772523652468419031, + 0.773010453346715698, 0.773496799482878972, 0.773982690590803823, 0.774468126384653011, + 0.774953106578857298, 0.775437630888115126, 0.775921699027393386, 0.776405310711927421, + 0.776888465657220917, 0.777371163579046121, 0.777853404193444398, 0.778335187216725788, + 0.778816512365470004, 0.779297379356525877, 0.779777787907011688, 0.780257737734315393, + 0.780737228556094953, 0.781216260090278114, 0.781694832055063182, 0.782172944168918471, + 0.782650596150582967, 0.783127787719066326, 0.783604518593649102, 0.784080788493882630, + 0.784556597139589806, 0.785031944250864644, 0.785506829548072494, 0.785981252751850712, + 0.786455213583108326, 0.786928711763026367, 0.787401747013058095, 0.787874319054929106, + 0.788346427610637446, 0.788818072402453607, 0.789289253152921200, 0.789759969584856947, + 0.790230221421350243, 0.790700008385764264, 0.791169330201735188, 0.791638186593173199, + 0.792106577284262259, 0.792574501999460113, 0.793041960463498619, 0.793508952401384193, + 0.793975477538397367, 0.794441535600093451, 0.794907126312302537, 0.795372249401129494, + 0.795836904592954530, 0.796301091614432965, 0.796764810192495343, 0.797228060054348209, + 0.797690840927473555, 0.798153152539629263, 0.798614994618849217, 0.799076366893443746, + 0.799537269091999514, 0.799997700943379408, 0.800457662176723428, 0.800917152521448239, + 0.801376171707247176, 0.801834719464091572, 0.802292795522229207, 0.802750399612185972, + 0.803207531464765090, 0.803664190811047674, 0.804120377382392726, 0.804576090910437580, + 0.805031331127097571, 0.805486097764566700, 0.805940390555317410, 0.806394209232100923, + 0.806847553527947570, 0.807300423176166460, 0.807752817910346033, 0.808204737464354173, + 0.808656181572338206, 0.809107149968725237, 0.809557642388222143, 0.810007658565815802, + 0.810457198236773424, 0.810906261136642437, 0.811354847001250379, 0.811802955566706119, + 0.812250586569398636, 0.812697739745998460, 0.813144414833456564, 0.813590611569005695, + 0.814036329690159821, 0.814481568934714351, 0.814926329040746578, 0.815370609746615571, + 0.815814410790962508, 0.816257731912710449, 0.816700572851065343, 0.817142933345515021, + 0.817584813135830202, 0.818026211962064487, 0.818467129564554363, 0.818907565683919203, + 0.819347520061061929, 0.819786992437168571, 0.820225982553709043, 0.820664490152436699, + 0.821102514975388553, 0.821540056764886395, 0.821977115263535230, 0.822413690214225057, + 0.822849781360129873, 0.823285388444708666, 0.823720511211704975, 0.824155149405147225, + 0.824589302769349053, 0.825022971048909093, 0.825456153988711638, 0.825888851333926088, + 0.826321062830008057, 0.826752788222698376, 0.827184027258024202, 0.827614779682298907, + 0.828045045242121636, 0.828474823684378414, 0.828904114756241706, 0.829332918205170522, + 0.829761233778910978, 0.830189061225495850, 0.830616400293245349, 0.831043250730767014, + 0.831469612286955706, 0.831895484710993838, 0.832320867752351701, 0.832745761160787246, + 0.833170164686346748, 0.833594078079364698, 0.834017501090463576, 0.834440433470554632, + 0.834862874970837443, 0.835284825342800685, 0.835706284338222027, 0.836127251709167796, + 0.836547727207993752, 0.836967710587344982, 0.837387201600156006, 0.837806199999651335, + 0.838224705539344694, 0.838642717973040241, 0.839060237054832125, 0.839477262539104374, + 0.839893794180531672, 0.840309831734079360, 0.840725374955003213, 0.841140423598849885, + 0.841554977421456685, 0.841969036178952690, 0.842382599627757522, 0.842795667524582570, + 0.843208239626430545, 0.843620315690596034, 0.844031895474665173, 0.844442978736516192, + 0.844853565234319537, 0.845263654726537528, 0.845673246971925363, 0.846082341729530230, + 0.846490938758692413, 0.846899037819044742, 0.847306638670512924, 0.847713741073315985, + 0.848120344787966163, 0.848526449575268904, 0.848932055196323088, 0.849337161412521469, + 0.849741767985550456, 0.850145874677390667, 0.850549481250316264, 0.850952587466896060, + 0.851355193089992968, 0.851757297882764441, 0.852158901608662700, 0.852560004031434615, + 0.852960604915121823, 0.853360704024061278, 0.853760301122884924, 0.854159395976520019, + 0.854557988350189590, 0.854956078009411757, 0.855353664720000739, 0.855750748248066517, + 0.856147328360015059, 0.856543404822548538, 0.856938977402665336, 0.857334045867660377, + 0.857728609985124901, 0.858122669522947135, 0.858516224249311843, 0.858909273932701112, + 0.859301818341893897, 0.859693857245966475, 0.860085390414292217, 0.860476417616542588, + 0.860866938622686151, 0.861256953202989561, 0.861646461128017127, 0.862035462168631583, + 0.862423956095993427, 0.862811942681561694, 0.863199421697094182, 0.863586392914646672, + 0.863972856106574150, 0.864358811045530140, 0.864744257504467262, 0.865129195256637451, + 0.865513624075591625, 0.865897543735180353, 0.866280954009553406, 0.866663854673160539, + 0.867046245500750934, 0.867428126267374200, 0.867809496748379705, 0.868190356719416911, + 0.868570705956435596, 0.868950544235686406, 0.869329871333719972, 0.869708687027388017, + 0.870086991093843243, 0.870464783310538781, 0.870842063455229409, 0.871218831305970776, + 0.871595086641120398, 0.871970829239336664, 0.872346058879579944, 0.872720775341112254, + 0.873094978403497701, 0.873468667846602154, 0.873841843450593792, 0.874214504995942998, + 0.874586652263422581, 0.874958285034107774, 0.875329403089376790, 0.875700006210910487, + 0.876070094180692371, 0.876439666781009374, 0.876808723794451517, 0.877177265003911799, + 0.877545290192587202, 0.877912799143977796, 0.878279791641887631, 0.878646267470424513, + 0.879012226414000009, 0.879377668257329992, 0.879742592785434541, 0.880106999783637822, + 0.880470889037568538, 0.880834260333160257, 0.881197113456650749, 0.881559448194582984, + 0.881921264333804689, 0.882282561661468900, 0.882643339965033635, 0.883003599032262221, + 0.883363338651223740, 0.883722558610292475, 0.884081258698148575, 0.884439438703778169, + 0.884797098416473027, 0.885154237625831231, 0.885510856121756951, 0.885866953694460779, + 0.886222530134459618, 0.886577585232577015, 0.886932118779943157, 0.887286130567995324, + 0.887639620388477213, 0.887992588033440056, 0.888345033295241948, 0.888696955966548519, + 0.889048355840332816, 0.889399232709875087, 0.889749586368763778, 0.890099416610894645, + 0.890448723230471750, 0.890797506022006691, 0.891145764780319927, 0.891493499300539671, + 0.891840709378102670, 0.892187394808754086, 0.892533555388547839, 0.892879190913846710, + 0.893224301181322011, 0.893568885987954475, 0.893912945131033587, 0.894256478408158362, + 0.894599485617236789, 0.894941966556486723, 0.895283921024435547, 0.895625348819920064, + 0.895966249742087273, 0.896306623590393814, 0.896646470164606524, 0.896985789264802547, + 0.897324580691369000, 0.897662844245003866, 0.898000579726715098, 0.898337786937821847, + 0.898674465679953793, 0.899010615755051368, 0.899346236965366308, 0.899681329113461214, + 0.900015892002209994, 0.900349925434797971, 0.900683429214721887, 0.901016403145790012, + 0.901348847032122258, 0.901680760678150728, 0.902012143888618834, 0.902342996468582736, + 0.902673318223410126, 0.903003108958781331, 0.903332368480688985, 0.903661096595438029, + 0.903989293109646375, 0.904316957830244350, 0.904644090564475367, 0.904970691119895476, + 0.905296759304374143, 0.905622294926093696, 0.905947297793550210, 0.906271767715552623, + 0.906595704501223620, 0.906919107959999637, 0.907241977901630858, 0.907564314136180994, + 0.907886116474028060, 0.908207384725864042, 0.908528118702695009, 0.908848318215841444, + 0.909167983076938357, 0.909487113097935063, 0.909805708091095511, 0.910123767868998623, + 0.910441292244537959, 0.910758281030922046, 0.911074734041674716, 0.911390651090634663, + 0.911706031991956101, 0.912020876560108440, 0.912335184609876837, 0.912648955956361974, + 0.912962190414980279, 0.913274887801464041, 0.913587047931861296, 0.913898670622536269, + 0.914209755690169490, 0.914520302951757569, 0.914830312224613529, 0.915139783326366918, + 0.915448716074963920, 0.915757110288667242, 0.916064965786056562, 0.916372282386028525, + 0.916679059907796634, 0.916985298170891472, 0.917290996995161034, 0.917596156200770618, + 0.917900775608202935, 0.918204855038258105, 0.918508394312054111, 0.918811393251026676, + 0.919113851676929272, 0.919415769411833339, 0.919717146278128617, 0.920017982098522813, + 0.920318276696041826, 0.920618029894030188, 0.920917241516150842, 0.921215911386385145, + 0.921514039329033530, 0.921811625168714843, 0.922108668730367120, 0.922405169839247141, + 0.922701128320931097, 0.922996544001314145, 0.923291416706610857, 0.923585746263355323, + 0.923879532498400824, 0.924172775238920718, 0.924465474312407776, 0.924757629546674620, + 0.925049240769853953, 0.925340307810398333, 0.925630830497080392, 0.925920808658993288, + 0.926210242125550476, 0.926499130726485376, 0.926787474291852487, 0.927075272652026716, + 0.927362525637703605, 0.927649233079899771, 0.927935394809952352, 0.928221010659520007, + 0.928506080460582250, 0.928790604045439672, 0.929074581246714604, 0.929358011897350567, + 0.929640895830612490, 0.929923232880087158, 0.930205022879682875, 0.930486265663629908, + 0.930766961066480270, 0.931047108923108269, 0.931326709068709957, 0.931605761338803795, + 0.931884265569230541, 0.932162221596153473, 0.932439629256058056, 0.932716488385752496, + 0.932992798822367853, 0.933268560403357705, 0.933543772966498708, 0.933818436349890257, + 0.934092550391955045, 0.934366114931438840, 0.934639129807410707, 0.934911594859262896, + 0.935183509926711398, 0.935454874849795615, 0.935725689468878352, 0.935995953624646493, + 0.936265667158110548, 0.936534829910604993, 0.936803441723788266, 0.937071502439643100, + 0.937339011900476193, 0.937605969948918649, 0.937872376427925758, 0.938138231180777771, + 0.938403534051079014, 0.938668284882758552, 0.938932483520070416, 0.939196129807593372, + 0.939459223590231041, 0.939721764713212115, 0.939983753022090474, 0.940245188362745066, + 0.940506070581380249, 0.940766399524525787, 0.941026175039036850, 0.941285396972094235, + 0.941544065171204148, 0.941802179484199087, 0.942059739759236736, 0.942316745844801185, + 0.942573197589702372, 0.942829094843076310, 0.943084437454385305, 0.943339225273417736, + 0.943593458150288611, 0.943847135935439230, 0.944100258479637411, 0.944352825633977933, + 0.944604837249881868, 0.944856293179097140, 0.945107193273698964, 0.945357537386089186, + 0.945607325368996832, 0.945856557075477999, 0.946105232358916082, 0.946353351073021876, + 0.946600913071833583, 0.946847918209716810, 0.947094366341364791, 0.947340257321798385, + 0.947585591006366412, 0.947830367250745209, 0.948074585910939294, 0.948318246843281143, + 0.948561349904431306, 0.948803894951378513, 0.949045881841439676, 0.949287310432260334, + 0.949528180581814096, 0.949768492148403309, 0.950008244990658834, 0.950247438967540381, + 0.950486073938336173, 0.950724149762663395, 0.950961666300468300, 0.951198623412025879, + 0.951435020957940414, 0.951670858799145369, 0.951906136796903390, 0.952140854812806525, + 0.952375012708776225, 0.952608610347063234, 0.952841647590248364, 0.953074124301241610, + 0.953306040343283034, 0.953537395579942326, 0.953768189875119243, 0.953998423093043280, + 0.954228095098274331, 0.954457205755702143, 0.954685754930546970, 0.954913742488359252, + 0.955141168295019494, 0.955368032216739271, 0.955594334120060118, 0.955820073871854747, + 0.956045251339325941, 0.956269866390007883, 0.956493918891765160, 0.956717408712793538, + 0.956940335721619739, 0.957162699787101445, 0.957384500778427627, 0.957605738565118547, + 0.957826413017025757, 0.958046524004331990, 0.958266071397551711, 0.958485055067530789, + 0.958703474885446938, 0.958921330722809273, 0.959138622451458756, 0.959355349943568525, + 0.959571513071643012, 0.959787111708519380, 0.960002145727366307, 0.960216615001684759, + 0.960430519405308214, 0.960643858812401996, 0.960856633097464052, 0.961068842135324952, + 0.961280485801147333, 0.961491563970426899, 0.961702076518991644, 0.961912023323002630, + 0.962121404258953317, 0.962330219203670456, 0.962538468034313643, 0.962746150628375319, + 0.962953266863681323, 0.963159816618390341, 0.963365799770994458, 0.963571216200319269, + 0.963776065785523439, 0.963980348406099363, 0.964184063941872727, 0.964387212273003058, + 0.964589793279983176, 0.964791806843640187, 0.964993252845134486, 0.965194131165960756, + 0.965394441687947302, 0.965594184293256719, 0.965793358864385554, 0.965991965284164533, + 0.966190003435758560, 0.966387473202666936, 0.966584374468723362, 0.966780707118095828, + 0.966976471035286833, 0.967171666105133609, 0.967366292212807788, 0.967560349243816065, + 0.967753837083999424, 0.967946755619534249, 0.968139104736931211, 0.968330884323036600, + 0.968522094265031219, 0.968712734450431268, 0.968902804767088011, 0.969092305103187890, + 0.969281235347252967, 0.969469595388140148, 0.969657385115042403, 0.969844604417487544, + 0.970031253185339559, 0.970217331308797615, 0.970402838678396829, 0.970587775185007939, + 0.970772140719837529, 0.970955935174428242, 0.971139158440658457, 0.971321810410742725, + 0.971503890977231443, 0.971685400033011404, 0.971866337471305353, 0.972046703185672767, + 0.972226497070008855, 0.972405719018545667, 0.972584368925851539, 0.972762446686831206, + 0.972939952196726243, 0.973116885351114735, 0.973293246045911387, 0.973469034177367742, + 0.973644249642072190, 0.973818892336950070, 0.973992962159263453, 0.974166459006611696, + 0.974339382776930885, 0.974511733368494615, 0.974683510679913323, 0.974854714610134954, + 0.975025345058444626, 0.975195401924464744, 0.975364885108155333, 0.975533794509813701, + 0.975702130030074888, 0.975869891569911552, 0.976037079030633636, 0.976203692313889371, + 0.976369731321664158, 0.976535195956281687, 0.976700086120403377, 0.976864401717028485, + 0.977028142649494558, 0.977191308821476867, 0.977353900136989084, 0.977515916500382720, + 0.977677357816347903, 0.977838223989912936, 0.977998514926444185, 0.978158230531646744, + 0.978317370711563994, 0.978475935372577932, 0.978633924421408952, 0.978791337765116287, + 0.978948175311097568, 0.979104436967089486, 0.979260122641167130, 0.979415232241744871, + 0.979569765677575477, 0.979723722857751111, 0.979877103691702667, 0.980029908089200097, + 0.980182135960352530, 0.980333787215608377, 0.980484861765754889, 0.980635359521918826, + 0.980785280395566450, 0.980934624298502977, 0.981083391142873240, 0.981231580841161688, + 0.981379193306191944, 0.981526228451127580, 0.981672686189471455, 0.981818566435066375, + 0.981963869102094655, 0.982108594105078558, 0.982252741358879966, 0.982396310778700932, + 0.982539302280083238, 0.982681715778908504, 0.982823551191398748, 0.982964808434115711, + 0.983105487423961533, 0.983245588078178190, 0.983385110314348165, 0.983524054050394225, + 0.983662419204579197, 0.983800205695506524, 0.983937413442119935, 0.984074042363703660, + 0.984210092379882440, 0.984345563410621405, 0.984480455376226748, 0.984614768197344614, + 0.984748501794962539, 0.984881656090408342, 0.985014231005350904, 0.985146226461799612, + 0.985277642382105134, 0.985408478688958755, 0.985538735305392932, 0.985668412154781071, + 0.985797509160837526, 0.985926026247617826, 0.986053963339518891, 0.986181320361278368, + 0.986308097237975523, 0.986434293895030789, 0.986559910258205885, 0.986684946253604034, + 0.986809401807669628, 0.986933276847188901, 0.987056571299289143, 0.987179285091439485, + 0.987301418151450561, 0.987422970407474621, 0.987543941788005641, 0.987664332221879215, + 0.987784141638272883, 0.987903369966705691, 0.988022017137038855, 0.988140083079474985, + 0.988257567724559305, 0.988374471003178434, 0.988490792846561273, 0.988606533186278558, + 0.988721691954243309, 0.988836269082710606, 0.988950264504277698, 0.989063678151883896, + 0.989176509958810901, 0.989288759858682698, 0.989400427785465664, 0.989511513673468235, + 0.989622017457341574, 0.989731939072079236, 0.989841278453016948, 0.989950035535833384, + 0.990058210256549387, 0.990165802551528640, 0.990272812357477328, 0.990379239611444473, + 0.990485084250821379, 0.990590346213342632, 0.990695025437085319, 0.990799121860469145, + 0.990902635422257094, 0.991005566061554655, 0.991107913717810374, 0.991209678330815969, + 0.991310859840705660, 0.991411458187957284, 0.991511473313391067, 0.991610905158170963, + 0.991709753663803650, 0.991808018772139088, 0.991905700425370629, 0.992002798566034460, + 0.992099313137010275, 0.992195244081521155, 0.992290591343133355, 0.992385354865756408, + 0.992479534593643575, 0.992573130471391174, 0.992666142443939248, 0.992758570456571232, + 0.992850414454914176, 0.992941674384938522, 0.993032350192958546, 0.993122441825631808, + 0.993211949229959812, 0.993300872353287678, 0.993389211143304252, 0.993476965548041990, + 0.993564135515877411, 0.993650720995530423, 0.993736721936065215, 0.993822138286889589, + 0.993906969997755407, 0.993991217018758144, 0.994074879300337666, 0.994157956793277453, + 0.994240449448705155, 0.994322357218092590, 0.994403680053255523, 0.994484417906353668, + 0.994564570729891129, 0.994644138476716178, 0.994723121100020924, 0.994801518553342090, + 0.994879330790560346, 0.994956557765900973, 0.995033199433933091, 0.995109255749570543, + 0.995184726668071340, 0.995259612145037775, 0.995333912136416754, 0.995407626598499462, + 0.995480755487921587, 0.995553298761663208, 0.995625256377049239, 0.995696628291748653, + 0.995767414463775147, 0.995837614851487252, 0.995907229413587669, 0.995976258109124157, + 0.996044700897488755, 0.996112557738418336, 0.996179828591994498, 0.996246513418643675, + 0.996312612179136692, 0.996378124834589429, 0.996443051346462494, 0.996507391676561216, + 0.996571145787035984, 0.996634313640381797, 0.996696895199438604, 0.996758890427391409, + 0.996820299287769940, 0.996881121744448873, 0.996941357761648050, 0.997001007303932152, + 0.997060070336210802, 0.997118546823738794, 0.997176436732115978, 0.997233740027287152, + 0.997290456675542281, 0.997346586643516386, 0.997402129898189660, 0.997457086406887461, + 0.997511456137280206, 0.997565239057383812, 0.997618435135558923, 0.997671044340511792, + 0.997723066641293732, 0.997774502007301334, 0.997825350408276579, 0.997875611814306618, + 0.997925286195823991, 0.997974373523606517, 0.998022873768777408, 0.998070786902805041, + 0.998118112897503629, 0.998164851725032443, 0.998211003357896032, 0.998256567768944780, + 0.998301544931374352, 0.998345934818725578, 0.998389737404885347, 0.998432952664085605, + 0.998475580570903798, 0.998517621100263209, 0.998559074227432397, 0.998599939928025537, + 0.998640218178002415, 0.998679908953668427, 0.998719012231674363, 0.998757527989016958, + 0.998795456203038223, 0.998832796851426119, 0.998869549912213994, 0.998905715363781033, + 0.998941293184852031, 0.998976283354497285, 0.999010685852133262, 0.999044500657521706, + 0.999077727750770306, 0.999110367112332365, 0.999142418723007020, 0.999173882563939020, + 0.999204758616619171, 0.999235046862883780, 0.999264747284915100, 0.999293859865241219, + 0.999322384586735724, 0.999350321432618371, 0.999377670386454753, 0.999404431432156071, + 0.999430604553979474, 0.999456189736528056, 0.999481186964750634, 0.999505596223941972, + 0.999529417499742889, 0.999552650778139817, 0.999575296045465134, 0.999597353288397494, + 0.999618822493960835, 0.999639703649525702, 0.999659996742808032, 0.999679701761869932, + 0.999698818695119673, 0.999717347531310918, 0.999735288259543831, 0.999752640869264408, + 0.999769405350264373, 0.999785581692681724, 0.999801169887000296, 0.999816169924050091, + 0.999830581795006723, 0.999844405491392196, 0.999857641005074460, 0.999870288328267298, + 0.999882347453530551, 0.999893818373770338, 0.999904701082238501, 0.999914995572533050, + 0.999924701838597940, 0.999933819874723184, 0.999942349675545072, 0.999950291236045619, + 0.999957644551553115, 0.999964409617741579, 0.999970586430631414, 0.999976174986589084, + 0.999981175282326773, 0.999985587314903057, 0.999989411081722346, 0.999992646580535438, + 0.999995293809438746, 0.999997352766875069, 0.999998823451633156, 0.999999705862847810, + 1.000000000000000000, +}; + diff --git a/lib_dsp/src/fft/dsp_fft_float4.xc b/lib_dsp/src/fft/dsp_fft_float4.xc new file mode 100644 index 00000000..1a4b780d --- /dev/null +++ b/lib_dsp/src/fft/dsp_fft_float4.xc @@ -0,0 +1,58 @@ +// Copyright (c) 2022, XMOS Ltd, All rights reserved +#include +#include +#include "dsp_fft_float4.h" + +extern void dsp_fft_float4_forward_xs3 ( + dsp_complex_float4_t pts[], + uint32_t N, + const float sine[]); + +extern void dsp_fft_float4_inverse_xs3 ( + dsp_complex_float4_t pts[], + uint32_t N, + const float sine[]); + +extern void dsp_fft_float4_split_spectrum_xs3( dsp_complex_float4_t pts[], + uint32_t N, float m ); + +extern void dsp_fft_float4_merge_spectra_xs3( dsp_complex_float4_t pts[], uint32_t N ); + +void dsp_fft_float4_forward ( + dsp_complex_float4_t pts[], + const uint32_t N, + const float sine[] ){ +#if defined(__XS3A__) + dsp_fft_float4_forward_xs3 (pts, (uint32_t) N, sine); +#else + asm volatile("ecallf %0" :: "r" (0)); +#endif +} + +void dsp_fft_float4_inverse ( + dsp_complex_float4_t pts[], + const uint32_t N, + const float sine[] ){ +#if defined(__XS3A__) + dsp_fft_float4_inverse_xs3 (pts, (uint32_t) N, sine); +#else + asm volatile("ecallf %0" :: "r" (0)); +#endif +} + +void dsp_fft_float4_split_spectrum( dsp_complex_float4_t pts[], const + uint32_t N, float m ){ +#if defined(__XS3A__) + dsp_fft_float4_split_spectrum_xs3(pts, (uint32_t) N, m); +#else + asm volatile("ecallf %0" :: "r" (0)); +#endif +} + +void dsp_fft_float4_merge_spectra( dsp_complex_float4_t pts[], const uint32_t N ){ +#if defined(__XS3A__) + dsp_fft_float4_merge_spectra_xs3(pts, (uint32_t) N); +#else + asm volatile("ecallf %0" :: "r" (0)); +#endif +} diff --git a/lib_dsp/src/fft/dsp_fft_float4_forward.S b/lib_dsp/src/fft/dsp_fft_float4_forward.S new file mode 100644 index 00000000..d1555365 --- /dev/null +++ b/lib_dsp/src/fft/dsp_fft_float4_forward.S @@ -0,0 +1,184 @@ +// Copyright (c) 2015-2017, XMOS Ltd, All rights reserved + +#if defined(__XS3A__) + + .text + .issue_mode dual + .globl dsp_fft_float4_forward_xs3 + .align 16 + .skip 8 + .type dsp_fft_float4_forward_xs3,@function + .cc_top dsp_fft_float4_forward_xs3.function,dsp_fft_float4_forward_xs3 + +dsp_fft_float4_forward_xs3: + + dualentsp 32 + + stw r4, sp[27] + std r9, r10, sp[10] + std r7, r8, sp[11] + std r5, r6, sp[9] + + { ldc r6, 1 ; ldc r5, 31 } + { mkmsk r4, r5 ; shl r5, r6, r5 } + add r4, r4, 1 + std r4, r4, sp[2] // 0x800000000 x 2 + + { stw r0, sp[16] ; ldc r10, 29 } // pts + { stw r1, sp[17] ; clz r11, r1 }// N + { stw r2, sp[29] ; sub r11, r10, r11 } // sine + + { stw r11, sp[15] ; ldc r11, 4 } // Shift + + { nop ; stw r11, sp[14] } // step + + +// First iteration + + { ldw r11, sp[17] ; ldc r8, 0 } // N + { sub r11, r11, 2 ; ldc r7, 1 } // k + N - step: BLOCK. + // N>>2 - k<>2 - k<>2 - k<>2 - k< header; + printf("#define SINE_H_\n")> header; + for(j = 2; j < max_points; j = j * 2) { + printf("extern const float dsp_sine_float_%d[%d];\n", 4*j, j+1) > header; + } + printf("\n") > header; + + + printf("// Copyright (c) 2022, XMOS Ltd, All rights reserved\n") > impl; + printf("\n") > impl; + + + for(j = 1; j < max_points; j = j * 2) { + printf("const float dsp_sine_float_%d[%d] = {\n ", 4*j, j+1) > impl; + for(i = 0; i <= j; i++) { + printf(" %20.18f,", sin(i*3.1415926535/2/j)) > impl; + if (i % 4 == 3) printf("\n ") > impl; + } + printf("\n};\n\n") > impl; + } +} +' diff --git a/tests/test_fft_float/Makefile b/tests/test_fft_float/Makefile new file mode 100644 index 00000000..2078daef --- /dev/null +++ b/tests/test_fft_float/Makefile @@ -0,0 +1,8 @@ +TARGET = XCORE-AI-EXPLORER +APP_NAME = test +USED_MODULES = lib_dsp(>=4.0.0) +XCC_FLAGS = -O2 -g -report -DDEBUG_PRINT_ENABLE=1 +VERBOSE = 0 + +XMOS_MAKE_PATH ?= ../.. +-include $(XMOS_MAKE_PATH)/xcommon/module_xcommon/build/Makefile.common diff --git a/tests/test_fft_float/config.xscope b/tests/test_fft_float/config.xscope new file mode 100644 index 00000000..bfdf1f86 --- /dev/null +++ b/tests/test_fft_float/config.xscope @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/test_fft_float/src/test.xc b/tests/test_fft_float/src/test.xc new file mode 100755 index 00000000..7721d7a4 --- /dev/null +++ b/tests/test_fft_float/src/test.xc @@ -0,0 +1,100 @@ +// Copyright 2016-2021 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. +#include +#include +#include +#include +#include + +#include "dsp_fft_float4.h" + +int random(unsigned &x){ + crc32(x, -1, 0xEB31D82E); + return (int)x; +} + +// Float FFTs are tested by going forwards and backwards. +// There is a small chance that you get the right answer +// when errors cancel each other out - that can be fixed at some time. + +void test_float_fft(){ + unsigned x=1; + + float max_error = 0; + float average_error = 0; + unsigned test_count = 2; + int fail = 0; + for(unsigned t=0;t max_error) + max_error = e; + e = f[i].im / FFT_LENGTH - g[i].im; + average_error += e; + e = fabs(e); + if(e > max_error) + max_error = e; + } + average_error = average_error / FFT_LENGTH / 2; + if (max_error >= 1e-6 || fabs(average_error) >= 1e-7) { + fail = 1; + printf("Forward/inverse FAIL %g %g\n", max_error, average_error); + } + for(unsigned i=0;i max_error) + max_error = e; + e = f[i].im / FFT_LENGTH - g[i].im; + average_error += e; + e = fabs(e); + if(e > max_error) + max_error = e; + } + average_error = average_error / FFT_LENGTH / 2; + if (max_error >= 1e-6 || fabs(average_error) >= 1e-7) { + fail = 1; + printf("Real forward/inverse FAIL %g %g\n", max_error, average_error); + } + } + if (!fail) { + printf("Float FFT: Pass.\n"); + } +} + +unsafe int main(){ + test_float_fft(); + _Exit(0); + return 0; +} diff --git a/tests/test_fft_float/wscript b/tests/test_fft_float/wscript new file mode 100644 index 00000000..4d984c5b --- /dev/null +++ b/tests/test_fft_float/wscript @@ -0,0 +1,10 @@ +def configure(conf): + conf.load('xwaf.compiler_xcc') + + +def build(bld): + bld.env.TARGET_ARCH = 'XCORE-200-EXPLORER' + bld.env.XCC_FLAGS = ['-O2', '-g', '-report', '-DDEBUG_PRINT_ENABLE=1'] + + # Build our program + prog = bld.program(target='bin/test.xe', depends_on='lib_dsp(>=4.0.0)') From d25d021ccebf035abf21c834c29e52f9eb6df175 Mon Sep 17 00:00:00 2001 From: Henk Muller Date: Wed, 26 Jan 2022 13:39:58 +0000 Subject: [PATCH 2/3] Updated coyrights --- lib_dsp/api/dsp_complex.h | 2 +- lib_dsp/api/dsp_fft_float4.h | 3 ++- lib_dsp/src/dsp_tables.c | 2 +- lib_dsp/src/fft/dsp_fft_float4.xc | 4 +++- lib_dsp/src/fft/dsp_fft_float4_forward.S | 4 +++- lib_dsp/src/fft/dsp_fft_float4_inverse.S | 4 +++- lib_dsp/src/fft/dsp_fft_float4_merge_spectra.S | 4 +++- lib_dsp/src/fft/dsp_fft_float4_split_spectrum.S | 4 +++- tests/test_fft_float/src/test.xc | 3 ++- 9 files changed, 21 insertions(+), 9 deletions(-) diff --git a/lib_dsp/api/dsp_complex.h b/lib_dsp/api/dsp_complex.h index 46768bae..447d3f69 100644 --- a/lib_dsp/api/dsp_complex.h +++ b/lib_dsp/api/dsp_complex.h @@ -1,4 +1,4 @@ -// Copyright 2016-2021 XMOS LIMITED. +// Copyright 2016-2022 XMOS LIMITED. // This Software is subject to the terms of the XMOS Public Licence: Version 1. #ifndef DSP_COMPLEX_H_ diff --git a/lib_dsp/api/dsp_fft_float4.h b/lib_dsp/api/dsp_fft_float4.h index ca1c0e38..023bdf58 100644 --- a/lib_dsp/api/dsp_fft_float4.h +++ b/lib_dsp/api/dsp_fft_float4.h @@ -1,4 +1,5 @@ -// Copyright (c) 2022, XMOS Ltd, All rights reserved +// Copyright 2022 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. #ifndef DSP_FFT_FLOAT4_H_ #define DSP_FFT_FLOAT4_H_ diff --git a/lib_dsp/src/dsp_tables.c b/lib_dsp/src/dsp_tables.c index 71d9f044..03bfcf80 100644 --- a/lib_dsp/src/dsp_tables.c +++ b/lib_dsp/src/dsp_tables.c @@ -1,4 +1,4 @@ -// Copyright 2015-2021 XMOS LIMITED. +// Copyright 2015-2022 XMOS LIMITED. // This Software is subject to the terms of the XMOS Public Licence: Version 1. #include diff --git a/lib_dsp/src/fft/dsp_fft_float4.xc b/lib_dsp/src/fft/dsp_fft_float4.xc index 1a4b780d..ce61d14f 100644 --- a/lib_dsp/src/fft/dsp_fft_float4.xc +++ b/lib_dsp/src/fft/dsp_fft_float4.xc @@ -1,4 +1,6 @@ -// Copyright (c) 2022, XMOS Ltd, All rights reserved +// Copyright 2022 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + #include #include #include "dsp_fft_float4.h" diff --git a/lib_dsp/src/fft/dsp_fft_float4_forward.S b/lib_dsp/src/fft/dsp_fft_float4_forward.S index d1555365..ed52b567 100644 --- a/lib_dsp/src/fft/dsp_fft_float4_forward.S +++ b/lib_dsp/src/fft/dsp_fft_float4_forward.S @@ -1,4 +1,6 @@ -// Copyright (c) 2015-2017, XMOS Ltd, All rights reserved +// Copyright 2022 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + #if defined(__XS3A__) diff --git a/lib_dsp/src/fft/dsp_fft_float4_inverse.S b/lib_dsp/src/fft/dsp_fft_float4_inverse.S index 79b51dac..4ba2055f 100644 --- a/lib_dsp/src/fft/dsp_fft_float4_inverse.S +++ b/lib_dsp/src/fft/dsp_fft_float4_inverse.S @@ -1,4 +1,6 @@ -// Copyright (c) 2015-2017, XMOS Ltd, All rights reserved +// Copyright 2022 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + #if defined(__XS3A__) diff --git a/lib_dsp/src/fft/dsp_fft_float4_merge_spectra.S b/lib_dsp/src/fft/dsp_fft_float4_merge_spectra.S index 6f7a9609..d001e3d8 100644 --- a/lib_dsp/src/fft/dsp_fft_float4_merge_spectra.S +++ b/lib_dsp/src/fft/dsp_fft_float4_merge_spectra.S @@ -1,4 +1,6 @@ -// Copyright (c) 2016, XMOS Ltd, All rights reserved +// Copyright 2022 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + .section .dp.data,"awd",@progbits .text diff --git a/lib_dsp/src/fft/dsp_fft_float4_split_spectrum.S b/lib_dsp/src/fft/dsp_fft_float4_split_spectrum.S index 380210f4..f8b63c17 100644 --- a/lib_dsp/src/fft/dsp_fft_float4_split_spectrum.S +++ b/lib_dsp/src/fft/dsp_fft_float4_split_spectrum.S @@ -1,4 +1,6 @@ -// Copyright (c) 2015-2016, XMOS Ltd, All rights reserved +// Copyright 2022 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + .text diff --git a/tests/test_fft_float/src/test.xc b/tests/test_fft_float/src/test.xc index 7721d7a4..fdca4341 100755 --- a/tests/test_fft_float/src/test.xc +++ b/tests/test_fft_float/src/test.xc @@ -1,5 +1,6 @@ -// Copyright 2016-2021 XMOS LIMITED. +// Copyright 2022 XMOS LIMITED. // This Software is subject to the terms of the XMOS Public Licence: Version 1. + #include #include #include From 3b235bb8efb92172888f01594c4197dda2fbd9d5 Mon Sep 17 00:00:00 2001 From: Henk Muller Date: Thu, 27 Jan 2022 17:31:27 +0000 Subject: [PATCH 3/3] Added functions for converting float arrays to BFP for efficient FFTs --- lib_dsp/api/dsp_bfp.h | 24 ++++++ lib_dsp/src/bfp/dsp_bfp_float.S | 122 +++++++++++++++++++++++++++++++ lib_dsp/src/bfp/dsp_bfp_float.c | 19 +++++ tests/test_fft_float/src/test.xc | 27 +++++++ 4 files changed, 192 insertions(+) create mode 100644 lib_dsp/src/bfp/dsp_bfp_float.S create mode 100644 lib_dsp/src/bfp/dsp_bfp_float.c diff --git a/lib_dsp/api/dsp_bfp.h b/lib_dsp/api/dsp_bfp.h index e6c08166..fa16d661 100644 --- a/lib_dsp/api/dsp_bfp.h +++ b/lib_dsp/api/dsp_bfp.h @@ -300,6 +300,30 @@ void dsp_bfp_shl2( dsp_complex_t * UNSAFE pts, const uint32_t N, */ void dsp_bfp_bit_reverse_shl( dsp_complex_t pts[], const uint32_t N, const int32_t shift ); +/** This function transforms a floating point array into a BFP array. + * It establishes the maximum magnitude, and returns the exponent of the + * maximum magnitude. + * + * \param[in,out] f Array of float elements (in), bfp (out) + * \param[in] N Half the number of points - when passing a + * dsp_complex_float4_t array as the first + * parameter it is the number of points + * \returns the exponent, needed when converting back. + */ +int32_t dsp_float_to_bfp(float f[], uint32_t N); + + +/** This function transforms a BFP array to a floating point array, giving + * all BFP values the exponent passed in. + * + * \param[in,out] f Array of float elements (out), bfp (in). + * \param[in] N Half the number of points - when passing a + * dsp_complex_float4_t array as the first + * parameter it is the number of points + * \param[in] exp the exponent, from the forward conversion + */ +void dsp_bfp_to_float(float f[], uint32_t N, int32_t exponent); + #endif #endif diff --git a/lib_dsp/src/bfp/dsp_bfp_float.S b/lib_dsp/src/bfp/dsp_bfp_float.S new file mode 100644 index 00000000..2bc8c6c3 --- /dev/null +++ b/lib_dsp/src/bfp/dsp_bfp_float.S @@ -0,0 +1,122 @@ +// Copyright (c) 2022, XMOS Ltd, All rights reserved + +#if defined(__XS3A__) + +#define NSTACKWORDS 4 + .text + .issue_mode dual + .globl dsp_float_to_bfp_xs3 + .type dsp_float_to_bfp_xs3,@function + .cc_top dsp_float_to_bfp_xs3.function,dsp_float_to_bfp_xs3 + + // int32_t dsp_float_to_bfp_xs3({float,float}*ptr, uint32_t N) + .align 16 +dsp_float_to_bfp_xs3: + dualentsp NSTACKWORDS + std r4, r5, sp[0] + std r6, r7, sp[1] + + { sub r1, r1, 1 ; mkmsk r2, 32 } + { shl r2, r2, 16 ; add r3, r1, 0 } +.loop: + ldd r4, r5, r0[r1] + fsexp r11, r4, r4 + fsexp r6, r5, r5 + { lss r11, r4, r2 ; nop } + { bt r11, .not ; lss r11, r5, r2 } + { add r2, r4, 0 ; lss r11, r5, r4 } +.not: + bt r11, .not2 + add r2, r5, 0 +.not2: + { bt r1, .loop ; sub r1, r1, 1 } + sub r2, r2, 5 + nop // This aligns the next loop... + +.loop2: + ldd r4, r5, r0[r3] + fsexp r11, r6, r4 + fmant r4, r4 + { bf r11, .not3 ; sub r6, r6, r2 } + neg r4, r4 +.not3: + shl r4, r4, r6 + fsexp r11, r6, r5 + fmant r5, r5 + { bf r11, .not4 ; sub r6, r6, r2 } + neg r5, r5 +.not4: + shl r5, r5, r6 + std r4, r5, r0[r3] + { bt r3, .loop2 ; sub r3, r3, 1 } + + ldd r4, r5, sp[0] + ldd r6, r7, sp[1] + add r0, r2, 0 + retsp NSTACKWORDS + + // RETURN_REG_HOLDER + .cc_bottom dsp_float_to_bfp_xs3.function + .set dsp_float_to_bfp_xs3.nstackwords,NSTACKWORDS + .globl dsp_float_to_bfp_xs3.nstackwords + .set dsp_float_to_bfp_xs3.maxcores,1 + .globl dsp_float_to_bfp_xs3.maxcores + .set dsp_float_to_bfp_xs3.maxtimers,0 + .globl dsp_float_to_bfp_xs3.maxtimers + .set dsp_float_to_bfp_xs3.maxchanends,0 + .globl dsp_float_to_bfp_xs3.maxchanends +.Ltmp0: + .size dsp_float_to_bfp_xs3, .Ltmp0-dsp_float_to_bfp_xs3 + +#undef NSTACKWORDS +#define NSTACKWORDS 4 + + .globl dsp_bfp_to_float_xs3 + .type dsp_bfp_to_float_xs3,@function + .cc_top dsp_bfp_to_float_xs3.function,dsp_bfp_to_float_xs3 + + // void dsp_bfp_to_float_xs3({float,float}*ptr, uint32_t N, int32_t exp) + + .align 16 +dsp_bfp_to_float_xs3: + dualentsp NSTACKWORDS + std r4, r5, sp[0] + { sub r1, r1, 1 ; ldc r3, 0 } + std r6, r7, sp[1] + +.loop3: + ldd r4, r5, r0[r1] + lss r11, r4, r3 + bf r11, .not5 + neg r4, r4 +.not5: + fmake r4, r11, r2, r3, r4 + lss r11, r5, r3 + bf r11, .not6 + neg r5, r5 +.not6: + fmake r5, r11, r2, r3, r5 + std r4, r5, r0[r1] + { bt r1, .loop3 ; sub r1, r1, 1 } + + ldd r4, r5, sp[0] + ldd r6, r7, sp[1] + add r0, r2, 0 + retsp NSTACKWORDS + + + // RETURN_REG_HOLDER + .cc_bottom dsp_bfp_to_float_xs3.function + .set dsp_bfp_to_float_xs3.nstackwords,NSTACKWORDS + .globl dsp_bfp_to_float_xs3.nstackwords + .set dsp_bfp_to_float_xs3.maxcores,1 + .globl dsp_bfp_to_float_xs3.maxcores + .set dsp_bfp_to_float_xs3.maxtimers,0 + .globl dsp_bfp_to_float_xs3.maxtimers + .set dsp_bfp_to_float_xs3.maxchanends,0 + .globl dsp_bfp_to_float_xs3.maxchanends +.Ltmp1: + .size dsp_bfp_to_float_xs3, .Ltmp1-dsp_bfp_to_float_xs3 + + +#endif diff --git a/lib_dsp/src/bfp/dsp_bfp_float.c b/lib_dsp/src/bfp/dsp_bfp_float.c new file mode 100644 index 00000000..fb3dafdd --- /dev/null +++ b/lib_dsp/src/bfp/dsp_bfp_float.c @@ -0,0 +1,19 @@ +#include +#include "dsp_bfp.h" + +extern int32_t dsp_float_to_bfp_xs3(float f[], uint32_t N); +extern void dsp_bfp_to_float_xs3(float f[], uint32_t N, int32_t exponent); + +int32_t dsp_float_to_bfp(float f[], uint32_t N) { +#if !defined(__XS3A__) + asm volatile("ecallf %0" :: "r" (0)); +#endif + return dsp_float_to_bfp_xs3(f, N); +} + +void dsp_bfp_to_float(float f[], uint32_t N, int32_t exponent) { +#if !defined(__XS3A__) + asm volatile("ecallf %0" :: "r" (0)); +#endif + dsp_bfp_to_float_xs3(f, N, exponent); +} diff --git a/tests/test_fft_float/src/test.xc b/tests/test_fft_float/src/test.xc index fdca4341..c0d57994 100755 --- a/tests/test_fft_float/src/test.xc +++ b/tests/test_fft_float/src/test.xc @@ -8,6 +8,7 @@ #include #include "dsp_fft_float4.h" +#include "dsp_bfp.h" int random(unsigned &x){ crc32(x, -1, 0xEB31D82E); @@ -88,6 +89,32 @@ void test_float_fft(){ fail = 1; printf("Real forward/inverse FAIL %g %g\n", max_error, average_error); } + + int exp = dsp_float_to_bfp((f, float[]), FFT_LENGTH); + dsp_fft_bit_reverse((f, dsp_complex_t[]), FFT_LENGTH); + dsp_fft_forward((f, dsp_complex_t[]), FFT_LENGTH, FFT_SINE(FFT_LENGTH)); + dsp_fft_bit_reverse((f, dsp_complex_t[]), FFT_LENGTH); + dsp_fft_inverse((f, dsp_complex_t[]), FFT_LENGTH, FFT_SINE(FFT_LENGTH)); + dsp_bfp_to_float((f, float[]), FFT_LENGTH, exp); + + max_error = average_error = 0; + for(unsigned i=0;i max_error) + max_error = e; + e = f[i].im / FFT_LENGTH - g[i].im; + average_error += e; + e = fabs(e); + if(e > max_error) + max_error = e; + } + average_error = average_error / FFT_LENGTH / 2; + if (max_error >= 1e-6 || fabs(average_error) >= 1e-7) { + fail = 1; + printf("Float to BSP forward/inverse FAIL %g %g\n", max_error, average_error); + } } if (!fail) { printf("Float FFT: Pass.\n");