diff --git a/CMakeLists.txt b/CMakeLists.txt index 26714f84..cc96f100 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,6 +53,7 @@ option(OPT_BUILD_METEOR_DEMODULATOR "Build the meteor demodulator module (no dep option(OPT_BUILD_PAGER_DECODER "Build the pager decoder module (no dependencies required)" ON) option(OPT_BUILD_RADIO "Main audio modulation decoder (AM, FM, SSB, etc...)" ON) option(OPT_BUILD_RYFI_DECODER "RyFi data link decoder" OFF) +option(OPT_BUILD_VOR_RECEIVER "VOR beacon receiver" ON) option(OPT_BUILD_WEATHER_SAT_DECODER "Build the HRPT decoder module (no dependencies required)" OFF) # Misc @@ -289,6 +290,10 @@ if (OPT_BUILD_RYFI_DECODER) add_subdirectory("decoder_modules/ryfi_decoder") endif (OPT_BUILD_RYFI_DECODER) +if (OPT_BUILD_VOR_RECEIVER) +add_subdirectory("decoder_modules/vor_receiver") +endif (OPT_BUILD_VOR_RECEIVER) + if (OPT_BUILD_WEATHER_SAT_DECODER) add_subdirectory("decoder_modules/weather_sat_decoder") endif (OPT_BUILD_WEATHER_SAT_DECODER) diff --git a/decoder_modules/vor_receiver/CMakeLists.txt b/decoder_modules/vor_receiver/CMakeLists.txt new file mode 100644 index 00000000..2cd77d0c --- /dev/null +++ b/decoder_modules/vor_receiver/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.13) +project(vor_receiver) + +file(GLOB_RECURSE SRC "src/*.cpp") + +include(${SDRPP_MODULE_CMAKE}) + +target_include_directories(vor_receiver PRIVATE "src/") \ No newline at end of file diff --git a/decoder_modules/vor_receiver/src/main.cpp b/decoder_modules/vor_receiver/src/main.cpp new file mode 100644 index 00000000..99897952 --- /dev/null +++ b/decoder_modules/vor_receiver/src/main.cpp @@ -0,0 +1,128 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "vor_decoder.h" +#include + +#define CONCAT(a, b) ((std::string(a) + b).c_str()) + +SDRPP_MOD_INFO{ + /* Name: */ "vor_receiver", + /* Description: */ "VOR Receiver for SDR++", + /* Author: */ "Ryzerth", + /* Version: */ 0, 1, 0, + /* Max instances */ -1 +}; + +ConfigManager config; + +#define INPUT_SAMPLE_RATE VOR_IN_SR + +class VORReceiverModule : public ModuleManager::Instance { +public: + VORReceiverModule(std::string name) { + this->name = name; + + // Load config + config.acquire(); + // TODO: Load config + config.release(); + + vfo = sigpath::vfoManager.createVFO(name, ImGui::WaterfallVFO::REF_CENTER, 0, INPUT_SAMPLE_RATE, INPUT_SAMPLE_RATE, INPUT_SAMPLE_RATE, INPUT_SAMPLE_RATE, true); + decoder = new vor::Decoder(vfo->output, 1); + decoder->onBearing.bind(&VORReceiverModule::onBearing, this); + + decoder->start(); + + gui::menu.registerEntry(name, menuHandler, this, this); + } + + ~VORReceiverModule() { + decoder->stop(); + sigpath::vfoManager.deleteVFO(vfo); + gui::menu.removeEntry(name); + delete decoder; + } + + void postInit() {} + + void enable() { + double bw = gui::waterfall.getBandwidth(); + vfo = sigpath::vfoManager.createVFO(name, ImGui::WaterfallVFO::REF_CENTER, 0, INPUT_SAMPLE_RATE, INPUT_SAMPLE_RATE, INPUT_SAMPLE_RATE, INPUT_SAMPLE_RATE, true); + + decoder->setInput(vfo->output); + + decoder->start(); + + enabled = true; + } + + void disable() { + decoder->stop(); + + sigpath::vfoManager.deleteVFO(vfo); + enabled = false; + } + + bool isEnabled() { + return enabled; + } + +private: + static void menuHandler(void* ctx) { + VORReceiverModule* _this = (VORReceiverModule*)ctx; + + float menuWidth = ImGui::GetContentRegionAvail().x; + + if (!_this->enabled) { style::beginDisabled(); } + + ImGui::Text("Bearing: %f°", _this->bearing); + ImGui::Text("Quality: %0.1f%%", _this->quality); + + if (!_this->enabled) { style::endDisabled(); } + } + + void onBearing(float nbearing, float nquality) { + bearing = (180.0f * nbearing / FL_M_PI); + quality = nquality * 100.0f; + } + + std::string name; + bool enabled = true; + + // DSP Chain + VFOManager::VFO* vfo; + vor::Decoder* decoder; + + float bearing = 0.0f, quality = 0.0f; +}; + +MOD_EXPORT void _INIT_() { + // Create default recording directory + std::string root = (std::string)core::args["root"]; + json def = json({}); + config.setPath(root + "/vor_receiver_config.json"); + config.load(def); + config.enableAutoSave(); +} + +MOD_EXPORT ModuleManager::Instance* _CREATE_INSTANCE_(std::string name) { + return new VORReceiverModule(name); +} + +MOD_EXPORT void _DELETE_INSTANCE_(void* instance) { + delete (VORReceiverModule*)instance; +} + +MOD_EXPORT void _END_() { + config.disableAutoSave(); + config.save(); +} \ No newline at end of file diff --git a/decoder_modules/vor_receiver/src/vor_decoder.cpp b/decoder_modules/vor_receiver/src/vor_decoder.cpp new file mode 100644 index 00000000..7e883924 --- /dev/null +++ b/decoder_modules/vor_receiver/src/vor_decoder.cpp @@ -0,0 +1,50 @@ +#include "vor_decoder.h" + +#define STDDEV_NORM_FACTOR 1.813799364234218f // 2.0f * FL_M_PI / sqrt(12) + +namespace vor { + Decoder::Decoder(dsp::stream* in, double integrationTime) { + rx.init(in); + reshape.init(&rx.out, round(1000.0 * integrationTime), 0); + symSink.init(&reshape.out, dataHandler, this); + } + + Decoder::~Decoder() { + // TODO + } + + void Decoder::setInput(dsp::stream* in) { + rx.setInput(in); + } + + void Decoder::start() { + rx.start(); + reshape.start(); + symSink.start(); + } + + void Decoder::stop() { + rx.stop(); + reshape.stop(); + symSink.stop(); + } + + void Decoder::dataHandler(float* data, int count, void* ctx) { + // Get the instance from context + Decoder* _this = (Decoder*)ctx; + + // Compute the mean and standard deviation of the + float mean, stddev; + volk_32f_stddev_and_mean_32f_x2(&stddev, &mean, data, count); + + // Compute the signal quality + float quality = std::max(1.0f - (stddev / STDDEV_NORM_FACTOR), 0.0f); + + // Convert the phase difference to a compass heading + mean = -mean; + if (mean < 0) { mean = 2.0f*FL_M_PI + mean; } + + // Call the handler + _this->onBearing(mean, quality); + } +} \ No newline at end of file diff --git a/decoder_modules/vor_receiver/src/vor_decoder.h b/decoder_modules/vor_receiver/src/vor_decoder.h new file mode 100644 index 00000000..2cbadd0a --- /dev/null +++ b/decoder_modules/vor_receiver/src/vor_decoder.h @@ -0,0 +1,49 @@ +#include "vor_receiver.h" +#include +#include +#include + +namespace vor { + // Note: hard coded to 22KHz samplerate + class Decoder { + public: + /** + * Create an instance of a VOR decoder. + * @param in Input IQ stream at 22 KHz sampling rate. + * @param integrationTime Integration time of the bearing data in seconds. + */ + Decoder(dsp::stream* in, double integrationTime); + + // Destructor + ~Decoder(); + + /** + * Set the input stream. + * @param in Input IQ stream at 22 KHz sampling rate. + */ + void setInput(dsp::stream* in); + + /** + * Start the decoder. + */ + void start(); + + /** + * Stop the decoder. + */ + void stop(); + + /** + * handler(bearing, signalQuality); + */ + NewEvent onBearing; + + private: + static void dataHandler(float* data, int count, void* ctx); + + // DSP + Receiver rx; + dsp::buffer::Reshaper reshape; + dsp::sink::Handler symSink; + }; +} \ No newline at end of file diff --git a/decoder_modules/vor_receiver/src/vor_fm_filter.h b/decoder_modules/vor_receiver/src/vor_fm_filter.h new file mode 100644 index 00000000..3f905efa --- /dev/null +++ b/decoder_modules/vor_receiver/src/vor_fm_filter.h @@ -0,0 +1,2019 @@ +#pragma once + +namespace vor { + inline const int FM_TAPS_COUNT = 2011; + + inline const float fm_taps[FM_TAPS_COUNT] = { + -0.000006109288183514f, + -0.000003674541955659f, + -0.000004779788270372f, + -0.000006045709764433f, + -0.000007474002547860f, + -0.000009063545700303f, + -0.000010810207693424f, + -0.000012706877818527f, + -0.000014742479261160f, + -0.000016901396500296f, + -0.000019162653755748f, + -0.000021500486472433f, + -0.000023884913347536f, + -0.000026282830804390f, + -0.000028657497204560f, + -0.000030967917135288f, + -0.000033168040525824f, + -0.000035208733347957f, + -0.000037040264177767f, + -0.000038613981437072f, + -0.000039879278109500f, + -0.000040781621510670f, + -0.000041266341629171f, + -0.000041288276941170f, + -0.000040808065382982f, + -0.000039778117801811f, + -0.000038154116399303f, + -0.000035928281417613f, + -0.000033054633620131f, + -0.000029534073221752f, + -0.000025354085200549f, + -0.000020519888102764f, + -0.000015044416540825f, + -0.000008951214988593f, + -0.000002275191769226f, + 0.000004938526263985f, + 0.000012634462464758f, + 0.000020747652900748f, + 0.000029202885846665f, + 0.000037915721950398f, + 0.000046793750158675f, + 0.000055739067322418f, + 0.000064648531473803f, + 0.000073414238505833f, + 0.000081924963558768f, + 0.000090070273708587f, + 0.000097741853704875f, + 0.000104833060750238f, + 0.000111240560563557f, + 0.000116870406913513f, + 0.000121637490311034f, + 0.000125463239871277f, + 0.000128283295161322f, + 0.000130050531713267f, + 0.000130722412238075f, + 0.000130283070362475f, + 0.000128724225693378f, + 0.000126059918829065f, + 0.000122318655944895f, + 0.000117546245869520f, + 0.000111804827379716f, + 0.000105172535994941f, + 0.000097742710427729f, + 0.000089621689426281f, + 0.000080927456636837f, + 0.000071788168485065f, + 0.000062340616578619f, + 0.000052727044513410f, + 0.000043092560698178f, + 0.000033583189823970f, + 0.000024343863627320f, + 0.000015514560719203f, + 0.000007227811194343f, + -0.000000392491452466f, + -0.000007233719517451f, + -0.000013198783755514f, + -0.000018205863042794f, + -0.000022188977775861f, + -0.000025102746508593f, + -0.000026921733263561f, + -0.000027638251254584f, + -0.000027269636840452f, + -0.000025848764651163f, + -0.000023432109178267f, + -0.000020093052903038f, + -0.000015923572923636f, + -0.000011030861655414f, + -0.000005535851135993f, + 0.000000428775864674f, + 0.000006721623638640f, + 0.000013195403079244f, + 0.000019699907362524f, + 0.000026084532309469f, + 0.000032201936203283f, + 0.000037911137465265f, + 0.000043080039937301f, + 0.000047587812967163f, + 0.000051328525346064f, + 0.000054213207228491f, + 0.000056170813563558f, + 0.000057150142241454f, + 0.000057122209107976f, + 0.000056079435281490f, + 0.000054036122005224f, + 0.000051029527904062f, + 0.000047117411434176f, + 0.000042377276484990f, + 0.000036907130120826f, + 0.000030818838701021f, + 0.000024240890727427f, + 0.000017311388485692f, + 0.000010178154295699f, + 0.000002993578289500f, + -0.000004087828493657f, + -0.000010912869611986f, + -0.000017333274865704f, + -0.000023209111430418f, + -0.000028411883800464f, + -0.000032826966647140f, + -0.000036356783996654f, + -0.000038923285975669f, + -0.000040469464411596f, + -0.000040960399482781f, + -0.000040384962965518f, + -0.000038756075197520f, + -0.000036110109901527f, + -0.000032506638562594f, + -0.000028027624096958f, + -0.000022774734901308f, + -0.000016868003449940f, + -0.000010443524585747f, + -0.000003649265564901f, + 0.000003357141330849f, + 0.000010411602206816f, + 0.000017349242608710f, + 0.000024005184719154f, + 0.000030221316412432f, + 0.000035847314768360f, + 0.000040746254394306f, + 0.000044796731079762f, + 0.000047895984883187f, + 0.000049962369281348f, + 0.000050937668029991f, + 0.000050788678249516f, + 0.000049507719097204f, + 0.000047113404283130f, + 0.000043650540665661f, + 0.000039189157368090f, + 0.000033822933058292f, + 0.000027667766107818f, + 0.000020858955407975f, + 0.000013548089519783f, + 0.000005900076470390f, + -0.000001910569513671f, + -0.000009704267699912f, + -0.000017299671406734f, + -0.000024518229198241f, + -0.000031188931025793f, + -0.000037151360310197f, + -0.000042259945949899f, + -0.000046388182493159f, + -0.000049430353411989f, + -0.000051306129846989f, + -0.000051960487217968f, + -0.000051367238062574f, + -0.000049528770519374f, + -0.000046476814913015f, + -0.000042271683966488f, + -0.000037001458648510f, + -0.000030780199814965f, + -0.000023745256101906f, + -0.000016054625888813f, + -0.000007883460437059f, + 0.000000580010658621f, + 0.000009138820056230f, + 0.000017591442259001f, + 0.000025736816225947f, + 0.000033378999586567f, + 0.000040331588355996f, + 0.000046422482562162f, + 0.000051498284636757f, + 0.000055427397862331f, + 0.000058103930641909f, + 0.000059450628457840f, + 0.000059420412393689f, + 0.000057998330189496f, + 0.000055202182499686f, + 0.000051082037800314f, + 0.000045720519367860f, + 0.000039229622613836f, + 0.000031750068450418f, + 0.000023447104982292f, + 0.000014507583030107f, + 0.000005135320776492f, + -0.000004453115475680f, + -0.000014033501809136f, + -0.000023379370168885f, + -0.000032267082887130f, + -0.000040481240839557f, + -0.000047819903216017f, + -0.000054099500139015f, + -0.000059159238150764f, + -0.000062865541322377f, + -0.000065115261946193f, + -0.000065838335783532f, + -0.000065000160192262f, + -0.000062602850639426f, + -0.000058685158171678f, + -0.000053322505890226f, + -0.000046625460072103f, + -0.000038737326490312f, + -0.000029831517862890f, + -0.000020107473309076f, + -0.000009786332972285f, + 0.000000893612030385f, + 0.000011683415329273f, + 0.000022327948303690f, + 0.000032572957968353f, + 0.000042170322379228f, + 0.000050884639982961f, + 0.000058498507625299f, + 0.000064818115626048f, + 0.000069678132878258f, + 0.000072945804661283f, + 0.000074524679300214f, + 0.000074357319998588f, + 0.000072427027959214f, + 0.000068758666351570f, + 0.000063418891615972f, + 0.000056514764098596f, + 0.000048191681245119f, + 0.000038630638267446f, + 0.000028044233859372f, + 0.000016671763862838f, + 0.000004774246341924f, + -0.000007371791557980f, + -0.000019480623429147f, + -0.000031263891561115f, + -0.000042437777277376f, + -0.000052729454173657f, + -0.000061883674185677f, + -0.000069669603079317f, + -0.000075885747574376f, + -0.000080366006836497f, + -0.000082983245918512f, + -0.000083653422722051f, + -0.000082337606261354f, + -0.000079043807515723f, + -0.000073827205335324f, + -0.000066789293502495f, + -0.000058076206904260f, + -0.000047875715676425f, + -0.000036413155139672f, + -0.000023946529294696f, + -0.000010760997095124f, + 0.000002837929257723f, + 0.000016531330055031f, + 0.000029994162618430f, + 0.000042903043632569f, + 0.000054944044464240f, + 0.000065820092948278f, + 0.000075258524248175f, + 0.000083017604435488f, + 0.000088892730133709f, + 0.000092721959459925f, + 0.000094390042787707f, + 0.000093831915325402f, + 0.000091034993646339f, + 0.000086039592752430f, + 0.000078939282206193f, + 0.000069878589209111f, + 0.000059050763097065f, + 0.000046693211794991f, + 0.000033082804827829f, + 0.000018529441435372f, + 0.000003369066166040f, + -0.000012043868711938f, + -0.000027344730485567f, + -0.000042167392863032f, + -0.000056152903718730f, + -0.000068957962372937f, + -0.000080263557202457f, + -0.000089782729168084f, + -0.000097267790578028f, + -0.000102516769440262f, + -0.000105378714156440f, + -0.000105757838777080f, + -0.000103616649443031f, + -0.000098977242564293f, + -0.000091921669252027f, + -0.000082590699045525f, + -0.000071180897914987f, + -0.000057940846593527f, + -0.000043165719462247f, + -0.000027190580135938f, + -0.000010383286105515f, + 0.000006864480575666f, + 0.000024145787349609f, + 0.000041048480720895f, + 0.000057164466809886f, + 0.000072099916427022f, + 0.000085484736468995f, + 0.000096981588205368f, + 0.000106294389892112f, + 0.000113175925002362f, + 0.000117434268747456f, + 0.000118937927929768f, + 0.000117619862113228f, + 0.000113479649884698f, + 0.000106584344959183f, + 0.000097067647087873f, + 0.000085127406721035f, + 0.000071021663530246f, + 0.000055063247659887f, + 0.000037612684360081f, + 0.000019070354101278f, + -0.000000132743264826f, + -0.000019545024609329f, + -0.000038704679299655f, + -0.000057150825745513f, + -0.000074434543886999f, + -0.000090129492071927f, + -0.000103842739652060f, + -0.000115224175991115f, + -0.000123975805453799f, + -0.000129858955411625f, + -0.000132701104299999f, + -0.000132400534164374f, + -0.000128929568432721f, + -0.000122336101488903f, + -0.000112743328920624f, + -0.000100347593414335f, + -0.000085414468904008f, + -0.000068273279618166f, + -0.000049309779187961f, + -0.000028957686511663f, + -0.000007688761118402f, + 0.000013998117657897f, + 0.000035588531205374f, + 0.000056564654116339f, + 0.000076417744861188f, + 0.000094660233103325f, + 0.000110837847198220f, + 0.000124540792616894f, + 0.000135413921811454f, + 0.000143166077682726f, + 0.000147577669633566f, + 0.000148506635980744f, + 0.000145892903907169f, + 0.000139760487469222f, + 0.000130218160711078f, + 0.000117457329242836f, + 0.000101748809486351f, + 0.000083436912060533f, + 0.000062932096951090f, + 0.000040701827458727f, + 0.000017260003924343f, + -0.000006844869128901f, + -0.000031042445142994f, + -0.000054753940419898f, + -0.000077406046946938f, + -0.000098444580707932f, + -0.000117348082442123f, + -0.000133640657977706f, + -0.000146903857037110f, + -0.000156787371204750f, + -0.000163018194211930f, + -0.000165407860465511f, + -0.000163858108991300f, + -0.000158364044859559f, + -0.000149015239228624f, + -0.000135994769902137f, + -0.000119575693854604f, + -0.000100115465555936f, + -0.000078048337189503f, + -0.000053875654227485f, + -0.000028154763931114f, + -0.000001485873028928f, + 0.000025501489749317f, + 0.000052163606545178f, + 0.000077857653648484f, + 0.000101957231697862f, + 0.000123867553980339f, + 0.000143040087408938f, + 0.000158986171842211f, + 0.000171289383458489f, + 0.000179616374017931f, + 0.000183725630542102f, + 0.000183474369177675f, + 0.000178822928489514f, + 0.000169836828539796f, + 0.000156686350072323f, + 0.000139643501613164f, + 0.000119076506627041f, + 0.000095442175628270f, + 0.000069275653018442f, + 0.000041178444187698f, + 0.000011804755541701f, + -0.000018153765334842f, + -0.000047984193980764f, + -0.000076969257057439f, + -0.000104404536640256f, + -0.000129615410194300f, + -0.000151973802613132f, + -0.000170913430275604f, + -0.000185944397704714f, + -0.000196665494067372f, + -0.000202774906248520f, + -0.000204078440849469f, + -0.000200495344999835f, + -0.000192061380080633f, + -0.000178929194127460f, + -0.000161365902038783f, + -0.000139747766642614f, + -0.000114552388120666f, + -0.000086348156286871f, + -0.000055781617585911f, + -0.000023562759579563f, + 0.000009551486366944f, + 0.000042774951156828f, + 0.000075310678204655f, + 0.000106370161296470f, + 0.000135192271040400f, + 0.000161061842309531f, + 0.000183327387980930f, + 0.000201417353207433f, + 0.000214854727783275f, + 0.000223269445311857f, + 0.000226408352499591f, + 0.000224142612856519f, + 0.000216471840000368f, + 0.000203525720753497f, + 0.000185561924942585f, + 0.000162961414700460f, + 0.000136220434771341f, + 0.000105939820680780f, + 0.000072811548963567f, + 0.000037603044512034f, + 0.000001139498141154f, + -0.000035715414773452f, + -0.000072079848335705f, + -0.000107074949526675f, + -0.000139845899303454f, + -0.000169582736765796f, + -0.000195540361560656f, + -0.000217057067033734f, + -0.000233571229753261f, + -0.000244635976468845f, + -0.000249930953131355f, + -0.000249271370314336f, + -0.000242613799721968f, + -0.000230058607352109f, + -0.000211849036222272f, + -0.000188366730772140f, + -0.000160123972414189f, + -0.000127752676517284f, + -0.000091990257797223f, + -0.000053663184506732f, + -0.000013667706402197f, + 0.000027050802662209f, + 0.000067520258576196f, + 0.000106764878981556f, + 0.000143828694980323f, + 0.000177798729106156f, + 0.000207827414362685f, + 0.000233153623537511f, + 0.000253121813906616f, + 0.000267198967244491f, + 0.000274988484701747f, + 0.000276241155641265f, + 0.000270862644930172f, + 0.000258917244824446f, + 0.000240627875427571f, + 0.000216372371437017f, + 0.000186675793710971f, + 0.000152199349429947f, + 0.000113725760249833f, + 0.000072141615439012f, + 0.000028417066772653f, + -0.000016416741936644f, + -0.000061291833845899f, + -0.000105128801205853f, + -0.000146862728898044f, + -0.000185468819252438f, + -0.000219987673066945f, + -0.000249548818178835f, + -0.000273392726783787f, + -0.000290890039600093f, + -0.000301558082783767f, + -0.000305073887385495f, + -0.000301283553357559f, + -0.000290207552112096f, + -0.000272041945923273f, + -0.000247155458810490f, + -0.000216082139037052f, + -0.000179510202151824f, + -0.000138266929170167f, + -0.000093300066808569f, + -0.000045656192830605f, + 0.000003543499133505f, + 0.000053129581304241f, + 0.000101911985600373f, + 0.000148708539102197f, + 0.000192373475600540f, + 0.000231825411591128f, + 0.000266074029647278f, + 0.000294244751094196f, + 0.000315600999561892f, + 0.000329563255643362f, + 0.000335724457631892f, + 0.000333861610323396f, + 0.000323942758925093f, + 0.000306129791103301f, + 0.000280776218667929f, + 0.000248420612200977f, + 0.000209775357909940f, + 0.000165711207175959f, + 0.000117237749620972f, + 0.000065480454431617f, + 0.000011654695050635f, + -0.000042962774103777f, + -0.000097063877816245f, + -0.000149340515333825f, + -0.000198516080173352f, + -0.000243376498636021f, + -0.000282800077830910f, + -0.000315785482964274f, + -0.000341476931451784f, + -0.000359186281686396f, + -0.000368411156669132f, + -0.000368848882756464f, + -0.000360405658883864f, + -0.000343200766966583f, + -0.000317565804028205f, + -0.000284038664899586f, + -0.000243352530534756f, + -0.000196420107916285f, + -0.000144313216729107f, + -0.000088238645931253f, + -0.000029510161374758f, + 0.000030482017904887f, + 0.000090304081920841f, + 0.000148512725823210f, + 0.000203689917065761f, + 0.000254477258816349f, + 0.000299609319517898f, + 0.000337945077501604f, + 0.000368496501071155f, + 0.000390453915844353f, + 0.000403207172594080f, + 0.000406362231355700f, + 0.000399752711620492f, + 0.000383446095862468f, + 0.000357744252777596f, + 0.000323178425315211f, + 0.000280498518316598f, + 0.000230657166244733f, + 0.000174788623814242f, + 0.000114183119367200f, + 0.000050257258242460f, + -0.000015478995578952f, + -0.000081457811605615f, + -0.000146090760815327f, + -0.000207806986134792f, + -0.000265091118421605f, + -0.000316520511327102f, + -0.000360800277018867f, + -0.000396795811663817f, + -0.000423561601424747f, + -0.000440365867882360f, + -0.000446710159741665f, + -0.000442343620199992f, + -0.000427271369037443f, + -0.000401756702773810f, + -0.000366317279745372f, + -0.000321714963462028f, + -0.000268939750876051f, + -0.000209188025323809f, + -0.000143835663425766f, + -0.000074406505493281f, + -0.000002537024943075f, + 0.000070062154908250f, + 0.000141646743758953f, + 0.000210480613485711f, + 0.000274877725471407f, + 0.000333243263213179f, + 0.000384112992062553f, + 0.000426189757441007f, + 0.000458376390621473f, + 0.000479804053538617f, + 0.000489855261625075f, + 0.000488181267359607f, + 0.000474712853317779f, + 0.000449664741205710f, + 0.000413532993516462f, + 0.000367085737537149f, + 0.000311347112260371f, + 0.000247575042369086f, + 0.000177233047404626f, + 0.000101956810277771f, + 0.000023516412887661f, + -0.000056225180304166f, + -0.000135356159281461f, + -0.000211961565689149f, + -0.000284169444399399f, + -0.000350196428298739f, + -0.000408391579188880f, + -0.000457277511920876f, + -0.000495587592047080f, + -0.000522298545356993f, + -0.000536657381430267f, + -0.000538202125616555f, + -0.000526775695830644f, + -0.000502532508109345f, + -0.000465937729194044f, + -0.000417758932029100f, + -0.000359050395188822f, + -0.000291130426196823f, + -0.000215551899524649f, + -0.000134067109242365f, + -0.000048587272421708f, + 0.000038862044292873f, + 0.000126188805874215f, + 0.000211284280505821f, + 0.000292073831410636f, + 0.000366567309326451f, + 0.000432907816650598f, + 0.000489417834089405f, + 0.000534641334274211f, + 0.000567381051818010f, + 0.000586729774143253f, + 0.000592094970581290f, + 0.000583216039019617f, + 0.000560173753961004f, + 0.000523391472540425f, + 0.000473628200271120f, + 0.000411963365254839f, + 0.000339773836382730f, + 0.000258703470323835f, + 0.000170625938169737f, + 0.000077601708201656f, + -0.000018169980111311f, + -0.000114402854245540f, + -0.000208777943582327f, + -0.000298999333782061f, + -0.000382849685611453f, + -0.000458244582972051f, + -0.000523284041247162f, + -0.000576300178733798f, + -0.000615899573859471f, + -0.000640999569009347f, + -0.000650857317879133f, + -0.000645090916443113f, + -0.000623692076900537f, + -0.000587029803977279f, + -0.000535845125982131f, + -0.000471236693134656f, + -0.000394637668966180f, + -0.000307784292817982f, + -0.000212676867095255f, + -0.000111533945688933f, + -0.000006740905603677f, + 0.000099206110965971f, + 0.000203759338567542f, + 0.000304380444739366f, + 0.000398601874378619f, + 0.000484087077343995f, + 0.000558688210517224f, + 0.000620499725251364f, + 0.000667906703989711f, + 0.000699626672616771f, + 0.000714743646499439f, + 0.000712733823319283f, + 0.000693481923699812f, + 0.000657287958436795f, + 0.000604863881967886f, + 0.000537320431346458f, + 0.000456144085856339f, + 0.000363164813629573f, + 0.000260515212892203f, + 0.000150581890789185f, + 0.000035950353735138f, + -0.000080655547218745f, + -0.000196438003514396f, + -0.000308592100856815f, + -0.000414373446766337f, + -0.000511165031862143f, + -0.000596541603568437f, + -0.000668330126244242f, + -0.000724664627164847f, + -0.000764034272669959f, + -0.000785323241406475f, + -0.000787841526201702f, + -0.000771345760459723f, + -0.000736049370475768f, + -0.000682621919611380f, + -0.000612177403935352f, + -0.000526251645214124f, + -0.000426769393947610f, + -0.000316001606423910f, + -0.000196514072958746f, + -0.000071108292231143f, + 0.000057243773946831f, + 0.000185469842669731f, + 0.000310470445722892f, + 0.000429193502262225f, + 0.000538708492699979f, + 0.000636278354278131f, + 0.000719427519956076f, + 0.000786004217237459f, + 0.000834235655806186f, + 0.000862774560012114f, + 0.000870735927309714f, + 0.000857722949465036f, + 0.000823841487870189f, + 0.000769702480834694f, + 0.000696412275536595f, + 0.000605550794392195f, + 0.000499138177084872f, + 0.000379590414910315f, + 0.000249664941566904f, + 0.000112397545384050f, + -0.000028968145225175f, + -0.000171056890541063f, + -0.000310441958807056f, + -0.000443727376541333f, + -0.000567630162278406f, + -0.000679060781174567f, + -0.000775199620379698f, + -0.000853567863077084f, + -0.000912090720446416f, + -0.000949151658236350f, + -0.000963636083729869f, + -0.000954963346580364f, + -0.000923106255268790f, + -0.000868597333537839f, + -0.000792521743584594f, + -0.000696496738584991f, + -0.000582638114487367f, + -0.000453514236506741f, + -0.000312088739126788f, + -0.000161653044104187f, + -0.000005750341932904f, + 0.000151907390950501f, + 0.000307527168302786f, + 0.000457325737989031f, + 0.000597621021234644f, + 0.000724921999418599f, + 0.000836015010072298f, + 0.000928044199584326f, + 0.000998584197848844f, + 0.001045703215282363f, + 0.001068014822294029f, + 0.001064717207208437f, + 0.001035618647771223f, + 0.000981148668511488f, + 0.000902354199230929f, + 0.000800880920131978f, + 0.000678939887758851f, + 0.000539260208785638f, + 0.000385028750009641f, + 0.000219818078613779f, + 0.000047504433401498f, + -0.000127822584420854f, + -0.000301956374217006f, + -0.000470673621933193f, + -0.000629836005929095f, + -0.000775490996683858f, + -0.000903969230599832f, + -0.001011976198496105f, + -0.001096675765065976f, + -0.001155763672847336f, + -0.001187528961173402f, + -0.001190901757034323f, + -0.001165486196812712f, + -0.001111577387794368f, + -0.001030161949763692f, + -0.000922901897348106f, + -0.000792102035807469f, + -0.000640661557040596f, + -0.000472010693083845f, + -0.000290033970495830f, + -0.000098981542441282f, + 0.000096629165750154f, + 0.000292119466267917f, + 0.000482760418647176f, + 0.000663886321151670f, + 0.000831008021245900f, + 0.000979923172481111f, + 0.001106820914028891f, + 0.001208378241925402f, + 0.001281845817859798f, + 0.001325120872088377f, + 0.001336805412658378f, + 0.001316248099853739f, + 0.001263568683237422f, + 0.001179664053697350f, + 0.001066195774497250f, + 0.000925558941800443f, + 0.000760833072732102f, + 0.000575715953072301f, + 0.000374441760639155f, + 0.000161685368249024f, + -0.000057545132281034f, + -0.000278025196889094f, + -0.000494437180161275f, + -0.000701497452824829f, + -0.000894084144405852f, + -0.001067362620642735f, + -0.001216905462139550f, + -0.001338804217329458f, + -0.001429769909061793f, + -0.001487219914591162f, + -0.001509348928286872f, + -0.001495182043429467f, + -0.001444608572842192f, + -0.001358395417193634f, + -0.001238179580960561f, + -0.001086439585029881f, + -0.000906446340282022f, + -0.000702194314323537f, + -0.000478314470947297f, + -0.000239970739822164f, + 0.000007257534175879f, + 0.000257504744197893f, + 0.000504756606074057f, + 0.000742993111413008f, + 0.000966333479261294f, + 0.001169179582224553f, + 0.001346354486244084f, + 0.001493232622509437f, + 0.001605858426899276f, + 0.001681050461301476f, + 0.001716488257381726f, + 0.001710779678368389f, + 0.001663506796833140f, + 0.001575249101527703f, + 0.001447582939891449f, + 0.001283057100229479f, + 0.001085144686780454f, + 0.000858172141290207f, + 0.000607226857732582f, + 0.000338045204180328f, + 0.000056883526005002f, + -0.000229625196616479f, + -0.000514625634796592f, + -0.000791201925739775f, + -0.001052543161505633f, + -0.001292108717692905f, + -0.001503789351214586f, + -0.001682060349609490f, + -0.001822122728222107f, + -0.001920029115983288f, + -0.001972791007041565f, + -0.001978464567128965f, + -0.001936212700330797f, + -0.001846341438698387f, + -0.001710309519914770f, + -0.001530710493438686f, + -0.001311227372189639f, + -0.001056560549858176f, + -0.000772330236683648f, + -0.000464955507910627f, + -0.000141512294698915f, + 0.000190426393694444f, + 0.000522964637420236f, + 0.000848068136106394f, + 0.001157754881712211f, + 0.001444287582262030f, + 0.001700363158770787f, + 0.001919294919617941f, + 0.002095182781576031f, + 0.002223067470953871f, + 0.002299064672491193f, + 0.002320475685747370f, + 0.002285871503734690f, + 0.002195148041434197f, + 0.002049550547604975f, + 0.001851666323690171f, + 0.001605385242904694f, + 0.001315828585144259f, + 0.000989247356155392f, + 0.000632891915121602f, + 0.000254855643812686f, + -0.000136104150988206f, + -0.000530764197046558f, + -0.000919647730062259f, + -0.001293246706118233f, + -0.001642248577815541f, + -0.001957762500453022f, + -0.002231539423160353f, + -0.002456180942801846f, + -0.002625331641195950f, + -0.002733850151055636f, + -0.002777954534599316f, + -0.002755338030046576f, + -0.002665252027960561f, + -0.002508553549757886f, + -0.002287715658051831f, + -0.002006799729519424f, + -0.001671389634196393f, + -0.001288488582880902f, + -0.000866380478859201f, + -0.000414458215989393f, + 0.000056977493823640f, + 0.000536944804670472f, + 0.001014027934289228f, + 0.001476639564576505f, + 0.001913292629582162f, + 0.002312875232676052f, + 0.002664922418949355f, + 0.002959878312039523f, + 0.003189342379815940f, + 0.003346293731032494f, + 0.003425287756498842f, + 0.003422620051591415f, + 0.003336452992718733f, + 0.003166901432708254f, + 0.002916074502064321f, + 0.002588071742884186f, + 0.002188932626730976f, + 0.001726539634251390f, + 0.001210476197912817f, + 0.000651841656482132f, + 0.000063026732563797f, + -0.000542546344233469f, + -0.001150713756894689f, + -0.001746884189038205f, + -0.002316370334082361f, + -0.002844730736072034f, + -0.003318114256331532f, + -0.003723599566428954f, + -0.004049521614559778f, + -0.004285777483251770f, + -0.004424104163313291f, + -0.004458321259035235f, + -0.004384532373692039f, + -0.004201279536838842f, + -0.003909646152751020f, + -0.003513304813797129f, + -0.003018507595207272f, + -0.002434017623538079f, + -0.001770981895371715f, + -0.001042746832674968f, + -0.000264619049958292f, + 0.000546424637949063f, + 0.001372072991645775f, + 0.002193055640284540f, + 0.002989550702014209f, + 0.003741616784341889f, + 0.004429640458945026f, + 0.005034790103351589f, + 0.005539466332993612f, + 0.005927739419900906f, + 0.006185763909726819f, + 0.006302161103918462f, + 0.006268360378164735f, + 0.006078891246075162f, + 0.005731618581314693f, + 0.005227914832562136f, + 0.004572763944797723f, + 0.003774793183911251f, + 0.002846230466056248f, + 0.001802786180950080f, + 0.000663460219756018f, + -0.000549723734577709f, + -0.001812052862639072f, + -0.003096523694591014f, + -0.004374297861543807f, + -0.005615207161931585f, + -0.006788299053137446f, + -0.007862412453197196f, + -0.008806773217769136f, + -0.009591597816394550f, + -0.010188693543732669f, + -0.010572043458701563f, + -0.010718364227651999f, + -0.010607625636306305f, + -0.010223520798234425f, + -0.009553877251362062f, + -0.008590999837187875f, + -0.007331937688935667f, + -0.005778668872655780f, + -0.003938197939999993f, + -0.001822563001151763f, + 0.000551249002045549f, + 0.003161478741513464f, + 0.005981860522019613f, + 0.008981974122213384f, + 0.012127677022839704f, + 0.015381609874482300f, + 0.018703766766603895f, + 0.022052120300969345f, + 0.025383290585517953f, + 0.028653246179152460f, + 0.031818024355095398f, + 0.034834457662538801f, + 0.037660893405902819f, + 0.040257892952716118f, + 0.042588897818130876f, + 0.044620850266891866f, + 0.046324756860185855f, + 0.047676184404936338f, + 0.048655679124534945f, + 0.049249101040798257f, + 0.049447867491351688f, + 0.049249101040798257f, + 0.048655679124534945f, + 0.047676184404936338f, + 0.046324756860185855f, + 0.044620850266891866f, + 0.042588897818130876f, + 0.040257892952716118f, + 0.037660893405902819f, + 0.034834457662538801f, + 0.031818024355095398f, + 0.028653246179152460f, + 0.025383290585517953f, + 0.022052120300969345f, + 0.018703766766603895f, + 0.015381609874482300f, + 0.012127677022839704f, + 0.008981974122213384f, + 0.005981860522019613f, + 0.003161478741513464f, + 0.000551249002045549f, + -0.001822563001151763f, + -0.003938197939999993f, + -0.005778668872655780f, + -0.007331937688935667f, + -0.008590999837187875f, + -0.009553877251362062f, + -0.010223520798234425f, + -0.010607625636306305f, + -0.010718364227651999f, + -0.010572043458701563f, + -0.010188693543732669f, + -0.009591597816394550f, + -0.008806773217769136f, + -0.007862412453197196f, + -0.006788299053137446f, + -0.005615207161931585f, + -0.004374297861543807f, + -0.003096523694591014f, + -0.001812052862639072f, + -0.000549723734577709f, + 0.000663460219756018f, + 0.001802786180950080f, + 0.002846230466056248f, + 0.003774793183911251f, + 0.004572763944797723f, + 0.005227914832562136f, + 0.005731618581314693f, + 0.006078891246075162f, + 0.006268360378164735f, + 0.006302161103918462f, + 0.006185763909726819f, + 0.005927739419900906f, + 0.005539466332993612f, + 0.005034790103351589f, + 0.004429640458945026f, + 0.003741616784341889f, + 0.002989550702014209f, + 0.002193055640284540f, + 0.001372072991645775f, + 0.000546424637949063f, + -0.000264619049958292f, + -0.001042746832674968f, + -0.001770981895371715f, + -0.002434017623538079f, + -0.003018507595207272f, + -0.003513304813797129f, + -0.003909646152751020f, + -0.004201279536838842f, + -0.004384532373692039f, + -0.004458321259035235f, + -0.004424104163313291f, + -0.004285777483251770f, + -0.004049521614559778f, + -0.003723599566428954f, + -0.003318114256331532f, + -0.002844730736072034f, + -0.002316370334082361f, + -0.001746884189038205f, + -0.001150713756894689f, + -0.000542546344233469f, + 0.000063026732563797f, + 0.000651841656482132f, + 0.001210476197912817f, + 0.001726539634251390f, + 0.002188932626730976f, + 0.002588071742884186f, + 0.002916074502064321f, + 0.003166901432708254f, + 0.003336452992718733f, + 0.003422620051591415f, + 0.003425287756498842f, + 0.003346293731032494f, + 0.003189342379815940f, + 0.002959878312039523f, + 0.002664922418949355f, + 0.002312875232676052f, + 0.001913292629582162f, + 0.001476639564576505f, + 0.001014027934289228f, + 0.000536944804670472f, + 0.000056977493823640f, + -0.000414458215989393f, + -0.000866380478859201f, + -0.001288488582880902f, + -0.001671389634196393f, + -0.002006799729519424f, + -0.002287715658051831f, + -0.002508553549757886f, + -0.002665252027960561f, + -0.002755338030046576f, + -0.002777954534599316f, + -0.002733850151055636f, + -0.002625331641195950f, + -0.002456180942801846f, + -0.002231539423160353f, + -0.001957762500453022f, + -0.001642248577815541f, + -0.001293246706118233f, + -0.000919647730062259f, + -0.000530764197046558f, + -0.000136104150988206f, + 0.000254855643812686f, + 0.000632891915121602f, + 0.000989247356155392f, + 0.001315828585144259f, + 0.001605385242904694f, + 0.001851666323690171f, + 0.002049550547604975f, + 0.002195148041434197f, + 0.002285871503734690f, + 0.002320475685747370f, + 0.002299064672491193f, + 0.002223067470953871f, + 0.002095182781576031f, + 0.001919294919617941f, + 0.001700363158770787f, + 0.001444287582262030f, + 0.001157754881712211f, + 0.000848068136106394f, + 0.000522964637420236f, + 0.000190426393694444f, + -0.000141512294698915f, + -0.000464955507910627f, + -0.000772330236683648f, + -0.001056560549858176f, + -0.001311227372189639f, + -0.001530710493438686f, + -0.001710309519914770f, + -0.001846341438698387f, + -0.001936212700330797f, + -0.001978464567128965f, + -0.001972791007041565f, + -0.001920029115983288f, + -0.001822122728222107f, + -0.001682060349609490f, + -0.001503789351214586f, + -0.001292108717692905f, + -0.001052543161505633f, + -0.000791201925739775f, + -0.000514625634796592f, + -0.000229625196616479f, + 0.000056883526005002f, + 0.000338045204180328f, + 0.000607226857732582f, + 0.000858172141290207f, + 0.001085144686780454f, + 0.001283057100229479f, + 0.001447582939891449f, + 0.001575249101527703f, + 0.001663506796833140f, + 0.001710779678368389f, + 0.001716488257381726f, + 0.001681050461301476f, + 0.001605858426899276f, + 0.001493232622509437f, + 0.001346354486244084f, + 0.001169179582224553f, + 0.000966333479261294f, + 0.000742993111413008f, + 0.000504756606074057f, + 0.000257504744197893f, + 0.000007257534175879f, + -0.000239970739822164f, + -0.000478314470947297f, + -0.000702194314323537f, + -0.000906446340282022f, + -0.001086439585029881f, + -0.001238179580960561f, + -0.001358395417193634f, + -0.001444608572842192f, + -0.001495182043429467f, + -0.001509348928286872f, + -0.001487219914591162f, + -0.001429769909061793f, + -0.001338804217329458f, + -0.001216905462139550f, + -0.001067362620642735f, + -0.000894084144405852f, + -0.000701497452824829f, + -0.000494437180161275f, + -0.000278025196889094f, + -0.000057545132281034f, + 0.000161685368249024f, + 0.000374441760639155f, + 0.000575715953072301f, + 0.000760833072732102f, + 0.000925558941800443f, + 0.001066195774497250f, + 0.001179664053697350f, + 0.001263568683237422f, + 0.001316248099853739f, + 0.001336805412658378f, + 0.001325120872088377f, + 0.001281845817859798f, + 0.001208378241925402f, + 0.001106820914028891f, + 0.000979923172481111f, + 0.000831008021245900f, + 0.000663886321151670f, + 0.000482760418647176f, + 0.000292119466267917f, + 0.000096629165750154f, + -0.000098981542441282f, + -0.000290033970495830f, + -0.000472010693083845f, + -0.000640661557040596f, + -0.000792102035807469f, + -0.000922901897348106f, + -0.001030161949763692f, + -0.001111577387794368f, + -0.001165486196812712f, + -0.001190901757034323f, + -0.001187528961173402f, + -0.001155763672847336f, + -0.001096675765065976f, + -0.001011976198496105f, + -0.000903969230599832f, + -0.000775490996683858f, + -0.000629836005929095f, + -0.000470673621933193f, + -0.000301956374217006f, + -0.000127822584420854f, + 0.000047504433401498f, + 0.000219818078613779f, + 0.000385028750009641f, + 0.000539260208785638f, + 0.000678939887758851f, + 0.000800880920131978f, + 0.000902354199230929f, + 0.000981148668511488f, + 0.001035618647771223f, + 0.001064717207208437f, + 0.001068014822294029f, + 0.001045703215282363f, + 0.000998584197848844f, + 0.000928044199584326f, + 0.000836015010072298f, + 0.000724921999418599f, + 0.000597621021234644f, + 0.000457325737989031f, + 0.000307527168302786f, + 0.000151907390950501f, + -0.000005750341932904f, + -0.000161653044104187f, + -0.000312088739126788f, + -0.000453514236506741f, + -0.000582638114487367f, + -0.000696496738584991f, + -0.000792521743584594f, + -0.000868597333537839f, + -0.000923106255268790f, + -0.000954963346580364f, + -0.000963636083729869f, + -0.000949151658236350f, + -0.000912090720446416f, + -0.000853567863077084f, + -0.000775199620379698f, + -0.000679060781174567f, + -0.000567630162278406f, + -0.000443727376541333f, + -0.000310441958807056f, + -0.000171056890541063f, + -0.000028968145225175f, + 0.000112397545384050f, + 0.000249664941566904f, + 0.000379590414910315f, + 0.000499138177084872f, + 0.000605550794392195f, + 0.000696412275536595f, + 0.000769702480834694f, + 0.000823841487870189f, + 0.000857722949465036f, + 0.000870735927309714f, + 0.000862774560012114f, + 0.000834235655806186f, + 0.000786004217237459f, + 0.000719427519956076f, + 0.000636278354278131f, + 0.000538708492699979f, + 0.000429193502262225f, + 0.000310470445722892f, + 0.000185469842669731f, + 0.000057243773946831f, + -0.000071108292231143f, + -0.000196514072958746f, + -0.000316001606423910f, + -0.000426769393947610f, + -0.000526251645214124f, + -0.000612177403935352f, + -0.000682621919611380f, + -0.000736049370475768f, + -0.000771345760459723f, + -0.000787841526201702f, + -0.000785323241406475f, + -0.000764034272669959f, + -0.000724664627164847f, + -0.000668330126244242f, + -0.000596541603568437f, + -0.000511165031862143f, + -0.000414373446766337f, + -0.000308592100856815f, + -0.000196438003514396f, + -0.000080655547218745f, + 0.000035950353735138f, + 0.000150581890789185f, + 0.000260515212892203f, + 0.000363164813629573f, + 0.000456144085856339f, + 0.000537320431346458f, + 0.000604863881967886f, + 0.000657287958436795f, + 0.000693481923699812f, + 0.000712733823319283f, + 0.000714743646499439f, + 0.000699626672616771f, + 0.000667906703989711f, + 0.000620499725251364f, + 0.000558688210517224f, + 0.000484087077343995f, + 0.000398601874378619f, + 0.000304380444739366f, + 0.000203759338567542f, + 0.000099206110965971f, + -0.000006740905603677f, + -0.000111533945688933f, + -0.000212676867095255f, + -0.000307784292817982f, + -0.000394637668966180f, + -0.000471236693134656f, + -0.000535845125982131f, + -0.000587029803977279f, + -0.000623692076900537f, + -0.000645090916443113f, + -0.000650857317879133f, + -0.000640999569009347f, + -0.000615899573859471f, + -0.000576300178733798f, + -0.000523284041247162f, + -0.000458244582972051f, + -0.000382849685611453f, + -0.000298999333782061f, + -0.000208777943582327f, + -0.000114402854245540f, + -0.000018169980111311f, + 0.000077601708201656f, + 0.000170625938169737f, + 0.000258703470323835f, + 0.000339773836382730f, + 0.000411963365254839f, + 0.000473628200271120f, + 0.000523391472540425f, + 0.000560173753961004f, + 0.000583216039019617f, + 0.000592094970581290f, + 0.000586729774143253f, + 0.000567381051818010f, + 0.000534641334274211f, + 0.000489417834089405f, + 0.000432907816650598f, + 0.000366567309326451f, + 0.000292073831410636f, + 0.000211284280505821f, + 0.000126188805874215f, + 0.000038862044292873f, + -0.000048587272421708f, + -0.000134067109242365f, + -0.000215551899524649f, + -0.000291130426196823f, + -0.000359050395188822f, + -0.000417758932029100f, + -0.000465937729194044f, + -0.000502532508109345f, + -0.000526775695830644f, + -0.000538202125616555f, + -0.000536657381430267f, + -0.000522298545356993f, + -0.000495587592047080f, + -0.000457277511920876f, + -0.000408391579188880f, + -0.000350196428298739f, + -0.000284169444399399f, + -0.000211961565689149f, + -0.000135356159281461f, + -0.000056225180304166f, + 0.000023516412887661f, + 0.000101956810277771f, + 0.000177233047404626f, + 0.000247575042369086f, + 0.000311347112260371f, + 0.000367085737537149f, + 0.000413532993516462f, + 0.000449664741205710f, + 0.000474712853317779f, + 0.000488181267359607f, + 0.000489855261625075f, + 0.000479804053538617f, + 0.000458376390621473f, + 0.000426189757441007f, + 0.000384112992062553f, + 0.000333243263213179f, + 0.000274877725471407f, + 0.000210480613485711f, + 0.000141646743758953f, + 0.000070062154908250f, + -0.000002537024943075f, + -0.000074406505493281f, + -0.000143835663425766f, + -0.000209188025323809f, + -0.000268939750876051f, + -0.000321714963462028f, + -0.000366317279745372f, + -0.000401756702773810f, + -0.000427271369037443f, + -0.000442343620199992f, + -0.000446710159741665f, + -0.000440365867882360f, + -0.000423561601424747f, + -0.000396795811663817f, + -0.000360800277018867f, + -0.000316520511327102f, + -0.000265091118421605f, + -0.000207806986134792f, + -0.000146090760815327f, + -0.000081457811605615f, + -0.000015478995578952f, + 0.000050257258242460f, + 0.000114183119367200f, + 0.000174788623814242f, + 0.000230657166244733f, + 0.000280498518316598f, + 0.000323178425315211f, + 0.000357744252777596f, + 0.000383446095862468f, + 0.000399752711620492f, + 0.000406362231355700f, + 0.000403207172594080f, + 0.000390453915844353f, + 0.000368496501071155f, + 0.000337945077501604f, + 0.000299609319517898f, + 0.000254477258816349f, + 0.000203689917065761f, + 0.000148512725823210f, + 0.000090304081920841f, + 0.000030482017904887f, + -0.000029510161374758f, + -0.000088238645931253f, + -0.000144313216729107f, + -0.000196420107916285f, + -0.000243352530534756f, + -0.000284038664899586f, + -0.000317565804028205f, + -0.000343200766966583f, + -0.000360405658883864f, + -0.000368848882756464f, + -0.000368411156669132f, + -0.000359186281686396f, + -0.000341476931451784f, + -0.000315785482964274f, + -0.000282800077830910f, + -0.000243376498636021f, + -0.000198516080173352f, + -0.000149340515333825f, + -0.000097063877816245f, + -0.000042962774103777f, + 0.000011654695050635f, + 0.000065480454431617f, + 0.000117237749620972f, + 0.000165711207175959f, + 0.000209775357909940f, + 0.000248420612200977f, + 0.000280776218667929f, + 0.000306129791103301f, + 0.000323942758925093f, + 0.000333861610323396f, + 0.000335724457631892f, + 0.000329563255643362f, + 0.000315600999561892f, + 0.000294244751094196f, + 0.000266074029647278f, + 0.000231825411591128f, + 0.000192373475600540f, + 0.000148708539102197f, + 0.000101911985600373f, + 0.000053129581304241f, + 0.000003543499133505f, + -0.000045656192830605f, + -0.000093300066808569f, + -0.000138266929170167f, + -0.000179510202151824f, + -0.000216082139037052f, + -0.000247155458810490f, + -0.000272041945923273f, + -0.000290207552112096f, + -0.000301283553357559f, + -0.000305073887385495f, + -0.000301558082783767f, + -0.000290890039600093f, + -0.000273392726783787f, + -0.000249548818178835f, + -0.000219987673066945f, + -0.000185468819252438f, + -0.000146862728898044f, + -0.000105128801205853f, + -0.000061291833845899f, + -0.000016416741936644f, + 0.000028417066772653f, + 0.000072141615439012f, + 0.000113725760249833f, + 0.000152199349429947f, + 0.000186675793710971f, + 0.000216372371437017f, + 0.000240627875427571f, + 0.000258917244824446f, + 0.000270862644930172f, + 0.000276241155641265f, + 0.000274988484701747f, + 0.000267198967244491f, + 0.000253121813906616f, + 0.000233153623537511f, + 0.000207827414362685f, + 0.000177798729106156f, + 0.000143828694980323f, + 0.000106764878981556f, + 0.000067520258576196f, + 0.000027050802662209f, + -0.000013667706402197f, + -0.000053663184506732f, + -0.000091990257797223f, + -0.000127752676517284f, + -0.000160123972414189f, + -0.000188366730772140f, + -0.000211849036222272f, + -0.000230058607352109f, + -0.000242613799721968f, + -0.000249271370314336f, + -0.000249930953131355f, + -0.000244635976468845f, + -0.000233571229753261f, + -0.000217057067033734f, + -0.000195540361560656f, + -0.000169582736765796f, + -0.000139845899303454f, + -0.000107074949526675f, + -0.000072079848335705f, + -0.000035715414773452f, + 0.000001139498141154f, + 0.000037603044512034f, + 0.000072811548963567f, + 0.000105939820680780f, + 0.000136220434771341f, + 0.000162961414700460f, + 0.000185561924942585f, + 0.000203525720753497f, + 0.000216471840000368f, + 0.000224142612856519f, + 0.000226408352499591f, + 0.000223269445311857f, + 0.000214854727783275f, + 0.000201417353207433f, + 0.000183327387980930f, + 0.000161061842309531f, + 0.000135192271040400f, + 0.000106370161296470f, + 0.000075310678204655f, + 0.000042774951156828f, + 0.000009551486366944f, + -0.000023562759579563f, + -0.000055781617585911f, + -0.000086348156286871f, + -0.000114552388120666f, + -0.000139747766642614f, + -0.000161365902038783f, + -0.000178929194127460f, + -0.000192061380080633f, + -0.000200495344999835f, + -0.000204078440849469f, + -0.000202774906248520f, + -0.000196665494067372f, + -0.000185944397704714f, + -0.000170913430275604f, + -0.000151973802613132f, + -0.000129615410194300f, + -0.000104404536640256f, + -0.000076969257057439f, + -0.000047984193980764f, + -0.000018153765334842f, + 0.000011804755541701f, + 0.000041178444187698f, + 0.000069275653018442f, + 0.000095442175628270f, + 0.000119076506627041f, + 0.000139643501613164f, + 0.000156686350072323f, + 0.000169836828539796f, + 0.000178822928489514f, + 0.000183474369177675f, + 0.000183725630542102f, + 0.000179616374017931f, + 0.000171289383458489f, + 0.000158986171842211f, + 0.000143040087408938f, + 0.000123867553980339f, + 0.000101957231697862f, + 0.000077857653648484f, + 0.000052163606545178f, + 0.000025501489749317f, + -0.000001485873028928f, + -0.000028154763931114f, + -0.000053875654227485f, + -0.000078048337189503f, + -0.000100115465555936f, + -0.000119575693854604f, + -0.000135994769902137f, + -0.000149015239228624f, + -0.000158364044859559f, + -0.000163858108991300f, + -0.000165407860465511f, + -0.000163018194211930f, + -0.000156787371204750f, + -0.000146903857037110f, + -0.000133640657977706f, + -0.000117348082442123f, + -0.000098444580707932f, + -0.000077406046946938f, + -0.000054753940419898f, + -0.000031042445142994f, + -0.000006844869128901f, + 0.000017260003924343f, + 0.000040701827458727f, + 0.000062932096951090f, + 0.000083436912060533f, + 0.000101748809486351f, + 0.000117457329242836f, + 0.000130218160711078f, + 0.000139760487469222f, + 0.000145892903907169f, + 0.000148506635980744f, + 0.000147577669633566f, + 0.000143166077682726f, + 0.000135413921811454f, + 0.000124540792616894f, + 0.000110837847198220f, + 0.000094660233103325f, + 0.000076417744861188f, + 0.000056564654116339f, + 0.000035588531205374f, + 0.000013998117657897f, + -0.000007688761118402f, + -0.000028957686511663f, + -0.000049309779187961f, + -0.000068273279618166f, + -0.000085414468904008f, + -0.000100347593414335f, + -0.000112743328920624f, + -0.000122336101488903f, + -0.000128929568432721f, + -0.000132400534164374f, + -0.000132701104299999f, + -0.000129858955411625f, + -0.000123975805453799f, + -0.000115224175991115f, + -0.000103842739652060f, + -0.000090129492071927f, + -0.000074434543886999f, + -0.000057150825745513f, + -0.000038704679299655f, + -0.000019545024609329f, + -0.000000132743264826f, + 0.000019070354101278f, + 0.000037612684360081f, + 0.000055063247659887f, + 0.000071021663530246f, + 0.000085127406721035f, + 0.000097067647087873f, + 0.000106584344959183f, + 0.000113479649884698f, + 0.000117619862113228f, + 0.000118937927929768f, + 0.000117434268747456f, + 0.000113175925002362f, + 0.000106294389892112f, + 0.000096981588205368f, + 0.000085484736468995f, + 0.000072099916427022f, + 0.000057164466809886f, + 0.000041048480720895f, + 0.000024145787349609f, + 0.000006864480575666f, + -0.000010383286105515f, + -0.000027190580135938f, + -0.000043165719462247f, + -0.000057940846593527f, + -0.000071180897914987f, + -0.000082590699045525f, + -0.000091921669252027f, + -0.000098977242564293f, + -0.000103616649443031f, + -0.000105757838777080f, + -0.000105378714156440f, + -0.000102516769440262f, + -0.000097267790578028f, + -0.000089782729168084f, + -0.000080263557202457f, + -0.000068957962372937f, + -0.000056152903718730f, + -0.000042167392863032f, + -0.000027344730485567f, + -0.000012043868711938f, + 0.000003369066166040f, + 0.000018529441435372f, + 0.000033082804827829f, + 0.000046693211794991f, + 0.000059050763097065f, + 0.000069878589209111f, + 0.000078939282206193f, + 0.000086039592752430f, + 0.000091034993646339f, + 0.000093831915325402f, + 0.000094390042787707f, + 0.000092721959459925f, + 0.000088892730133709f, + 0.000083017604435488f, + 0.000075258524248175f, + 0.000065820092948278f, + 0.000054944044464240f, + 0.000042903043632569f, + 0.000029994162618430f, + 0.000016531330055031f, + 0.000002837929257723f, + -0.000010760997095124f, + -0.000023946529294696f, + -0.000036413155139672f, + -0.000047875715676425f, + -0.000058076206904260f, + -0.000066789293502495f, + -0.000073827205335324f, + -0.000079043807515723f, + -0.000082337606261354f, + -0.000083653422722051f, + -0.000082983245918512f, + -0.000080366006836497f, + -0.000075885747574376f, + -0.000069669603079317f, + -0.000061883674185677f, + -0.000052729454173657f, + -0.000042437777277376f, + -0.000031263891561115f, + -0.000019480623429147f, + -0.000007371791557980f, + 0.000004774246341924f, + 0.000016671763862838f, + 0.000028044233859372f, + 0.000038630638267446f, + 0.000048191681245119f, + 0.000056514764098596f, + 0.000063418891615972f, + 0.000068758666351570f, + 0.000072427027959214f, + 0.000074357319998588f, + 0.000074524679300214f, + 0.000072945804661283f, + 0.000069678132878258f, + 0.000064818115626048f, + 0.000058498507625299f, + 0.000050884639982961f, + 0.000042170322379228f, + 0.000032572957968353f, + 0.000022327948303690f, + 0.000011683415329273f, + 0.000000893612030385f, + -0.000009786332972285f, + -0.000020107473309076f, + -0.000029831517862890f, + -0.000038737326490312f, + -0.000046625460072103f, + -0.000053322505890226f, + -0.000058685158171678f, + -0.000062602850639426f, + -0.000065000160192262f, + -0.000065838335783532f, + -0.000065115261946193f, + -0.000062865541322377f, + -0.000059159238150764f, + -0.000054099500139015f, + -0.000047819903216017f, + -0.000040481240839557f, + -0.000032267082887130f, + -0.000023379370168885f, + -0.000014033501809136f, + -0.000004453115475680f, + 0.000005135320776492f, + 0.000014507583030107f, + 0.000023447104982292f, + 0.000031750068450418f, + 0.000039229622613836f, + 0.000045720519367860f, + 0.000051082037800314f, + 0.000055202182499686f, + 0.000057998330189496f, + 0.000059420412393689f, + 0.000059450628457840f, + 0.000058103930641909f, + 0.000055427397862331f, + 0.000051498284636757f, + 0.000046422482562162f, + 0.000040331588355996f, + 0.000033378999586567f, + 0.000025736816225947f, + 0.000017591442259001f, + 0.000009138820056230f, + 0.000000580010658621f, + -0.000007883460437059f, + -0.000016054625888813f, + -0.000023745256101906f, + -0.000030780199814965f, + -0.000037001458648510f, + -0.000042271683966488f, + -0.000046476814913015f, + -0.000049528770519374f, + -0.000051367238062574f, + -0.000051960487217968f, + -0.000051306129846989f, + -0.000049430353411989f, + -0.000046388182493159f, + -0.000042259945949899f, + -0.000037151360310197f, + -0.000031188931025793f, + -0.000024518229198241f, + -0.000017299671406734f, + -0.000009704267699912f, + -0.000001910569513671f, + 0.000005900076470390f, + 0.000013548089519783f, + 0.000020858955407975f, + 0.000027667766107818f, + 0.000033822933058292f, + 0.000039189157368090f, + 0.000043650540665661f, + 0.000047113404283130f, + 0.000049507719097204f, + 0.000050788678249516f, + 0.000050937668029991f, + 0.000049962369281348f, + 0.000047895984883187f, + 0.000044796731079762f, + 0.000040746254394306f, + 0.000035847314768360f, + 0.000030221316412432f, + 0.000024005184719154f, + 0.000017349242608710f, + 0.000010411602206816f, + 0.000003357141330849f, + -0.000003649265564901f, + -0.000010443524585747f, + -0.000016868003449940f, + -0.000022774734901308f, + -0.000028027624096958f, + -0.000032506638562594f, + -0.000036110109901527f, + -0.000038756075197520f, + -0.000040384962965518f, + -0.000040960399482781f, + -0.000040469464411596f, + -0.000038923285975669f, + -0.000036356783996654f, + -0.000032826966647140f, + -0.000028411883800464f, + -0.000023209111430418f, + -0.000017333274865704f, + -0.000010912869611986f, + -0.000004087828493657f, + 0.000002993578289500f, + 0.000010178154295699f, + 0.000017311388485692f, + 0.000024240890727427f, + 0.000030818838701021f, + 0.000036907130120826f, + 0.000042377276484990f, + 0.000047117411434176f, + 0.000051029527904062f, + 0.000054036122005224f, + 0.000056079435281490f, + 0.000057122209107976f, + 0.000057150142241454f, + 0.000056170813563558f, + 0.000054213207228491f, + 0.000051328525346064f, + 0.000047587812967163f, + 0.000043080039937301f, + 0.000037911137465265f, + 0.000032201936203283f, + 0.000026084532309469f, + 0.000019699907362524f, + 0.000013195403079244f, + 0.000006721623638640f, + 0.000000428775864674f, + -0.000005535851135993f, + -0.000011030861655414f, + -0.000015923572923636f, + -0.000020093052903038f, + -0.000023432109178267f, + -0.000025848764651163f, + -0.000027269636840452f, + -0.000027638251254584f, + -0.000026921733263561f, + -0.000025102746508593f, + -0.000022188977775861f, + -0.000018205863042794f, + -0.000013198783755514f, + -0.000007233719517451f, + -0.000000392491452466f, + 0.000007227811194343f, + 0.000015514560719203f, + 0.000024343863627320f, + 0.000033583189823970f, + 0.000043092560698178f, + 0.000052727044513410f, + 0.000062340616578619f, + 0.000071788168485065f, + 0.000080927456636837f, + 0.000089621689426281f, + 0.000097742710427729f, + 0.000105172535994941f, + 0.000111804827379716f, + 0.000117546245869520f, + 0.000122318655944895f, + 0.000126059918829065f, + 0.000128724225693378f, + 0.000130283070362475f, + 0.000130722412238075f, + 0.000130050531713267f, + 0.000128283295161322f, + 0.000125463239871277f, + 0.000121637490311034f, + 0.000116870406913513f, + 0.000111240560563557f, + 0.000104833060750238f, + 0.000097741853704875f, + 0.000090070273708587f, + 0.000081924963558768f, + 0.000073414238505833f, + 0.000064648531473803f, + 0.000055739067322418f, + 0.000046793750158675f, + 0.000037915721950398f, + 0.000029202885846665f, + 0.000020747652900748f, + 0.000012634462464758f, + 0.000004938526263985f, + -0.000002275191769226f, + -0.000008951214988593f, + -0.000015044416540825f, + -0.000020519888102764f, + -0.000025354085200549f, + -0.000029534073221752f, + -0.000033054633620131f, + -0.000035928281417613f, + -0.000038154116399303f, + -0.000039778117801811f, + -0.000040808065382982f, + -0.000041288276941170f, + -0.000041266341629171f, + -0.000040781621510670f, + -0.000039879278109500f, + -0.000038613981437072f, + -0.000037040264177767f, + -0.000035208733347957f, + -0.000033168040525824f, + -0.000030967917135288f, + -0.000028657497204560f, + -0.000026282830804390f, + -0.000023884913347536f, + -0.000021500486472433f, + -0.000019162653755748f, + -0.000016901396500296f, + -0.000014742479261160f, + -0.000012706877818527f, + -0.000010810207693424f, + -0.000009063545700303f, + -0.000007474002547860f, + -0.000006045709764433f, + -0.000004779788270372f, + -0.000003674541955659f, + -0.000006109288183514 + }; +} \ No newline at end of file diff --git a/decoder_modules/vor_receiver/src/vor_receiver.h b/decoder_modules/vor_receiver/src/vor_receiver.h new file mode 100644 index 00000000..a4f0b4aa --- /dev/null +++ b/decoder_modules/vor_receiver/src/vor_receiver.h @@ -0,0 +1,106 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "vor_fm_filter.h" +#include + +#define VOR_IN_SR 25e3 + +namespace vor { + class Receiver : public dsp::Processor { + using base_type = dsp::Processor; + public: + Receiver() {} + + Receiver(dsp::stream* in) { init(in); } + + ~Receiver() { + if (!base_type::_block_init) { return; } + base_type::stop(); + dsp::taps::free(fmfTaps); + } + + void init(dsp::stream* in) { + amd.init(NULL, dsp::demod::AM::CARRIER, VOR_IN_SR, 50.0f / VOR_IN_SR, 5.0f / VOR_IN_SR, 100.0f / VOR_IN_SR, VOR_IN_SR); + amr2c.init(NULL); + fmr2c.init(NULL); + fmx.init(NULL, -9960, VOR_IN_SR); + fmfTaps = dsp::taps::fromArray(FM_TAPS_COUNT, fm_taps); + fmf.init(NULL, fmfTaps); + fmd.init(NULL, 600, VOR_IN_SR); + amde.init(NULL, FM_TAPS_COUNT / 2); + amv.init(NULL, VOR_IN_SR, 1000, 30, 30); + fmv.init(NULL, VOR_IN_SR, 1000, 30, 30); + + base_type::init(in); + } + + int process(dsp::complex_t* in, float* out, int count) { + // Demodulate the AM outer modulation + volk_32fc_magnitude_32f(amd.out.writeBuf, (lv_32fc_t*)in, count); + amr2c.process(count, amd.out.writeBuf, amr2c.out.writeBuf); + + // Isolate the FM subcarrier + fmx.process(count, amr2c.out.writeBuf, fmx.out.writeBuf); + fmf.process(count, fmx.out.writeBuf, fmx.out.writeBuf); + + // Demodulate the FM subcarrier + fmd.process(count, fmx.out.writeBuf, fmd.out.writeBuf); + fmr2c.process(count, fmd.out.writeBuf, fmr2c.out.writeBuf); + + // Delay the AM signal by the same amount as the FM one + amde.process(count, amr2c.out.writeBuf, amr2c.out.writeBuf); + + // Isolate the 30Hz component on both the AM and FM channels + int rcount = amv.process(count, amr2c.out.writeBuf, amv.out.writeBuf); + fmv.process(count, fmr2c.out.writeBuf, fmv.out.writeBuf); + + // If no data was returned, we're done for this round + if (!rcount) { return 0; } + + // Conjugate FM reference + volk_32fc_conjugate_32fc((lv_32fc_t*)fmv.out.writeBuf, (lv_32fc_t*)fmv.out.writeBuf, rcount); + + // Multiply both together + volk_32fc_x2_multiply_32fc((lv_32fc_t*)amv.out.writeBuf, (lv_32fc_t*)amv.out.writeBuf, (lv_32fc_t*)fmv.out.writeBuf, rcount); + + // Compute angle + volk_32fc_s32f_atan2_32f(out, (lv_32fc_t*)amv.out.writeBuf, 1.0f, rcount); + + return rcount; + } + + int run() { + int count = base_type::_in->read(); + if (count < 0) { return -1; } + + int outCount = process(base_type::_in->readBuf, base_type::out.writeBuf, count); + + // Swap if some data was generated + base_type::_in->flush(); + if (outCount) { + if (!base_type::out.swap(outCount)) { return -1; } + } + return outCount; + } + + private: + dsp::demod::AM amd; + dsp::convert::RealToComplex amr2c; + dsp::convert::RealToComplex fmr2c; + dsp::channel::FrequencyXlator fmx; + dsp::tap fmfTaps; + dsp::filter::FIR fmf; + dsp::demod::Quadrature fmd; + dsp::math::Delay amde; + dsp::channel::RxVFO amv; + dsp::channel::RxVFO fmv; + }; +} \ No newline at end of file diff --git a/readme.md b/readme.md index 6f421339..ff1ad18b 100644 --- a/readme.md +++ b/readme.md @@ -367,6 +367,7 @@ Modules in beta are still included in releases for the most part but not enabled | meteor_demodulator | Working | - | OPT_BUILD_METEOR_DEMODULATOR | ✅ | ✅ | ⛔ | | pager_decoder | Unfinished | - | OPT_BUILD_PAGER_DECODER | ⛔ | ⛔ | ⛔ | | radio | Working | - | OPT_BUILD_RADIO | ✅ | ✅ | ✅ | +| radio | Unfinished | - | OPT_BUILD_VOR_RECEIVER | ⛔ | ⛔ | ⛔ | | weather_sat_decoder | Unfinished | - | OPT_BUILD_WEATHER_SAT_DECODER | ⛔ | ⛔ | ⛔ | ## Misc