#include "live_run.h" #include "imgui/imgui.h" #include "sdr/airspy.h" #include "global.h" #include #include #include "logger.h" #include #ifdef BUILD_LIVE #define FFT_BUFFER_SIZE 8192 bool live_processing = false; float fft_buffer[FFT_BUFFER_SIZE]; extern std::shared_ptr radio; extern std::vector> liveModules; float scale = 1.0f; std::shared_ptr>> moduleStream; void processFFT(int) { int refresh_per_second = 20; int runs_to_wait = (radio->getSamplerate() / 8192) / (refresh_per_second * 3); int i = 0, y = 0, cnt = 0; float fftb[FFT_BUFFER_SIZE]; // std::complex *sample_buffer = new std::complex[8192 * 100]; volk::vector> sample_buffer_vec; std::complex sample_buffer[FFT_BUFFER_SIZE]; std::complex buffer_fft_out[FFT_BUFFER_SIZE]; fftwf_plan p = fftwf_plan_dft_1d(FFT_BUFFER_SIZE, (fftwf_complex *)sample_buffer, (fftwf_complex *)buffer_fft_out, FFTW_FORWARD, FFTW_ESTIMATE); while (1) { // This also reduces the buffer size for the demod if (sample_buffer_vec.size() < FFT_BUFFER_SIZE) { cnt = radio->output_stream->read(); sample_buffer_vec.insert(sample_buffer_vec.end(), radio->output_stream->readBuf, &radio->output_stream->readBuf[cnt]); radio->output_stream->flush(); } std::memcpy(sample_buffer, sample_buffer_vec.data(), FFT_BUFFER_SIZE * sizeof(std::complex)); std::memcpy(moduleStream->writeBuf, sample_buffer, FFT_BUFFER_SIZE * sizeof(std::complex)); moduleStream->swap(FFT_BUFFER_SIZE); sample_buffer_vec.erase(sample_buffer_vec.begin(), sample_buffer_vec.begin() + FFT_BUFFER_SIZE); if (y % runs_to_wait == 0) { fftwf_execute(p); for (int i = 0, iMax = FFT_BUFFER_SIZE / 2; i < iMax; i++) { float a = buffer_fft_out[i].real(); float b = buffer_fft_out[i].imag(); float c = sqrt(a * a + b * b); float x = buffer_fft_out[FFT_BUFFER_SIZE / 2 + i].real(); float y = buffer_fft_out[FFT_BUFFER_SIZE / 2 + i].imag(); float z = sqrt(x * x + y * y); fftb[i] = z * 4.0f * scale; fftb[FFT_BUFFER_SIZE / 2 + i] = c * 4.0f * scale; } for (int i = 0; i < FFT_BUFFER_SIZE; i++) { fft_buffer[i] = (fftb[i] * 1 + fft_buffer[i] * 9) / 10; } i++; if (i == 10000000) i = 0; } if (y == 10000000) y = 0; y++; } } void startRealLive() { // 1 moduleStream = std::make_shared>>(); processThreadPool.push(processFFT); /* module1->input_stream = moduleStream; module1->setInputType(DATA_DSP_STREAM); module1->setOutputType(DATA_STREAM); module1->output_fifo = std::make_shared>(1000000); module1->init(); module1->input_active = true; processThreadPool.push([=](int) { logger->info("Start processing..."); module1->process(); }); module2->input_fifo = module1->output_fifo; module2->setInputType(DATA_STREAM); module2->setOutputType(DATA_FILE); module2->init(); module2->input_active = true; processThreadPool.push([=](int) { logger->info("Start processing..."); module2->process(); });*/ // Init first module in the chain, always a demod... liveModules[0]->input_stream = moduleStream; liveModules[0]->setInputType(DATA_DSP_STREAM); liveModules[0]->setOutputType(liveModules.size() > 1 ? DATA_STREAM : DATA_FILE); liveModules[0]->output_fifo = std::make_shared>(1000000); liveModules[0]->init(); liveModules[0]->input_active = true; processThreadPool.push([=](int) { logger->info("Start processing..."); liveModules[0]->process(); }); // Init whatever's in the middle for (int i = 1; i < liveModules.size() - 1; i++) { liveModules[i]->input_fifo = liveModules[i - 1]->output_fifo; liveModules[i]->output_fifo = std::make_shared>(1000000); liveModules[i]->setInputType(DATA_STREAM); liveModules[i]->setOutputType(DATA_STREAM); liveModules[i]->init(); liveModules[i]->input_active = true; processThreadPool.push([=](int) { logger->info("Start processing..."); liveModules[i]->process(); }); } // Init the last module if (liveModules.size() > 1) { int num = liveModules.size() - 1; liveModules[num]->input_fifo = liveModules[num - 1]->output_fifo; liveModules[num]->setInputType(DATA_STREAM); liveModules[num]->setOutputType(DATA_FILE); liveModules[num]->init(); liveModules[num]->input_active = true; processThreadPool.push([=](int) { logger->info("Start processing..."); liveModules[num]->process(); }); } } void renderLive() { radio->drawUI(); //ImGui::SetNextWindowPos({0, 0}); for (std::shared_ptr mod : liveModules) mod->drawUI(true); //ImGui::Text("LIVE"); ImGui::Begin("Input FFT", NULL); ImGui::PlotLines("", fft_buffer, IM_ARRAYSIZE(fft_buffer), 0, 0, 0, 100, {std::max(ImGui::GetWindowWidth() - 3, 200), std::max(ImGui::GetWindowHeight() - 64, 100)}); ImGui::SliderFloat("Scale", &scale, 0, 22); ImGui::End(); } #endif