mirror of
https://github.com/AlexandreRouma/SDRPlusPlus.git
synced 2025-07-16 05:53:31 +02:00
Compare commits
24 Commits
08f3a7d201
...
retroactiv
Author | SHA1 | Date | |
---|---|---|---|
2ce1738a49 | |||
f205d97b52 | |||
628dcfcce0 | |||
d1e7cc56b4 | |||
334860c963 | |||
5ab3428b90 | |||
7f002f6276 | |||
a728403a3f | |||
0f1d2da3b7 | |||
6d0b65c27f | |||
f640cdcb6a | |||
80a90e13d9 | |||
3982db73d3 | |||
bd64f07a20 | |||
c9950d9331 | |||
9bc609f4e4 | |||
bcc8e20e66 | |||
b07e828fed | |||
bd24a4a5eb | |||
fe4a7b32a7 | |||
0e1ab29b5d | |||
fbbafddd3d | |||
1cbc8ec6f5 | |||
9f65e3ec71 |
4
.github/workflows/build_all.yml
vendored
4
.github/workflows/build_all.yml
vendored
@ -138,7 +138,7 @@ jobs:
|
||||
|
||||
- name: Prepare CMake
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 $GITHUB_WORKSPACE -DOPT_BUILD_PLUTOSDR_SOURCE=ON -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_AUDIO_SINK=OFF -DOPT_BUILD_PORTAUDIO_SINK=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON -DOPT_BUILD_PERSEUS_SOURCE=ON -DOPT_BUILD_AUDIO_SOURCE=OFF -DOPT_BUILD_RFNM_SOURCE=ON -DOPT_BUILD_FOBOSSDR_SOURCE=ON -DUSE_BUNDLE_DEFAULTS=ON -DCMAKE_BUILD_TYPE=Release
|
||||
run: cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 $GITHUB_WORKSPACE -DOPT_BUILD_PLUTOSDR_SOURCE=ON -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_AUDIO_SINK=OFF -DOPT_BUILD_PORTAUDIO_SINK=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=OFF -DOPT_BUILD_PERSEUS_SOURCE=ON -DOPT_BUILD_AUDIO_SOURCE=OFF -DOPT_BUILD_RFNM_SOURCE=ON -DOPT_BUILD_FOBOSSDR_SOURCE=ON -DUSE_BUNDLE_DEFAULTS=ON -DCMAKE_BUILD_TYPE=Release
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
@ -195,7 +195,7 @@ jobs:
|
||||
|
||||
- name: Prepare CMake
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 $GITHUB_WORKSPACE -DOPT_BUILD_PLUTOSDR_SOURCE=ON -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_AUDIO_SINK=OFF -DOPT_BUILD_PORTAUDIO_SINK=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=OFF -DOPT_BUILD_PERSEUS_SOURCE=OFF -DOPT_BUILD_AUDIO_SOURCE=OFF -DOPT_BUILD_RFNM_SOURCE=ON -DOPT_BUILD_FOBOSSDR_SOURCE=ON -DUSE_BUNDLE_DEFAULTS=ON -DCMAKE_BUILD_TYPE=Release
|
||||
run: cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 $GITHUB_WORKSPACE -DOPT_BUILD_PLUTOSDR_SOURCE=ON -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_AUDIO_SINK=OFF -DOPT_BUILD_PORTAUDIO_SINK=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON -DOPT_BUILD_PERSEUS_SOURCE=OFF -DOPT_BUILD_AUDIO_SOURCE=OFF -DOPT_BUILD_RFNM_SOURCE=ON -DOPT_BUILD_FOBOSSDR_SOURCE=ON -DUSE_BUNDLE_DEFAULTS=ON -DCMAKE_BUILD_TYPE=Release
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
|
@ -183,6 +183,8 @@ int sdrpp_main(int argc, char* argv[]) {
|
||||
defConfig["moduleInstances"]["Hermes Source"]["enabled"] = true;
|
||||
defConfig["moduleInstances"]["LimeSDR Source"]["module"] = "limesdr_source";
|
||||
defConfig["moduleInstances"]["LimeSDR Source"]["enabled"] = true;
|
||||
defConfig["moduleInstances"]["Network Source"]["module"] = "network_source";
|
||||
defConfig["moduleInstances"]["Network Source"]["enabled"] = true;
|
||||
defConfig["moduleInstances"]["PerseusSDR Source"]["module"] = "perseus_source";
|
||||
defConfig["moduleInstances"]["PerseusSDR Source"]["enabled"] = true;
|
||||
defConfig["moduleInstances"]["PlutoSDR Source"]["module"] = "plutosdr_source";
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <gui/style.h>
|
||||
#include <gui/gui.h>
|
||||
#include <backend.h>
|
||||
#include <utils/hrfreq.h>
|
||||
|
||||
#ifndef IMGUI_DEFINE_MATH_OPERATORS
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
@ -90,6 +91,7 @@ void FrequencySelect::moveCursorToDigit(int i) {
|
||||
|
||||
void FrequencySelect::draw() {
|
||||
auto window = ImGui::GetCurrentWindow();
|
||||
auto io = ImGui::GetIO();
|
||||
widgetPos = ImGui::GetWindowContentRegionMin();
|
||||
ImVec2 cursorPos = ImGui::GetCursorPos();
|
||||
widgetPos.x += window->Pos.x + cursorPos.x;
|
||||
@ -132,7 +134,7 @@ void FrequencySelect::draw() {
|
||||
ImVec2 mousePos = ImGui::GetMousePos();
|
||||
bool leftClick = ImGui::IsMouseClicked(ImGuiMouseButton_Left);
|
||||
bool rightClick = ImGui::IsMouseClicked(ImGuiMouseButton_Right);
|
||||
int mw = ImGui::GetIO().MouseWheel;
|
||||
int mw = io.MouseWheel;
|
||||
bool onDigit = false;
|
||||
bool hovered = false;
|
||||
|
||||
@ -174,7 +176,7 @@ void FrequencySelect::draw() {
|
||||
moveCursorToDigit(i + 1);
|
||||
}
|
||||
|
||||
auto chars = ImGui::GetIO().InputQueueCharacters;
|
||||
auto chars = io.InputQueueCharacters;
|
||||
|
||||
// For each keyboard characters, type it
|
||||
for (int j = 0; j < chars.Size; j++) {
|
||||
@ -194,6 +196,34 @@ void FrequencySelect::draw() {
|
||||
}
|
||||
}
|
||||
digitHovered = hovered;
|
||||
|
||||
if (isInArea(mousePos, digitTopMins[0], digitBottomMaxs[11])) {
|
||||
bool shortcutKey = io.ConfigMacOSXBehaviors ? (io.KeyMods == ImGuiKeyModFlags_Super) : (io.KeyMods == ImGuiKeyModFlags_Ctrl);
|
||||
bool ctrlOnly = (io.KeyMods == ImGuiKeyModFlags_Ctrl);
|
||||
bool shiftOnly = (io.KeyMods == ImGuiKeyModFlags_Shift);
|
||||
bool copy = ((shortcutKey && ImGui::IsKeyPressed(ImGuiKey_C)) || (ctrlOnly && ImGui::IsKeyPressed(ImGuiKey_Insert)));
|
||||
bool paste = ((shortcutKey && ImGui::IsKeyPressed(ImGuiKey_V)) || (shiftOnly && ImGui::IsKeyPressed(ImGuiKey_Insert)));
|
||||
if (copy) {
|
||||
// Convert the freqency to a string
|
||||
std::string freqStr = hrfreq::toString(frequency);
|
||||
|
||||
// Write it to the clipboard
|
||||
ImGui::SetClipboardText(freqStr.c_str());
|
||||
}
|
||||
if (paste) {
|
||||
// Attempt to parse the clipboard as a number
|
||||
const char* clip = ImGui::GetClipboardText();
|
||||
|
||||
// If the clipboard is not empty, attempt to parse it
|
||||
if (clip) {
|
||||
double newFreq;
|
||||
if (hrfreq::fromString(clip, newFreq)) {
|
||||
setFrequency(abs(newFreq));
|
||||
frequencyChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t freq = 0;
|
||||
|
120
core/src/utils/hrfreq.cpp
Normal file
120
core/src/utils/hrfreq.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
#include "hrfreq.h"
|
||||
#include <utils/flog.h>
|
||||
|
||||
namespace hrfreq {
|
||||
|
||||
|
||||
std::string toString(double freq) {
|
||||
// Determine the scale
|
||||
int maxDecimals = 0;
|
||||
const char* suffix = "Hz";
|
||||
if (freq >= 1e9) {
|
||||
freq /= 1e9;
|
||||
maxDecimals = 9;
|
||||
suffix = "GHz";
|
||||
}
|
||||
else if (freq >= 1e6) {
|
||||
freq /= 1e6;
|
||||
maxDecimals = 6;
|
||||
suffix = "MHz";
|
||||
}
|
||||
else if (freq >= 1e3) {
|
||||
freq /= 1e3;
|
||||
maxDecimals = 3;
|
||||
suffix = "KHz";
|
||||
}
|
||||
|
||||
// Convert to string (TODO: Not sure if limiting the decimals rounds)
|
||||
char numBuf[128];
|
||||
int numLen = sprintf(numBuf, "%0.*lf", maxDecimals, freq);
|
||||
|
||||
// If there is a decimal point, remove the useless zeros
|
||||
if (maxDecimals) {
|
||||
for (int i = numLen-1; i >= 0; i--) {
|
||||
bool dot = (numBuf[i] == '.');
|
||||
if (numBuf[i] != '0' && !dot) { break; }
|
||||
numBuf[i] = 0;
|
||||
if (dot) { break; }
|
||||
}
|
||||
}
|
||||
|
||||
// Concat the suffix
|
||||
char finalBuf[128];
|
||||
sprintf(finalBuf, "%s%s", numBuf, suffix);
|
||||
|
||||
// Return the final string
|
||||
return finalBuf;
|
||||
}
|
||||
|
||||
bool isNumeric(char c) {
|
||||
return std::isdigit(c) || c == '+' || c == '-' || c == '.' || c == ',';
|
||||
}
|
||||
|
||||
bool fromString(const std::string& str, double& freq) {
|
||||
// Skip non-numeric characters
|
||||
int i = 0;
|
||||
char c;
|
||||
for (; i < str.size(); i++) {
|
||||
if (isNumeric(str[i])) { break; }
|
||||
}
|
||||
|
||||
// Extract the numeric part
|
||||
std::string numeric;
|
||||
for (; i < str.size(); i++) {
|
||||
// Get the character
|
||||
c = str[i];
|
||||
|
||||
// If it's a letter, stop
|
||||
if (std::isalpha(c)) { break; }
|
||||
|
||||
// If isn't numeric, skip it
|
||||
if (!isNumeric(c)) { continue; }
|
||||
|
||||
// If it's a comma, skip it for now. This enforces a dot as a decimal point
|
||||
if (c == ',') { continue; }
|
||||
|
||||
// Add the character to the numeric string
|
||||
numeric += c;
|
||||
}
|
||||
|
||||
// Attempt to parse the numeric part
|
||||
double num;
|
||||
try {
|
||||
num = std::stod(numeric);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
flog::error("Failed to parse numeric part: '{}'", numeric);
|
||||
return false;
|
||||
}
|
||||
|
||||
// If no more text is available, assume the numeric part gives a frequency in Hz
|
||||
if (i == str.size()) {
|
||||
flog::warn("No unit given, assuming it's Hz");
|
||||
freq = num;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Scale the numeric value depending on the first scale character
|
||||
char scale = std::toupper(str[i]);
|
||||
switch (scale) {
|
||||
case 'G':
|
||||
num *= 1e9;
|
||||
break;
|
||||
case 'M':
|
||||
num *= 1e6;
|
||||
break;
|
||||
case 'K':
|
||||
num *= 1e3;
|
||||
break;
|
||||
case 'H':
|
||||
break;
|
||||
default:
|
||||
flog::warn("Unknown frequency scale: '{}'", scale);
|
||||
break;
|
||||
}
|
||||
|
||||
// Return the frequency
|
||||
freq = num;
|
||||
return true; // TODO
|
||||
}
|
||||
}
|
19
core/src/utils/hrfreq.h
Normal file
19
core/src/utils/hrfreq.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
namespace hrfreq {
|
||||
/**
|
||||
* Convert a frequency to a human-readable string.
|
||||
* @param freq Frequency in Hz.
|
||||
* @return Human-readable representation of the frequency.
|
||||
*/
|
||||
std::string toString(double freq);
|
||||
|
||||
/**
|
||||
* Convert a human-readable representation of a frequency to a frequency value.
|
||||
* @param str String containing the human-readable frequency.
|
||||
* @param freq Value to write the decoded frequency to.
|
||||
* @return True on success, false otherwise.
|
||||
*/
|
||||
bool fromString(const std::string& str, double& freq);
|
||||
}
|
@ -39,6 +39,7 @@ bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules
|
||||
bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules/hackrf_source/hackrf_source.dylib
|
||||
bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules/hermes_source/hermes_source.dylib
|
||||
bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules/limesdr_source/limesdr_source.dylib
|
||||
bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules/network_source/network_source.dylib
|
||||
bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules/perseus_source/perseus_source.dylib
|
||||
bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules/plutosdr_source/plutosdr_source.dylib
|
||||
bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules/rfnm_source/rfnm_source.dylib
|
||||
|
@ -35,6 +35,8 @@ cp $build_dir/source_modules/hermes_source/Release/hermes_source.dll sdrpp_windo
|
||||
cp $build_dir/source_modules/limesdr_source/Release/limesdr_source.dll sdrpp_windows_x64/modules/
|
||||
cp 'C:/Program Files/PothosSDR/bin/LimeSuite.dll' sdrpp_windows_x64/
|
||||
|
||||
cp $build_dir/source_modules/network_source/Release/network_source.dll sdrpp_windows_x64/modules/
|
||||
|
||||
cp $build_dir/source_modules/perseus_source/Release/perseus_source.dll sdrpp_windows_x64/modules/
|
||||
cp 'C:/Program Files/PothosSDR/bin/perseus-sdr.dll' sdrpp_windows_x64/
|
||||
|
||||
|
@ -52,9 +52,22 @@ public:
|
||||
sampleTypes.define(wav::SAMP_TYPE_INT32, "Int32", wav::SAMP_TYPE_INT32);
|
||||
sampleTypes.define(wav::SAMP_TYPE_FLOAT32, "Float32", wav::SAMP_TYPE_FLOAT32);
|
||||
|
||||
// Define retroactive buffer sizes
|
||||
retroBufSizes.define(0, "None", 0);
|
||||
retroBufSizes.define(1 << 18, "256MB", 1 << 18);
|
||||
retroBufSizes.define(1 << 19, "512MB", 1 << 19);
|
||||
retroBufSizes.define(1 << 20, "1GB", 1 << 20);
|
||||
retroBufSizes.define(1 << 21, "2GB", 1 << 21);
|
||||
retroBufSizes.define(1 << 22, "4GB", 1 << 22);
|
||||
retroBufSizes.define(1 << 23, "8GB", 1 << 23);
|
||||
retroBufSizes.define(1 << 24, "16GB", 1 << 24);
|
||||
retroBufSizes.define(1 << 25, "32GB", 1 << 25);
|
||||
retroBufSizes.define(1 << 26, "64GB", 1 << 26);
|
||||
|
||||
// Load default config for option lists
|
||||
containerId = containers.valueId(wav::FORMAT_WAV);
|
||||
sampleTypeId = sampleTypes.valueId(wav::SAMP_TYPE_INT16);
|
||||
retroBufSizeId = retroBufSizes.nameId("None");
|
||||
|
||||
// Load config
|
||||
config.acquire();
|
||||
@ -70,6 +83,9 @@ public:
|
||||
if (config.conf[name].contains("sampleType") && sampleTypes.keyExists(config.conf[name]["sampleType"])) {
|
||||
sampleTypeId = sampleTypes.keyId(config.conf[name]["sampleType"]);
|
||||
}
|
||||
if (config.conf[name].contains("retroBufferSize") && retroBufSizes.keyExists(config.conf[name]["retroBufferSize"])) {
|
||||
retroBufSizeId = retroBufSizes.keyId(config.conf[name]["retroBufferSize"]);
|
||||
}
|
||||
if (config.conf[name].contains("audioStream")) {
|
||||
selectedStreamName = config.conf[name]["audioStream"];
|
||||
}
|
||||
@ -282,6 +298,14 @@ private:
|
||||
config.release(true);
|
||||
}
|
||||
|
||||
ImGui::LeftLabel("Retroactive buffer");
|
||||
ImGui::FillWidth();
|
||||
if (ImGui::Combo(CONCAT("##_recorder_retro_buf_size_", _this->name), &_this->retroBufSizeId, _this->retroBufSizes.txt)) {
|
||||
config.acquire();
|
||||
config.conf[_this->name]["retroBufferSize"] = _this->retroBufSizes.key(_this->retroBufSizeId);
|
||||
config.release(true);
|
||||
}
|
||||
|
||||
if (_this->recording) { style::endDisabled(); }
|
||||
|
||||
// Show additional audio options
|
||||
@ -566,11 +590,13 @@ private:
|
||||
|
||||
OptionList<std::string, wav::Format> containers;
|
||||
OptionList<int, wav::SampleType> sampleTypes;
|
||||
OptionList<int64_t, int64_t> retroBufSizes;
|
||||
FolderSelect folderSelect;
|
||||
|
||||
int recMode = RECORDER_MODE_AUDIO;
|
||||
int containerId;
|
||||
int sampleTypeId;
|
||||
int retroBufSizeId;
|
||||
bool stereo = true;
|
||||
std::string selectedStreamName = "";
|
||||
float audioVolume = 1.0f;
|
||||
|
12
readme.md
12
readme.md
@ -324,13 +324,13 @@ Modules in beta are still included in releases for the most part but not enabled
|
||||
| audio_source | Working | rtaudio | OPT_BUILD_AUDIO_SOURCE | ✅ | ✅ | ✅ |
|
||||
| bladerf_source | Working | libbladeRF | OPT_BUILD_BLADERF_SOURCE | ⛔ | ✅ (not Debian Buster) | ✅ |
|
||||
| file_source | Working | - | OPT_BUILD_FILE_SOURCE | ✅ | ✅ | ✅ |
|
||||
| fobossdr_source | Beta | libfobos | OPT_BUILD_FOBOSSDR_SOURCE | ✅ | ✅ | ✅ |
|
||||
| fobossdr_source | Working | libfobos | OPT_BUILD_FOBOSSDR_SOURCE | ✅ | ✅ | ✅ |
|
||||
| hackrf_source | Working | libhackrf | OPT_BUILD_HACKRF_SOURCE | ✅ | ✅ | ✅ |
|
||||
| harogic_source | Beta | htra_api | OPT_BUILD_HAROGIC_SOURCE | ⛔ | ⛔ | ✅ |
|
||||
| hermes_source | Beta | - | OPT_BUILD_HERMES_SOURCE | ✅ | ✅ | ✅ |
|
||||
| kcsdr_source | Unfinished | libkcsdr | OPT_BUILD_KCSDR_SOURCE | ⛔ | ⛔ | ⛔ |
|
||||
| limesdr_source | Working | liblimesuite | OPT_BUILD_LIMESDR_SOURCE | ⛔ | ✅ | ✅ |
|
||||
| network_source | Unfinished | - | OPT_BUILD_NETWORK_SOURCE | ✅ | ✅ | ⛔ |
|
||||
| network_source | Beta | - | OPT_BUILD_NETWORK_SOURCE | ✅ | ✅ | ✅ |
|
||||
| perseus_source | Beta | libperseus-sdr | OPT_BUILD_PERSEUS_SOURCE | ⛔ | ✅ | ✅ |
|
||||
| plutosdr_source | Working | libiio, libad9361 | OPT_BUILD_PLUTOSDR_SOURCE | ✅ | ✅ | ✅ |
|
||||
| rfnm_source | Beta | librfnm | OPT_BUILD_RFNM_SOURCE | ⛔ | ✅ | ✅ |
|
||||
@ -352,8 +352,8 @@ Modules in beta are still included in releases for the most part but not enabled
|
||||
| android_audio_sink | Working | - | OPT_BUILD_ANDROID_AUDIO_SINK | ⛔ | ✅ | ✅ (Android only) |
|
||||
| audio_sink | Working | rtaudio | OPT_BUILD_AUDIO_SINK | ✅ | ✅ | ✅ |
|
||||
| network_sink | Working | - | OPT_BUILD_NETWORK_SINK | ✅ | ✅ | ✅ |
|
||||
| new_portaudio_sink | Beta | portaudio | OPT_BUILD_NEW_PORTAUDIO_SINK | ⛔ | ✅ | ⛔ |
|
||||
| portaudio_sink | Beta | portaudio | OPT_BUILD_PORTAUDIO_SINK | ⛔ | ✅ | ⛔ |
|
||||
| new_portaudio_sink | Working | portaudio | OPT_BUILD_NEW_PORTAUDIO_SINK | ⛔ | ✅ | ⛔ |
|
||||
| portaudio_sink | Working | portaudio | OPT_BUILD_PORTAUDIO_SINK | ⛔ | ✅ | ⛔ |
|
||||
|
||||
## Decoders
|
||||
|
||||
@ -419,8 +419,8 @@ If you still have an issue, please open an issue about it or ask on the discord.
|
||||
|
||||
# Contributing
|
||||
|
||||
Feel free to submit pull requests and report bugs via the GitHub issue tracker.
|
||||
I will soon publish a contributing.md listing the code style to use.
|
||||
Feel free to submit band plans via the GitHub issue tracker.
|
||||
For code changes, please create a feature request instead.
|
||||
|
||||
# Credits
|
||||
|
||||
|
201
root/res/bandplans/ireland.json
Normal file
201
root/res/bandplans/ireland.json
Normal file
@ -0,0 +1,201 @@
|
||||
{
|
||||
"name": "Ireland",
|
||||
"country_name": "Republic Of Ireland",
|
||||
"country_code": "IE",
|
||||
"author_name": "Oskar Dudek",
|
||||
"author_url": "",
|
||||
"bands": [
|
||||
{
|
||||
"name": "2200m Ham Band",
|
||||
"type": "amateur",
|
||||
"start": 135700,
|
||||
"end": 137800
|
||||
},
|
||||
{
|
||||
"name": "Long wave",
|
||||
"type": "broadcast",
|
||||
"start": 148500,
|
||||
"end": 282500
|
||||
},
|
||||
{
|
||||
"name": "AM broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 531000,
|
||||
"end": 1602000
|
||||
},
|
||||
{
|
||||
"name": "160m ham band",
|
||||
"type": "amateur",
|
||||
"start": 1810000,
|
||||
"end": 2000000
|
||||
},
|
||||
{
|
||||
"name": "120m SW broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 2300000,
|
||||
"end": 2495000
|
||||
},
|
||||
{
|
||||
"name": "90m SW Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 3200000,
|
||||
"end": 3400000
|
||||
},
|
||||
{
|
||||
"name": "80m ham band",
|
||||
"type": "amateur",
|
||||
"start": 3500000,
|
||||
"end": 3800000
|
||||
},
|
||||
{
|
||||
"name": "75m SW Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 3900000,
|
||||
"end": 4000000
|
||||
},
|
||||
{
|
||||
"name": "60m SW Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 4750000,
|
||||
"end": 5060000
|
||||
},
|
||||
{
|
||||
"name": "60m ham band",
|
||||
"type": "amateur",
|
||||
"start": 5351500,
|
||||
"end": 5366500
|
||||
},
|
||||
{
|
||||
"name": "49m SW Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 5900000,
|
||||
"end": 6200000
|
||||
},
|
||||
{
|
||||
"name": "40m ham band",
|
||||
"type": "amateur",
|
||||
"start": 7000000,
|
||||
"end": 7200000
|
||||
},
|
||||
{
|
||||
"name": "40m SW Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 7200000,
|
||||
"end": 7450000
|
||||
},
|
||||
{
|
||||
"name": "31m SW Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 9400000,
|
||||
"end": 9900000
|
||||
},
|
||||
{
|
||||
"name": "30m ham band",
|
||||
"type": "amateur",
|
||||
"start": 10100000,
|
||||
"end": 10150000
|
||||
},
|
||||
{
|
||||
"name": "25m SW Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 11600000,
|
||||
"end": 12100000
|
||||
},
|
||||
{
|
||||
"name": "22m SW Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 13570000,
|
||||
"end": 13870000
|
||||
},
|
||||
{
|
||||
"name": "20m ham band",
|
||||
"type": "amateur",
|
||||
"start": 14000000,
|
||||
"end": 14350000
|
||||
},
|
||||
{
|
||||
"name": "19m SW Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 15100000,
|
||||
"end": 15800000
|
||||
},
|
||||
{
|
||||
"name": "17m ham band",
|
||||
"type": "amateur",
|
||||
"start": 18068000,
|
||||
"end": 18168000
|
||||
},
|
||||
{
|
||||
"name": "16m SW Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 17480000,
|
||||
"end": 17900000
|
||||
},
|
||||
{
|
||||
"name": "15m SW Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 18900000,
|
||||
"end": 19020000
|
||||
},
|
||||
{
|
||||
"name": "15m ham band",
|
||||
"type": "amateur",
|
||||
"start": 21000000,
|
||||
"end": 21450000
|
||||
},
|
||||
{
|
||||
"name": "13m SW Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 21450000,
|
||||
"end": 21850000
|
||||
},
|
||||
{
|
||||
"name": "12m ham band",
|
||||
"type": "amateur",
|
||||
"start": 24890000,
|
||||
"end": 24990000
|
||||
},
|
||||
{
|
||||
"name": "11m SW Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 25670000,
|
||||
"end": 26100000
|
||||
},
|
||||
{
|
||||
"name": "10m ham band",
|
||||
"type": "amateur",
|
||||
"start": 28000000,
|
||||
"end": 29700000
|
||||
},
|
||||
{
|
||||
"name": "FM Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 87500000,
|
||||
"end": 108000000
|
||||
},
|
||||
{
|
||||
"name": "6m ham band",
|
||||
"type": "amateur",
|
||||
"start": 50000000,
|
||||
"end": 52000000
|
||||
},
|
||||
{
|
||||
"name": "4m ham band",
|
||||
"type": "amateur",
|
||||
"start": 70000000,
|
||||
"end": 70500000
|
||||
},
|
||||
{
|
||||
"name": "2m ham band",
|
||||
"type": "amateur",
|
||||
"start": 144000000,
|
||||
"end": 146000000
|
||||
},
|
||||
{
|
||||
"name": "70cm ham band",
|
||||
"type": "amateur",
|
||||
"start": 430000000,
|
||||
"end": 440000000
|
||||
}
|
||||
]
|
||||
}
|
549
root/res/bandplans/republic-of-korea.json
Normal file
549
root/res/bandplans/republic-of-korea.json
Normal file
@ -0,0 +1,549 @@
|
||||
{
|
||||
"name": "Republic of Korea",
|
||||
"country_name": "Republic of Korea",
|
||||
"country_code": "KR",
|
||||
"author_name": "SeoyeonBae",
|
||||
"author_url": "https://github.com/bsy0317",
|
||||
"bands": [
|
||||
{
|
||||
"name": "Radio Navigation",
|
||||
"type": "aviation",
|
||||
"start": 8300,
|
||||
"end": 14000
|
||||
},
|
||||
{
|
||||
"name": "Coastal Telegraph",
|
||||
"type": "marine",
|
||||
"start": 14000,
|
||||
"end": 19950
|
||||
},
|
||||
{
|
||||
"name": "Standard Frequency Time Signal",
|
||||
"type": "utility",
|
||||
"start": 19950,
|
||||
"end": 20250
|
||||
},
|
||||
{
|
||||
"name": "Coastal Telegraph",
|
||||
"type": "marine",
|
||||
"start": 20250,
|
||||
"end": 70000
|
||||
},
|
||||
{
|
||||
"name": "Radio Navigation",
|
||||
"type": "navigation",
|
||||
"start": 70000,
|
||||
"end": 160000
|
||||
},
|
||||
{
|
||||
"name": "Aviation Radio Navigation",
|
||||
"type": "aviation",
|
||||
"start": 160000,
|
||||
"end": 285000
|
||||
},
|
||||
{
|
||||
"name": "Aviation Maritime Radiobeacon",
|
||||
"type": "aviation",
|
||||
"start": 285000,
|
||||
"end": 325000
|
||||
},
|
||||
{
|
||||
"name": "Aviation Radio Navigation",
|
||||
"type": "aviation",
|
||||
"start": 325000,
|
||||
"end": 472000
|
||||
},
|
||||
{
|
||||
"name": "Amateur",
|
||||
"type": "amateur",
|
||||
"start": 472000,
|
||||
"end": 479000
|
||||
},
|
||||
{
|
||||
"name": "International Distress Safety Call",
|
||||
"type": "marine",
|
||||
"start": 479000,
|
||||
"end": 505000
|
||||
},
|
||||
{
|
||||
"name": "Maritime Telegraph",
|
||||
"type": "marine",
|
||||
"start": 505000,
|
||||
"end": 526500
|
||||
},
|
||||
{
|
||||
"name": "Standard Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 526500,
|
||||
"end": 1606500
|
||||
},
|
||||
{
|
||||
"name": "Radiobuoy",
|
||||
"type": "navigation",
|
||||
"start": 1606500,
|
||||
"end": 1800000
|
||||
},
|
||||
{
|
||||
"name": "Amateur Station",
|
||||
"type": "amateur",
|
||||
"start": 1800000,
|
||||
"end": 1825000
|
||||
},
|
||||
{
|
||||
"name": "Radiobuoy Control LORAN",
|
||||
"type": "radiolocation",
|
||||
"start": 1825000,
|
||||
"end": 2000000
|
||||
},
|
||||
{
|
||||
"name": "Radiobuoy",
|
||||
"type": "fixed",
|
||||
"start": 2000000,
|
||||
"end": 2065000
|
||||
},
|
||||
{
|
||||
"name": "Distress Call",
|
||||
"type": "marine",
|
||||
"start": 2065000,
|
||||
"end": 2107000
|
||||
},
|
||||
{
|
||||
"name": "International Distress Search and Rescue",
|
||||
"type": "mobile",
|
||||
"start": 2173500,
|
||||
"end": 2190500
|
||||
},
|
||||
{
|
||||
"name": "Road Management",
|
||||
"type": "fixed",
|
||||
"start": 2194000,
|
||||
"end": 2495000
|
||||
},
|
||||
{
|
||||
"name": "Standard Frequency Time Signal",
|
||||
"type": "utility",
|
||||
"start": 2495000,
|
||||
"end": 2505000
|
||||
},
|
||||
{
|
||||
"name": "Ship Station Telephone",
|
||||
"type": "fixed",
|
||||
"start": 2505000,
|
||||
"end": 2850000
|
||||
},
|
||||
{
|
||||
"name": "Aviation Mobile R",
|
||||
"type": "aviation",
|
||||
"start": 2850000,
|
||||
"end": 3025000
|
||||
},
|
||||
{
|
||||
"name": "Aviation Mobile OR",
|
||||
"type": "aviation",
|
||||
"start": 3025000,
|
||||
"end": 3155000
|
||||
},
|
||||
{
|
||||
"name": "Aviation Mobile R",
|
||||
"type": "aviation",
|
||||
"start": 3400000,
|
||||
"end": 3500000
|
||||
},
|
||||
{
|
||||
"name": "Amateur Station",
|
||||
"type": "amateur",
|
||||
"start": 3500000,
|
||||
"end": 3550000
|
||||
},
|
||||
{
|
||||
"name": "Experimental Station",
|
||||
"type": "fixed",
|
||||
"start": 3550000,
|
||||
"end": 3790000
|
||||
},
|
||||
{
|
||||
"name": "Amateur Station",
|
||||
"type": "amateur",
|
||||
"start": 3790000,
|
||||
"end": 3800000
|
||||
},
|
||||
{
|
||||
"name": "Shortwave Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 3900000,
|
||||
"end": 3950000
|
||||
},
|
||||
{
|
||||
"name": "Standard Frequency Time Signal",
|
||||
"type": "utility",
|
||||
"start": 3995000,
|
||||
"end": 4005000
|
||||
},
|
||||
{
|
||||
"name": "Ship Station Telephone",
|
||||
"type": "marine",
|
||||
"start": 4005000,
|
||||
"end": 4063000
|
||||
},
|
||||
{
|
||||
"name": "Oceanographic Data",
|
||||
"type": "marine",
|
||||
"start": 4063000,
|
||||
"end": 4065000
|
||||
},
|
||||
{
|
||||
"name": "Ship Station Duplex Telephone",
|
||||
"type": "marine",
|
||||
"start": 4065000,
|
||||
"end": 4146000
|
||||
},
|
||||
{
|
||||
"name": "Ship Station Simplex Telephone",
|
||||
"type": "marine",
|
||||
"start": 4146000,
|
||||
"end": 4152000
|
||||
},
|
||||
{
|
||||
"name": "Ship Station Wideband Telegraph Fax",
|
||||
"type": "marine",
|
||||
"start": 4152000,
|
||||
"end": 4172000
|
||||
},
|
||||
{
|
||||
"name": "Ship Station Narrowband",
|
||||
"type": "marine",
|
||||
"start": 4172000,
|
||||
"end": 4181750
|
||||
},
|
||||
{
|
||||
"name": "Ship Station A1A Morse Code Communication",
|
||||
"type": "marine",
|
||||
"start": 4186750,
|
||||
"end": 4202250
|
||||
},
|
||||
{
|
||||
"name": "Radiolocation",
|
||||
"type": "radiolocation",
|
||||
"start": 4438000,
|
||||
"end": 4488000
|
||||
},
|
||||
{
|
||||
"name": "Calling Response",
|
||||
"type": "fixed",
|
||||
"start": 4488000,
|
||||
"end": 4650000
|
||||
},
|
||||
{
|
||||
"name": "Aviation Mobile R",
|
||||
"type": "aviation",
|
||||
"start": 4650000,
|
||||
"end": 4850000
|
||||
},
|
||||
{
|
||||
"name": "Standard Frequency Time Signal",
|
||||
"type": "utility",
|
||||
"start": 4995000,
|
||||
"end": 5005000
|
||||
},
|
||||
{
|
||||
"name": "Search Rescue",
|
||||
"type": "aviation",
|
||||
"start": 5480000,
|
||||
"end": 5730000
|
||||
},
|
||||
{
|
||||
"name": "Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 5900000,
|
||||
"end": 5950000
|
||||
},
|
||||
{
|
||||
"name": "Shortwave Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 5950000,
|
||||
"end": 6200000
|
||||
},
|
||||
{
|
||||
"name": "Amateur Station",
|
||||
"type": "amateur",
|
||||
"start": 7000000,
|
||||
"end": 7100000
|
||||
},
|
||||
{
|
||||
"name": "Amateur Station",
|
||||
"type": "amateur",
|
||||
"start": 7100000,
|
||||
"end": 7200000
|
||||
},
|
||||
{
|
||||
"name": "Shortwave Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 7200000,
|
||||
"end": 7450000
|
||||
},
|
||||
{
|
||||
"name": "Standard Frequency Time Signal",
|
||||
"type": "utility",
|
||||
"start": 7995000,
|
||||
"end": 8005000
|
||||
},
|
||||
{
|
||||
"name": "Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 9400000,
|
||||
"end": 9500000
|
||||
},
|
||||
{
|
||||
"name": "Shortwave Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 9500000,
|
||||
"end": 9900000
|
||||
},
|
||||
{
|
||||
"name": "Standard Frequency Time Signal",
|
||||
"type": "utility",
|
||||
"start": 9995000,
|
||||
"end": 10005000
|
||||
},
|
||||
{
|
||||
"name": "Amateur Station",
|
||||
"type": "amateur",
|
||||
"start": 10100000,
|
||||
"end": 10150000
|
||||
},
|
||||
{
|
||||
"name": "Aviation Mobile",
|
||||
"type": "aviation",
|
||||
"start": 10150000,
|
||||
"end": 11600000
|
||||
},
|
||||
{
|
||||
"name": "Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 11600000,
|
||||
"end": 11650000
|
||||
},
|
||||
{
|
||||
"name": "Shortwave Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 11650000,
|
||||
"end": 12050000
|
||||
},
|
||||
{
|
||||
"name": "Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 12050000,
|
||||
"end": 12100000
|
||||
},
|
||||
{
|
||||
"name": "Aviation Mobile",
|
||||
"type": "aviation",
|
||||
"start": 13260000,
|
||||
"end": 13360000
|
||||
},
|
||||
{
|
||||
"name": "Radio Astronomy",
|
||||
"type": "astronomy",
|
||||
"start": 13360000,
|
||||
"end": 13410000
|
||||
},
|
||||
{
|
||||
"name": "Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 13570000,
|
||||
"end": 13600000
|
||||
},
|
||||
{
|
||||
"name": "Shortwave Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 13600000,
|
||||
"end": 13800000
|
||||
},
|
||||
{
|
||||
"name": "Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 13800000,
|
||||
"end": 13870000
|
||||
},
|
||||
{
|
||||
"name": "Amateur Station",
|
||||
"type": "amateur",
|
||||
"start": 14000000,
|
||||
"end": 14350000
|
||||
},
|
||||
{
|
||||
"name": "Aviation Mobile",
|
||||
"type": "aviation",
|
||||
"start": 15010000,
|
||||
"end": 15100000
|
||||
},
|
||||
{
|
||||
"name": "Shortwave Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 15100000,
|
||||
"end": 15600000
|
||||
},
|
||||
{
|
||||
"name": "Shortwave Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 15600000,
|
||||
"end": 15800000
|
||||
},
|
||||
{
|
||||
"name": "Shortwave Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 15800000,
|
||||
"end": 15995000
|
||||
},
|
||||
{
|
||||
"name": "Standard Frequency Time Signal",
|
||||
"type": "utility",
|
||||
"start": 15995000,
|
||||
"end": 16005000
|
||||
},
|
||||
{
|
||||
"name": "Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 18900000,
|
||||
"end": 19020000
|
||||
},
|
||||
{
|
||||
"name": "Amateur Station",
|
||||
"type": "amateur",
|
||||
"start": 21000000,
|
||||
"end": 21450000
|
||||
},
|
||||
{
|
||||
"name": "Shortwave Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 21450000,
|
||||
"end": 21850000
|
||||
},
|
||||
{
|
||||
"name": "Amateur Station",
|
||||
"type": "amateur",
|
||||
"start": 24890000,
|
||||
"end": 24990000
|
||||
},
|
||||
{
|
||||
"name": "Shortwave Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 25670000,
|
||||
"end": 26100000
|
||||
},
|
||||
{
|
||||
"name": "Amateur Station",
|
||||
"type": "amateur",
|
||||
"start": 28000000,
|
||||
"end": 29700000
|
||||
},
|
||||
{
|
||||
"name": "Amateur Station",
|
||||
"type": "amateur",
|
||||
"start": 50000000,
|
||||
"end": 54000000
|
||||
},
|
||||
{
|
||||
"name": "TV Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 54000000,
|
||||
"end": 72000000
|
||||
},
|
||||
{
|
||||
"name": "Flood Warning",
|
||||
"type": "broadcast",
|
||||
"start": 72000000,
|
||||
"end": 74800000
|
||||
},
|
||||
{
|
||||
"name": "TV Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 76000000,
|
||||
"end": 88000000
|
||||
},
|
||||
{
|
||||
"name": "FM Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 88000000,
|
||||
"end": 100000000
|
||||
},
|
||||
{
|
||||
"name": "FM Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 100000000,
|
||||
"end": 108000000
|
||||
},
|
||||
{
|
||||
"name": "ILS Localizer VOR",
|
||||
"type": "fixed",
|
||||
"start": 108000000,
|
||||
"end": 117975000
|
||||
},
|
||||
{
|
||||
"name": "Amateur Station",
|
||||
"type": "amateur",
|
||||
"start": 144000000,
|
||||
"end": 146000000
|
||||
},
|
||||
{
|
||||
"name": "General Communication",
|
||||
"type": "fixed",
|
||||
"start": 146000000,
|
||||
"end": 148000000
|
||||
},
|
||||
{
|
||||
"name": "Low Power Device",
|
||||
"type": "fixed",
|
||||
"start": 162037500,
|
||||
"end": 174000000
|
||||
},
|
||||
{
|
||||
"name": "TV Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 174000000,
|
||||
"end": 216000000
|
||||
},
|
||||
{
|
||||
"name": "Low Power Device",
|
||||
"type": "fixed",
|
||||
"start": 216000000,
|
||||
"end": 230000000
|
||||
},
|
||||
{
|
||||
"name": "Low Power Device",
|
||||
"type": "fixed",
|
||||
"start": 273000000,
|
||||
"end": 322000000
|
||||
},
|
||||
{
|
||||
"name": "Personal Radio",
|
||||
"type": "fixed",
|
||||
"start": 420000000,
|
||||
"end": 470000000
|
||||
},
|
||||
{
|
||||
"name": "Public Network",
|
||||
"type": "broadcast",
|
||||
"start": 698000000,
|
||||
"end": 806000000
|
||||
},
|
||||
{
|
||||
"name": "Low Power Device",
|
||||
"type": "fixed",
|
||||
"start": 942000000,
|
||||
"end": 960000000
|
||||
},
|
||||
{
|
||||
"name": "Satellite Mobile Communication",
|
||||
"type": "fixed",
|
||||
"start": 15250000000,
|
||||
"end": 16605000000
|
||||
},
|
||||
{
|
||||
"name": "Mobile Communication",
|
||||
"type": "mobile",
|
||||
"start": 25000000000,
|
||||
"end": 37000000000
|
||||
}
|
||||
]
|
||||
}
|
@ -10,6 +10,7 @@
|
||||
#include <libbladeRF.h>
|
||||
#include <gui/smgui.h>
|
||||
#include <algorithm>
|
||||
#include <utils/optionlist.h>
|
||||
|
||||
#define CONCAT(a, b) ((std::string(a) + b).c_str())
|
||||
|
||||
@ -37,6 +38,10 @@ public:
|
||||
BladeRFSourceModule(std::string name) {
|
||||
this->name = name;
|
||||
|
||||
// Define clocks
|
||||
clocks.define("onboard", "On-Board", CLOCK_SELECT_ONBOARD);
|
||||
clocks.define("external", "External", CLOCK_SELECT_EXTERNAL);
|
||||
|
||||
sampleRate = 1000000.0;
|
||||
|
||||
handler.ctx = this;
|
||||
@ -267,6 +272,15 @@ public:
|
||||
}
|
||||
config.release(true);
|
||||
|
||||
// Load clock source
|
||||
clkId = clocks.keyId("onboard");
|
||||
if (config.conf["devices"][selectedSerial].contains("clock")) {
|
||||
std::string clkStr = config.conf["devices"][selectedSerial]["clock"];
|
||||
if (clocks.keyExists(clkStr)) {
|
||||
clkId = clocks.keyId(clkStr);
|
||||
}
|
||||
}
|
||||
|
||||
// Load gain mode
|
||||
if (config.conf["devices"][selectedSerial].contains("gainMode")) {
|
||||
std::string gm = config.conf["devices"][selectedSerial]["gainMode"];
|
||||
@ -364,6 +378,7 @@ private:
|
||||
if (_this->bufferSize < 1024) { _this->bufferSize = 1024; }
|
||||
|
||||
// Setup device parameters
|
||||
_this->setClockSource(_this->clocks[_this->clkId]);
|
||||
bladerf_set_sample_rate(_this->openDev, BLADERF_CHANNEL_RX(_this->chanId), _this->sampleRate, NULL);
|
||||
bladerf_set_frequency(_this->openDev, BLADERF_CHANNEL_RX(_this->chanId), _this->freq);
|
||||
bladerf_set_bandwidth(_this->openDev, BLADERF_CHANNEL_RX(_this->chanId), (_this->bwId == _this->bandwidths.size()) ? std::clamp<uint64_t>(_this->sampleRate, _this->bwRange->min, _this->bwRange->max) : _this->bandwidths[_this->bwId], NULL);
|
||||
@ -486,6 +501,19 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
SmGui::LeftLabel("Clock Source");
|
||||
SmGui::FillWidth();
|
||||
if (SmGui::Combo(CONCAT("##_balderf_clk_sel_", _this->name), &_this->clkId, _this->clocks.txt)) {
|
||||
if (_this->running) {
|
||||
_this->setClockSource(_this->clocks[_this->clkId]);
|
||||
}
|
||||
if (_this->selectedSerial != "") {
|
||||
config.acquire();
|
||||
config.conf["devices"][_this->selectedSerial]["clock"] = _this->clocks.key(_this->clkId);
|
||||
config.release(true);
|
||||
}
|
||||
}
|
||||
|
||||
// General config BS
|
||||
SmGui::LeftLabel("Gain control mode");
|
||||
SmGui::FillWidth();
|
||||
@ -537,6 +565,15 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void setClockSource(bladerf_clock_select clk) {
|
||||
if (selectedBladeType == BLADERF_TYPE_V1) {
|
||||
bladerf_set_smb_mode(openDev, (clk == CLOCK_SELECT_EXTERNAL) ? BLADERF_SMB_MODE_INPUT : BLADERF_SMB_MODE_DISABLED);
|
||||
}
|
||||
else {
|
||||
bladerf_set_clock_select(openDev, clk);
|
||||
}
|
||||
}
|
||||
|
||||
void worker() {
|
||||
int16_t* buffer = new int16_t[bufferSize * 2];
|
||||
bladerf_metadata meta;
|
||||
@ -565,6 +602,7 @@ private:
|
||||
int devId = 0;
|
||||
int srId = 0;
|
||||
int bwId = 0;
|
||||
int clkId = 0;
|
||||
int chanId = 0;
|
||||
int gainMode = 0;
|
||||
bool streamingEnabled = false;
|
||||
@ -580,8 +618,8 @@ private:
|
||||
std::string sampleRatesTxt;
|
||||
std::vector<uint64_t> bandwidths;
|
||||
std::string bandwidthsTxt;
|
||||
|
||||
std::string channelNamesTxt;
|
||||
OptionList<std::string, bladerf_clock_select> clocks;
|
||||
|
||||
int bufferSize;
|
||||
struct bladerf_stream* rxStream;
|
||||
|
@ -36,10 +36,10 @@ enum SampleType {
|
||||
};
|
||||
|
||||
const size_t SAMPLE_TYPE_SIZE[] {
|
||||
sizeof(int8_t)*2,
|
||||
sizeof(int16_t)*2,
|
||||
sizeof(int32_t)*2,
|
||||
sizeof(float)*2,
|
||||
2*sizeof(int8_t),
|
||||
2*sizeof(int16_t),
|
||||
2*sizeof(int32_t),
|
||||
2*sizeof(float),
|
||||
};
|
||||
|
||||
class NetworkSourceModule : public ModuleManager::Instance {
|
||||
@ -58,20 +58,6 @@ public:
|
||||
handler.tuneHandler = tune;
|
||||
handler.stream = &stream;
|
||||
|
||||
// Define samplerates
|
||||
for (int i = 3000; i <= 192000; i <<= 1) {
|
||||
samplerates.define(i, getSrScaled(i), i);
|
||||
}
|
||||
for (int i = 250000; i < 1000000; i += 250000) {
|
||||
samplerates.define(i, getSrScaled(i), i);
|
||||
}
|
||||
for (int i = 1000000; i < 10000000; i += 500000) {
|
||||
samplerates.define(i, getSrScaled(i), i);
|
||||
}
|
||||
for (int i = 10000000; i <= 100000000; i += 5000000) {
|
||||
samplerates.define(i, getSrScaled(i), i);
|
||||
}
|
||||
|
||||
// Define protocols
|
||||
// protocols.define("TCP (Server)", PROTOCOL_TCP_SERVER);
|
||||
protocols.define("TCP (Client)", PROTOCOL_TCP_CLIENT);
|
||||
@ -86,8 +72,8 @@ public:
|
||||
// Load config
|
||||
config.acquire();
|
||||
if (config.conf[name].contains("samplerate")) {
|
||||
int sr = config.conf[name]["samplerate"];
|
||||
if (samplerates.keyExists(sr)) { samplerate = samplerates.value(samplerates.keyId(sr)); }
|
||||
samplerate = config.conf[name]["samplerate"];
|
||||
tempSamplerate = samplerate;
|
||||
}
|
||||
if (config.conf[name].contains("protocol")) {
|
||||
std::string protoStr = config.conf[name]["protocol"];
|
||||
@ -108,7 +94,6 @@ public:
|
||||
config.release();
|
||||
|
||||
// Set menu IDs
|
||||
srId = samplerates.valueId(samplerate);
|
||||
protoId = protocols.valueId(proto);
|
||||
sampTypeId = sampleTypes.valueId(sampType);
|
||||
|
||||
@ -228,35 +213,24 @@ private:
|
||||
if (_this->running) { SmGui::BeginDisabled(); }
|
||||
|
||||
// Hostname and port field
|
||||
if (ImGui::InputText(("##iq_exporter_host_" + _this->name).c_str(), _this->hostname, sizeof(_this->hostname))) {
|
||||
if (SmGui::InputText(("##network_source_host_" + _this->name).c_str(), _this->hostname, sizeof(_this->hostname))) {
|
||||
config.acquire();
|
||||
config.conf[_this->name]["host"] = _this->hostname;
|
||||
config.release(true);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::FillWidth();
|
||||
if (ImGui::InputInt(("##iq_exporter_port_" + _this->name).c_str(), &_this->port, 0, 0)) {
|
||||
SmGui::SameLine();
|
||||
SmGui::FillWidth();
|
||||
if (SmGui::InputInt(("##network_source_port_" + _this->name).c_str(), &_this->port, 0, 0)) {
|
||||
_this->port = std::clamp<int>(_this->port, 1, 65535);
|
||||
config.acquire();
|
||||
config.conf[_this->name]["port"] = _this->port;
|
||||
config.release(true);
|
||||
}
|
||||
|
||||
// Samplerate selector
|
||||
ImGui::LeftLabel("Samplerate");
|
||||
ImGui::FillWidth();
|
||||
if (ImGui::Combo(("##iq_exporter_sr_" + _this->name).c_str(), &_this->srId, _this->samplerates.txt)) {
|
||||
_this->samplerate = _this->samplerates.value(_this->srId);
|
||||
core::setInputSampleRate(_this->samplerate);
|
||||
config.acquire();
|
||||
config.conf[_this->name]["samplerate"] = _this->samplerates.key(_this->srId);
|
||||
config.release(true);
|
||||
}
|
||||
|
||||
// Mode protocol selector
|
||||
ImGui::LeftLabel("Protocol");
|
||||
ImGui::FillWidth();
|
||||
if (ImGui::Combo(("##iq_exporter_proto_" + _this->name).c_str(), &_this->protoId, _this->protocols.txt)) {
|
||||
SmGui::LeftLabel("Protocol");
|
||||
SmGui::FillWidth();
|
||||
if (SmGui::Combo(("##network_source_proto_" + _this->name).c_str(), &_this->protoId, _this->protocols.txt)) {
|
||||
_this->proto = _this->protocols.value(_this->protoId);
|
||||
config.acquire();
|
||||
config.conf[_this->name]["protocol"] = _this->protocols.key(_this->protoId);
|
||||
@ -264,15 +238,38 @@ private:
|
||||
}
|
||||
|
||||
// Sample type selector
|
||||
ImGui::LeftLabel("Sample type");
|
||||
ImGui::FillWidth();
|
||||
if (ImGui::Combo(("##iq_exporter_samp_" + _this->name).c_str(), &_this->sampTypeId, _this->sampleTypes.txt)) {
|
||||
SmGui::LeftLabel("Sample type");
|
||||
SmGui::FillWidth();
|
||||
if (SmGui::Combo(("##network_source_samp_" + _this->name).c_str(), &_this->sampTypeId, _this->sampleTypes.txt)) {
|
||||
_this->sampType = _this->sampleTypes.value(_this->sampTypeId);
|
||||
config.acquire();
|
||||
config.conf[_this->name]["sampleType"] = _this->sampleTypes.key(_this->sampTypeId);
|
||||
config.release(true);
|
||||
}
|
||||
|
||||
// Samplerate selector
|
||||
SmGui::LeftLabel("Samplerate");
|
||||
SmGui::FillWidth();
|
||||
if (SmGui::InputInt(("##network_source_sr_" + _this->name).c_str(), &_this->tempSamplerate)) {
|
||||
// Prevent silly values from silly users
|
||||
_this->tempSamplerate = std::max<int>(_this->tempSamplerate, 1000);
|
||||
}
|
||||
bool applyEn = (!_this->running && _this->tempSamplerate != _this->samplerate);
|
||||
if (!applyEn) { SmGui::BeginDisabled(); }
|
||||
SmGui::FillWidth();
|
||||
if (SmGui::Button(("Apply##network_source_apply_" + _this->name).c_str())) {
|
||||
_this->samplerate = _this->tempSamplerate;
|
||||
core::setInputSampleRate(_this->samplerate);
|
||||
config.acquire();
|
||||
config.conf[_this->name]["samplerate"] = _this->samplerate;
|
||||
config.release(true);
|
||||
}
|
||||
if (!applyEn) { SmGui::EndDisabled(); }
|
||||
|
||||
if (_this->tempSamplerate != _this->samplerate) {
|
||||
SmGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "Warning: Samplerate not applied yet");
|
||||
}
|
||||
|
||||
if (_this->running) { SmGui::EndDisabled(); }
|
||||
}
|
||||
|
||||
@ -280,14 +277,17 @@ private:
|
||||
// Compute sizes
|
||||
int blockSize = samplerate / 200;
|
||||
int sampleSize = SAMPLE_TYPE_SIZE[sampType];
|
||||
int frameSize = blockSize*sampleSize;
|
||||
|
||||
// Chose amount of bytes to attempt to read
|
||||
bool forceSize = (proto != PROTOCOL_UDP);
|
||||
int frameSize = sampleSize * (forceSize ? blockSize : STREAM_BUFFER_SIZE);
|
||||
|
||||
// Allocate receive buffer
|
||||
uint8_t* buffer = dsp::buffer::alloc<uint8_t>(frameSize);
|
||||
|
||||
while (true) {
|
||||
// Read samples from socket
|
||||
int bytes = sock->recv(buffer, frameSize, true);
|
||||
int bytes = sock->recv(buffer, frameSize, forceSize);
|
||||
if (bytes <= 0) { break; }
|
||||
|
||||
// Convert to CF32 (note: problem if partial sample)
|
||||
@ -325,7 +325,7 @@ private:
|
||||
double freq;
|
||||
|
||||
int samplerate = 1000000;
|
||||
int srId;
|
||||
int tempSamplerate = 1000000;
|
||||
Protocol proto = PROTOCOL_UDP;
|
||||
int protoId;
|
||||
SampleType sampType = SAMPLE_TYPE_INT16;
|
||||
@ -333,7 +333,6 @@ private:
|
||||
char hostname[1024] = "localhost";
|
||||
int port = 1234;
|
||||
|
||||
OptionList<int, int> samplerates;
|
||||
OptionList<std::string, Protocol> protocols;
|
||||
OptionList<std::string, SampleType> sampleTypes;
|
||||
|
||||
|
Reference in New Issue
Block a user