mirror of
https://github.com/eried/portapack-mayhem.git
synced 2025-01-31 00:33:25 -05:00
CTCSS in soundboard. 24 jammer chs instead of 9.
Soundboard random mode now cares about loop option. Started documenting UI.
This commit is contained in:
parent
703d8044a3
commit
607e6c5bd4
171
docs/widgets.txt
Normal file
171
docs/widgets.txt
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
~ Pretty ugly PortaPack H1 (+HAVOC) UI widget documentation ~
|
||||||
|
by @furrtek - v0.1 - 2017/02/02
|
||||||
|
Not approved at all by @Sharebrained
|
||||||
|
|
||||||
|
The display is 240 x 320 pixels.
|
||||||
|
|
||||||
|
A View is basically a rectangular zone on the screen.
|
||||||
|
Widgets (aka controls, UI elements...) go into Views.
|
||||||
|
|
||||||
|
Views can be pushed to/popped from a stack.
|
||||||
|
The main menu view is at the bottom of the stack and can't be popped.
|
||||||
|
The title bar view is a special case, it (normally) can't be hidden by pushed Views.
|
||||||
|
Since the title bar is 16 pixel high, a regular full-screen view is 240 x 304 pixels.
|
||||||
|
|
||||||
|
If the current View can be popped (removed), an arrow shows on the left of the title bar.
|
||||||
|
|
||||||
|
Kind of widgets:
|
||||||
|
|
||||||
|
==== Rectangle ====
|
||||||
|
|
||||||
|
A simple filled or outlined rectangle. No interactivity.
|
||||||
|
|
||||||
|
Constructors:
|
||||||
|
- Empty
|
||||||
|
- Rectangle(Rect, Color)
|
||||||
|
|
||||||
|
Methods:
|
||||||
|
- set_color(Color)
|
||||||
|
- set_outline(bool): Default is filled, set to true for outline only
|
||||||
|
|
||||||
|
==== Text ====
|
||||||
|
|
||||||
|
A simple text label. No interactivity.
|
||||||
|
|
||||||
|
Constructors:
|
||||||
|
- Empty
|
||||||
|
- Text(Rect)
|
||||||
|
- Text(Rect, std::string)
|
||||||
|
|
||||||
|
Methods:
|
||||||
|
- set(std::string): Updates text
|
||||||
|
|
||||||
|
==== BigFrequency (HAVOC) ====
|
||||||
|
|
||||||
|
Displays a big 7-segment style frequency value in the XXXX.xxxMHz format.
|
||||||
|
If the value is 0, ----.--- is displayed. No leading zeros. No interactivity.
|
||||||
|
|
||||||
|
Constructors:
|
||||||
|
- BigFrequency(Rect, rf::Frequency)
|
||||||
|
|
||||||
|
Methods:
|
||||||
|
- set(rf::Frequency): Updates value
|
||||||
|
|
||||||
|
==== ProgressBar (HAVOC) ====
|
||||||
|
|
||||||
|
Displays progress as an horizontal progress bar with value and maximum value.
|
||||||
|
No interactivity.
|
||||||
|
|
||||||
|
Constructors:
|
||||||
|
- ProgressBar(Rect)
|
||||||
|
|
||||||
|
Methods:
|
||||||
|
- set_max(uint32_t): Updates maximum value
|
||||||
|
- set_value(uint32_t): Updates current value
|
||||||
|
|
||||||
|
The maximum value is set by default to 100.
|
||||||
|
|
||||||
|
==== Console ====
|
||||||
|
|
||||||
|
Displays a scrolling text console. No interactivity.
|
||||||
|
|
||||||
|
Constructors:
|
||||||
|
- Console(Rect)
|
||||||
|
|
||||||
|
Methods:
|
||||||
|
- clear(): Clears text and resets cursor to top-left
|
||||||
|
- write(std::string): Adds text
|
||||||
|
- writeln(std::string): Adds text and CR + LF
|
||||||
|
|
||||||
|
==== Checkbox (HAVOC) ====
|
||||||
|
|
||||||
|
A toggle option shown as a tickable box with a text label.
|
||||||
|
Interactive: select and touch.
|
||||||
|
|
||||||
|
Constructors:
|
||||||
|
- Empty
|
||||||
|
- Checkbox(Point, size_t, std::string)
|
||||||
|
- Checkbox(Point, size_t, std::string, bool)
|
||||||
|
|
||||||
|
(Position, length of text label, text, regular size/small)
|
||||||
|
|
||||||
|
Methods:
|
||||||
|
- bool value(): Returns state
|
||||||
|
- set_text(std::string): Updates text label
|
||||||
|
- set_value(bool): Sets state
|
||||||
|
|
||||||
|
Callbacks:
|
||||||
|
- on_select: Select key press or touch. Returns state
|
||||||
|
|
||||||
|
==== Button ====
|
||||||
|
|
||||||
|
A momentary push-button. Interactive: select and touch.
|
||||||
|
|
||||||
|
Constructors:
|
||||||
|
- Empty
|
||||||
|
- Button(Rect, std::string)
|
||||||
|
|
||||||
|
Methods:
|
||||||
|
- std::string text(): Returns text
|
||||||
|
- set_text(std::string): Updates text
|
||||||
|
|
||||||
|
Callbacks:
|
||||||
|
- on_select: Select key press or touch
|
||||||
|
- on_dir: Direction keys press
|
||||||
|
- on_highlight: Focus get
|
||||||
|
|
||||||
|
==== Image ====
|
||||||
|
|
||||||
|
Shows a 1-bit bitmap. No interactivity.
|
||||||
|
|
||||||
|
Constructors:
|
||||||
|
- Empty
|
||||||
|
- Image(Rect, Bitmap*, Color, Color)
|
||||||
|
|
||||||
|
(Rect, pointer to bitmap (see bitmap.hpp), foreground, background)
|
||||||
|
|
||||||
|
Methods:
|
||||||
|
- set_bitmap(Bitmap*): Updates bitmap
|
||||||
|
- set_foreground(Color): Changes foreground color
|
||||||
|
- set_background(Color): Changes background color
|
||||||
|
- invert_colors(): Flip foreground color with background
|
||||||
|
|
||||||
|
==== ImageButton ====
|
||||||
|
|
||||||
|
Same as the Image widget, except interactive (select and touch). No methods.
|
||||||
|
|
||||||
|
Constructors:
|
||||||
|
- Empty
|
||||||
|
- ImageButton(Rect, Bitmap*, Color, Color)
|
||||||
|
|
||||||
|
(Rect, pointer to bitmap (see bitmap.hpp), foreground, background)
|
||||||
|
|
||||||
|
Callbacks:
|
||||||
|
- on_select: Select key press or touch
|
||||||
|
|
||||||
|
==== ImageOptionsField (HAVOC) ====
|
||||||
|
|
||||||
|
Options list displayed as images.
|
||||||
|
Interactive: change (jog wheel) and focus.
|
||||||
|
|
||||||
|
Constructors:
|
||||||
|
- Empty
|
||||||
|
- ImageOptionsField(Rect, options_t)
|
||||||
|
|
||||||
|
options_t is a std::vector of std::pair of unsigned char pointers to color bitmap data and an int32_t
|
||||||
|
|
||||||
|
Methods:
|
||||||
|
- set_options(options_t)
|
||||||
|
- size_t selected_index()
|
||||||
|
- size_t selected_index_value()
|
||||||
|
- set_selected_index(size_t)
|
||||||
|
- set_by_value(value_t)
|
||||||
|
|
||||||
|
Callbacks:
|
||||||
|
- on_change: Option was changed
|
||||||
|
- on_show_options: Focus get
|
||||||
|
|
||||||
|
==== OptionsField ====
|
||||||
|
==== NumberField ====
|
||||||
|
==== SymField (HAVOC) ====
|
||||||
|
==== Waveform (HAVOC) ====
|
@ -22,55 +22,55 @@
|
|||||||
|
|
||||||
#include "ctcss.hpp"
|
#include "ctcss.hpp"
|
||||||
|
|
||||||
ctcss_tone ctcss_tones[CTCSS_TONES_NB] = {
|
const ctcss_tone ctcss_tones[CTCSS_TONES_NB] = {
|
||||||
{ "XZ", 0, 67000 },
|
{ "XZ", 0, 67.000 },
|
||||||
{ "WZ", 1, 69400 },
|
{ "WZ", 1, 69.400 },
|
||||||
{ "XA", 39, 71900 },
|
{ "XA", 39, 71.900 },
|
||||||
{ "WA", 3, 74400 },
|
{ "WA", 3, 74.400 },
|
||||||
{ "XB", 4, 77000 },
|
{ "XB", 4, 77.000 },
|
||||||
{ "WB", 5, 79700 },
|
{ "WB", 5, 79.700 },
|
||||||
{ "YZ", 6, 82500 },
|
{ "YZ", 6, 82.500 },
|
||||||
{ "YA", 7, 85400 },
|
{ "YA", 7, 85.400 },
|
||||||
{ "YB", 8, 88500 },
|
{ "YB", 8, 88.500 },
|
||||||
{ "ZZ", 9, 91500 },
|
{ "ZZ", 9, 91.500 },
|
||||||
{ "ZA", 10, 94800 },
|
{ "ZA", 10, 94.800 },
|
||||||
{ "ZB", 11, 97400 },
|
{ "ZB", 11, 97.400 },
|
||||||
{ "1Z", 12, 100000 },
|
{ "1Z", 12, 100.000 },
|
||||||
{ "1A", 13, 103500 },
|
{ "1A", 13, 103.500 },
|
||||||
{ "1B", 14, 107200 },
|
{ "1B", 14, 107.200 },
|
||||||
{ "2Z", 15, 110900 },
|
{ "2Z", 15, 110.900 },
|
||||||
{ "2Z", 16, 114800 },
|
{ "2Z", 16, 114.800 },
|
||||||
{ "2B", 17, 118800 },
|
{ "2B", 17, 118.800 },
|
||||||
{ "3Z", 18, 123000 },
|
{ "3Z", 18, 123.000 },
|
||||||
{ "3A", 19, 127300 },
|
{ "3A", 19, 127.300 },
|
||||||
{ "3B", 20, 131800 },
|
{ "3B", 20, 131.800 },
|
||||||
{ "4Z", 21, 136500 },
|
{ "4Z", 21, 136.500 },
|
||||||
{ "4A", 22, 141300 },
|
{ "4A", 22, 141.300 },
|
||||||
{ "4B", 23, 146200 },
|
{ "4B", 23, 146.200 },
|
||||||
{ "5Z", 24, 151400 },
|
{ "5Z", 24, 151.400 },
|
||||||
{ "5A", 25, 156700 },
|
{ "5A", 25, 156.700 },
|
||||||
{ "--", 40, 159800 },
|
{ "--", 40, 159.800 },
|
||||||
{ "5B", 26, 162200 },
|
{ "5B", 26, 162.200 },
|
||||||
{ "--", 41, 165500 },
|
{ "--", 41, 165.500 },
|
||||||
{ "6Z", 27, 167900 },
|
{ "6Z", 27, 167.900 },
|
||||||
{ "--", 42, 171300 },
|
{ "--", 42, 171.300 },
|
||||||
{ "6A", 28, 173800 },
|
{ "6A", 28, 173.800 },
|
||||||
{ "--", 43, 177300 },
|
{ "--", 43, 177.300 },
|
||||||
{ "6B", 29, 179900 },
|
{ "6B", 29, 179.900 },
|
||||||
{ "--", 44, 183500 },
|
{ "--", 44, 183.500 },
|
||||||
{ "7Z", 30, 186200 },
|
{ "7Z", 30, 186.200 },
|
||||||
{ "--", 45, 189900 },
|
{ "--", 45, 189.900 },
|
||||||
{ "7A", 31, 192800 },
|
{ "7A", 31, 192.800 },
|
||||||
{ "--", 46, 196600 },
|
{ "--", 46, 196.600 },
|
||||||
{ "--", 47, 199500 },
|
{ "--", 47, 199.500 },
|
||||||
{ "M1", 32, 203500 },
|
{ "M1", 32, 203.500 },
|
||||||
{ "8Z", 48, 206500 },
|
{ "8Z", 48, 206.500 },
|
||||||
{ "M2", 33, 210700 },
|
{ "M2", 33, 210.700 },
|
||||||
{ "M3", 34, 218100 },
|
{ "M3", 34, 218.100 },
|
||||||
{ "M4", 35, 225700 },
|
{ "M4", 35, 225.700 },
|
||||||
{ "9Z", 49, 229100 },
|
{ "9Z", 49, 229.100 },
|
||||||
{ "--", 36, 233600 },
|
{ "--", 36, 233.600 },
|
||||||
{ "--", 37, 241800 },
|
{ "--", 37, 241.800 },
|
||||||
{ "--", 38, 250300 },
|
{ "--", 38, 250.300 },
|
||||||
{ "0Z", 50, 254100 }
|
{ "0Z", 50, 254.100 }
|
||||||
};
|
};
|
||||||
|
@ -30,9 +30,9 @@
|
|||||||
struct ctcss_tone {
|
struct ctcss_tone {
|
||||||
char PL_code[3];
|
char PL_code[3];
|
||||||
uint16_t num_code;
|
uint16_t num_code;
|
||||||
uint32_t frequency; // Hz * 1000
|
float frequency;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern ctcss_tone ctcss_tones[CTCSS_TONES_NB];
|
extern const ctcss_tone ctcss_tones[CTCSS_TONES_NB];
|
||||||
|
|
||||||
#endif/*__CTCSS_H_*/
|
#endif/*__CTCSS_H_*/
|
||||||
|
@ -32,7 +32,8 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#define JAMMER_CH_WIDTH 500000
|
#define JAMMER_CH_WIDTH 1000000
|
||||||
|
#define JAMMER_MAX_CH 24
|
||||||
|
|
||||||
using namespace portapack;
|
using namespace portapack;
|
||||||
|
|
||||||
@ -95,7 +96,7 @@ void JammerView::update_button(const uint32_t n) {
|
|||||||
void JammerView::on_retune(const rf::Frequency freq, const uint32_t range) {
|
void JammerView::on_retune(const rf::Frequency freq, const uint32_t range) {
|
||||||
if (freq) {
|
if (freq) {
|
||||||
transmitter_model.set_tuning_frequency(freq);
|
transmitter_model.set_tuning_frequency(freq);
|
||||||
text_range_number.set(to_string_dec_uint(range, 1));
|
text_range_number.set(to_string_dec_uint(range, 2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,8 +149,10 @@ JammerView::JammerView(NavigationView& nav) {
|
|||||||
value_ptr = &frequency_range[id].min;
|
value_ptr = &frequency_range[id].min;
|
||||||
|
|
||||||
auto new_view = nav.push<FrequencyKeypadView>(*value_ptr);
|
auto new_view = nav.push<FrequencyKeypadView>(*value_ptr);
|
||||||
new_view->on_changed = [this, value_ptr](rf::Frequency f) {
|
new_view->on_changed = [this, value_ptr, &button](rf::Frequency f) {
|
||||||
*value_ptr = f;
|
*value_ptr = f;
|
||||||
|
update_button(button.id);
|
||||||
|
update_range(button.id >> 1);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -235,10 +238,10 @@ JammerView::JammerView(NavigationView& nav) {
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Disable all ranges by default
|
// Disable all ranges by default
|
||||||
for (c = 0; c < 9; c++)
|
for (c = 0; c < JAMMER_MAX_CH; c++)
|
||||||
jammer_channels[c].enabled = false;
|
jammer_channels[c].enabled = false;
|
||||||
|
|
||||||
// Generate jamming "channels", maximum: 9
|
// Generate jamming "channels", maximum: JAMMER_MAX_CH
|
||||||
// Convert ranges min/max to center/bw
|
// Convert ranges min/max to center/bw
|
||||||
for (size_t r = 0; r < 3; r++) {
|
for (size_t r = 0; r < 3; r++) {
|
||||||
|
|
||||||
@ -260,24 +263,24 @@ JammerView::JammerView(NavigationView& nav) {
|
|||||||
} while (range_bw_sub >= JAMMER_CH_WIDTH);
|
} while (range_bw_sub >= JAMMER_CH_WIDTH);
|
||||||
ch_width = range_bw / num_channels;
|
ch_width = range_bw / num_channels;
|
||||||
for (c = 0; c < num_channels; c++) {
|
for (c = 0; c < num_channels; c++) {
|
||||||
if (i >= 9) {
|
if (i >= JAMMER_MAX_CH) {
|
||||||
out_of_ranges = true;
|
out_of_ranges = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
jammer_channels[i].enabled = true;
|
jammer_channels[i].enabled = true;
|
||||||
jammer_channels[i].width = ch_width;
|
jammer_channels[i].width = (ch_width * 0xFFFFFFULL) / 1536000;
|
||||||
jammer_channels[i].center = start_freq + (ch_width / 2) + (ch_width * c);
|
jammer_channels[i].center = start_freq + (ch_width / 2) + (ch_width * c);
|
||||||
jammer_channels[i].duration = 15360 * options_hop.selected_index_value();
|
jammer_channels[i].duration = 30720 * options_hop.selected_index_value();
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (i >= 9) {
|
if (i >= JAMMER_MAX_CH) {
|
||||||
out_of_ranges = true;
|
out_of_ranges = true;
|
||||||
} else {
|
} else {
|
||||||
jammer_channels[i].enabled = true;
|
jammer_channels[i].enabled = true;
|
||||||
jammer_channels[i].width = range_bw;
|
jammer_channels[i].width = (range_bw * 0xFFFFFFULL) / 1536000;
|
||||||
jammer_channels[i].center = start_freq + (range_bw / 2);
|
jammer_channels[i].center = start_freq + (range_bw / 2);
|
||||||
jammer_channels[i].duration = 15360 * options_hop.selected_index_value();
|
jammer_channels[i].duration = 30720 * options_hop.selected_index_value();
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -285,15 +288,15 @@ JammerView::JammerView(NavigationView& nav) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!out_of_ranges) {
|
if (!out_of_ranges) {
|
||||||
text_range_total.set("/" + to_string_dec_uint(i, 1));
|
text_range_total.set("/" + to_string_dec_uint(i, 2));
|
||||||
|
|
||||||
jamming = true;
|
jamming = true;
|
||||||
button_transmit.set_style(&style_cancel);
|
button_transmit.set_style(&style_cancel);
|
||||||
button_transmit.set_text("STOP");
|
button_transmit.set_text("STOP");
|
||||||
|
|
||||||
transmitter_model.set_sampling_rate(1536000U);
|
transmitter_model.set_sampling_rate(3072000U);
|
||||||
transmitter_model.set_rf_amp(true);
|
transmitter_model.set_rf_amp(true);
|
||||||
transmitter_model.set_baseband_bandwidth(1750000);
|
transmitter_model.set_baseband_bandwidth(3500000U);
|
||||||
transmitter_model.set_tx_gain(47);
|
transmitter_model.set_tx_gain(47);
|
||||||
transmitter_model.enable();
|
transmitter_model.enable();
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ private:
|
|||||||
// Free
|
// Free
|
||||||
{{ true, 945000000, 950000000 }, // GSM 900 BW:5M
|
{{ true, 945000000, 950000000 }, // GSM 900 BW:5M
|
||||||
{ false, 0, 0 },
|
{ false, 0, 0 },
|
||||||
{ true, 0, 0 }},
|
{ false, 0, 0 }},
|
||||||
|
|
||||||
// GSM-R
|
// GSM-R
|
||||||
{{ true, 921000000, 925000000 }, // GSM 900 BW:4M
|
{{ true, 921000000, 925000000 }, // GSM 900 BW:4M
|
||||||
@ -174,12 +174,12 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
Text text_range_number {
|
Text text_range_number {
|
||||||
{ 18 * 8, 4, 1 * 8, 16 },
|
{ 18 * 8, 4, 2 * 8, 16 },
|
||||||
"-"
|
"--"
|
||||||
};
|
};
|
||||||
Text text_range_total {
|
Text text_range_total {
|
||||||
{ 19 * 8, 4, 2 * 8, 16 },
|
{ 20 * 8, 4, 3 * 8, 16 },
|
||||||
"/-"
|
"/--"
|
||||||
};
|
};
|
||||||
|
|
||||||
Text text_speed {
|
Text text_speed {
|
||||||
|
@ -352,8 +352,8 @@ SystemMenuView::SystemMenuView(NavigationView& nav) {
|
|||||||
add_items<12>({ {
|
add_items<12>({ {
|
||||||
{ "Play dead", ui::Color::red(), &bitmap_icon_playdead, [&nav](){ nav.push<PlayDeadView>(); } },
|
{ "Play dead", ui::Color::red(), &bitmap_icon_playdead, [&nav](){ nav.push<PlayDeadView>(); } },
|
||||||
{ "Receivers", ui::Color::cyan(), &bitmap_icon_receiver, [&nav](){ nav.push<ReceiverMenuView>(); } },
|
{ "Receivers", ui::Color::cyan(), &bitmap_icon_receiver, [&nav](){ nav.push<ReceiverMenuView>(); } },
|
||||||
{ "Capture", ui::Color::cyan(), &bitmap_icon_capture, [&nav](){ nav.push<CaptureAppView>(); } },
|
{ "Capture", ui::Color::cyan(), &bitmap_icon_capture, [&nav](){ nav.push<NotImplementedView>(); } }, //CaptureAppView
|
||||||
{ "Replay", ui::Color::blue(), &bitmap_icon_replay, [&nav](){ nav.push<ReplayAppView>(); } },
|
{ "Replay", ui::Color::grey(), &bitmap_icon_replay, [&nav](){ nav.push<ReplayAppView>(); } },
|
||||||
{ "Code transmitters", ui::Color::green(), &bitmap_icon_codetx, [&nav](){ nav.push<TransmitterCodedMenuView>(); } },
|
{ "Code transmitters", ui::Color::green(), &bitmap_icon_codetx, [&nav](){ nav.push<TransmitterCodedMenuView>(); } },
|
||||||
{ "Audio transmitters", ui::Color::green(), &bitmap_icon_audiotx, [&nav](){ nav.push<TransmitterAudioMenuView>(); } },
|
{ "Audio transmitters", ui::Color::green(), &bitmap_icon_audiotx, [&nav](){ nav.push<TransmitterAudioMenuView>(); } },
|
||||||
{ "Close Call", ui::Color::orange(),&bitmap_icon_closecall, [&nav](){ nav.push<CloseCallView>(); } },
|
{ "Close Call", ui::Color::orange(),&bitmap_icon_closecall, [&nav](){ nav.push<CloseCallView>(); } },
|
||||||
|
@ -38,11 +38,12 @@ using namespace portapack;
|
|||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
void SoundBoardView::do_random() {
|
void SoundBoardView::do_random() {
|
||||||
uint16_t id;
|
uint32_t id;
|
||||||
|
|
||||||
chThdSleepMilliseconds(300); // 300ms
|
chThdSleepMilliseconds(500);
|
||||||
|
|
||||||
id = lfsr_iterate(lfsr_v) % max_sound;
|
lfsr_v = lfsr_iterate(lfsr_v);
|
||||||
|
id = lfsr_v % max_sound;
|
||||||
|
|
||||||
play_sound(id);
|
play_sound(id);
|
||||||
|
|
||||||
@ -67,7 +68,8 @@ void SoundBoardView::prepare_audio() {
|
|||||||
} else {
|
} else {
|
||||||
pbar.set_value(0);
|
pbar.set_value(0);
|
||||||
transmitter_model.disable();
|
transmitter_model.disable();
|
||||||
do_random();
|
if (check_loop.value())
|
||||||
|
do_random();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +100,7 @@ void SoundBoardView::on_tuning_frequency_changed(rf::Frequency f) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SoundBoardView::play_sound(uint16_t id) {
|
void SoundBoardView::play_sound(uint16_t id) {
|
||||||
uint32_t ctcss_option;
|
uint32_t ctcss_index;
|
||||||
bool ctcss_enabled;
|
bool ctcss_enabled;
|
||||||
uint32_t divider;
|
uint32_t divider;
|
||||||
|
|
||||||
@ -122,9 +124,9 @@ void SoundBoardView::play_sound(uint16_t id) {
|
|||||||
transmitter_model.set_baseband_bandwidth(1750000);
|
transmitter_model.set_baseband_bandwidth(1750000);
|
||||||
transmitter_model.enable();
|
transmitter_model.enable();
|
||||||
|
|
||||||
ctcss_option = options_ctcss.selected_index();
|
ctcss_index = options_ctcss.selected_index();
|
||||||
|
|
||||||
if (ctcss_option)
|
if (ctcss_index)
|
||||||
ctcss_enabled = true;
|
ctcss_enabled = true;
|
||||||
else
|
else
|
||||||
ctcss_enabled = false;
|
ctcss_enabled = false;
|
||||||
@ -133,9 +135,9 @@ void SoundBoardView::play_sound(uint16_t id) {
|
|||||||
|
|
||||||
baseband::set_audiotx_data(
|
baseband::set_audiotx_data(
|
||||||
divider,
|
divider,
|
||||||
number_bw.value(),
|
number_bw.value() * 1000,
|
||||||
ctcss_enabled,
|
ctcss_enabled,
|
||||||
(67109.0 * (float)_ctcss_freq)/1536000.0 // TODO: Might not be precise enough
|
(uint32_t)((ctcss_tones[ctcss_index].frequency / 1536000.0) * 0xFFFFFFFFULL)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,10 +187,6 @@ void SoundBoardView::change_page(Button& button, const KeyEvent key) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundBoardView::on_ctcss_changed(uint32_t v) {
|
|
||||||
_ctcss_freq = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
SoundBoardView::SoundBoardView(
|
SoundBoardView::SoundBoardView(
|
||||||
NavigationView& nav
|
NavigationView& nav
|
||||||
) : nav_ (nav)
|
) : nav_ (nav)
|
||||||
@ -249,9 +247,6 @@ SoundBoardView::SoundBoardView(
|
|||||||
|
|
||||||
options_ctcss.set_options(ctcss_options);
|
options_ctcss.set_options(ctcss_options);
|
||||||
|
|
||||||
options_ctcss.on_change = [this](size_t, OptionsField::value_t v) {
|
|
||||||
this->on_ctcss_changed(v);
|
|
||||||
};
|
|
||||||
options_ctcss.set_selected_index(0);
|
options_ctcss.set_selected_index(0);
|
||||||
|
|
||||||
const auto button_fn = [this](Button& button) {
|
const auto button_fn = [this](Button& button) {
|
||||||
|
@ -73,17 +73,15 @@ private:
|
|||||||
uint32_t sample_duration { 0 };
|
uint32_t sample_duration { 0 };
|
||||||
uint8_t page = 0;
|
uint8_t page = 0;
|
||||||
|
|
||||||
uint16_t lfsr_v = 0x1337;
|
uint32_t lfsr_v = 0x13377331;
|
||||||
|
|
||||||
std::unique_ptr<WAVFileReader> reader { };
|
std::unique_ptr<WAVFileReader> reader { };
|
||||||
|
|
||||||
sound sounds[105];
|
sound sounds[105];
|
||||||
uint8_t max_sound { 0 };
|
uint32_t max_sound { };
|
||||||
uint8_t max_page { 0 };
|
uint8_t max_page { };
|
||||||
|
|
||||||
uint32_t _ctcss_freq { 0 };
|
|
||||||
|
|
||||||
int8_t audio_buffer[2048];
|
int8_t audio_buffer[1024];
|
||||||
|
|
||||||
Style style_a {
|
Style style_a {
|
||||||
.font = font::fixed_8x16,
|
.font = font::fixed_8x16,
|
||||||
|
@ -83,8 +83,8 @@ private:
|
|||||||
|
|
||||||
NumberField field_bw {
|
NumberField field_bw {
|
||||||
{ 14 * 8, 0 * 16 },
|
{ 14 * 8, 0 * 16 },
|
||||||
2,
|
3,
|
||||||
{ 1, 99 },
|
{ 1, 150 },
|
||||||
1,
|
1,
|
||||||
' '
|
' '
|
||||||
};
|
};
|
||||||
|
@ -37,18 +37,13 @@ void AudioTXProcessor::execute(const buffer_c8_t& buffer){
|
|||||||
//ai = 0;
|
//ai = 0;
|
||||||
for (size_t i = 0; i<buffer.count; i++) {
|
for (size_t i = 0; i<buffer.count; i++) {
|
||||||
|
|
||||||
// Audio preview sample generation: 1536000/divider = samplerate
|
// Audio preview sample generation @ 1536000/divider
|
||||||
if (!as) {
|
if (!as) {
|
||||||
as = divider;
|
as = divider;
|
||||||
audio_fifo.out(sample);
|
audio_fifo.out(out_sample);
|
||||||
|
sample = (int32_t)out_sample;
|
||||||
//preview_audio_buffer.p[ai++] = sample << 8;
|
//preview_audio_buffer.p[ai++] = sample << 8;
|
||||||
|
|
||||||
if (ctcss_enabled) {
|
|
||||||
ctcss_sample = sine_table_i8[(ctcss_phase & 0x03FC0000) >> 18];
|
|
||||||
int16_t mix = (sample * 218) + (ctcss_sample * 37); // ~15%
|
|
||||||
sample = mix >> 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((audio_fifo.len() < 1024) && (asked == false)) {
|
if ((audio_fifo.len() < 1024) && (asked == false)) {
|
||||||
// Ask application to fill up fifo
|
// Ask application to fill up fifo
|
||||||
sigmessage.signaltype = 1;
|
sigmessage.signaltype = 1;
|
||||||
@ -59,36 +54,38 @@ void AudioTXProcessor::execute(const buffer_c8_t& buffer){
|
|||||||
as--;
|
as--;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctcss_phase += ctcss_phase_inc;
|
if (ctcss_enabled) {
|
||||||
|
ctcss_sample = sine_table_i8[(ctcss_phase & 0xFF000000U) >> 24];
|
||||||
|
sample_mixed = ((sample * 217) + (ctcss_sample * 38)) / 256; // ~15%
|
||||||
|
ctcss_phase += ctcss_phase_inc;
|
||||||
|
} else {
|
||||||
|
sample_mixed = sample;
|
||||||
|
}
|
||||||
|
|
||||||
// FM
|
// FM
|
||||||
frq = sample * bw;
|
delta = sample_mixed * fm_delta;
|
||||||
|
|
||||||
phase = (phase + frq);
|
phase += delta;
|
||||||
sphase = phase + (64 << 18);
|
sphase = phase + (64 << 24);
|
||||||
|
|
||||||
re = (sine_table_i8[(sphase & 0x03FC0000) >> 18]);
|
re = (sine_table_i8[(sphase & 0xFF000000U) >> 24]);
|
||||||
im = (sine_table_i8[(phase & 0x03FC0000) >> 18]);
|
im = (sine_table_i8[(phase & 0xFF000000U) >> 24]);
|
||||||
|
|
||||||
buffer.p[i] = {(int8_t)re, (int8_t)im};
|
buffer.p[i] = {re, im};
|
||||||
}
|
}
|
||||||
|
|
||||||
//AudioOutput::fill_audio_buffer(preview_audio_buffer, true);
|
//AudioOutput::fill_audio_buffer(preview_audio_buffer, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioTXProcessor::on_message(const Message* const msg) {
|
void AudioTXProcessor::on_message(const Message* const msg) {
|
||||||
const auto message = static_cast<const AudioTXConfigMessage*>(msg);
|
const auto message = *reinterpret_cast<const AudioTXConfigMessage*>(msg);
|
||||||
|
|
||||||
switch(msg->id) {
|
switch(msg->id) {
|
||||||
case Message::ID::AudioTXConfig:
|
case Message::ID::AudioTXConfig:
|
||||||
|
fm_delta = message.fm_delta * (0xFFFFFFULL / 1536000);
|
||||||
// 1<<18 = 262144
|
divider = message.divider;
|
||||||
// m = (262144 * a) / 1536000
|
ctcss_enabled = message.ctcss_enabled;
|
||||||
// a = 262144 / 1536000 (*1000 = 171)
|
ctcss_phase_inc = message.ctcss_phase_inc;
|
||||||
bw = 171 * (message->bw);
|
|
||||||
divider = message->divider;
|
|
||||||
ctcss_phase_inc = message->ctcss_phase_inc;
|
|
||||||
ctcss_enabled = message->ctcss_enabled;
|
|
||||||
as = 0;
|
as = 0;
|
||||||
|
|
||||||
configured = true;
|
configured = true;
|
||||||
|
@ -38,19 +38,21 @@ private:
|
|||||||
|
|
||||||
BasebandThread baseband_thread { 1536000, this, NORMALPRIO + 20, baseband::Direction::Transmit };
|
BasebandThread baseband_thread { 1536000, this, NORMALPRIO + 20, baseband::Direction::Transmit };
|
||||||
|
|
||||||
int8_t audio_fifo_data[2048];
|
int8_t audio_fifo_data[2048] { };
|
||||||
FIFO<int8_t> audio_fifo = { audio_fifo_data, 11 }; // 43ms @ 48000Hz
|
FIFO<int8_t> audio_fifo = { audio_fifo_data, 11 }; // 43ms @ 48000Hz
|
||||||
|
|
||||||
uint32_t bw;
|
uint32_t fm_delta { 0 };
|
||||||
uint32_t divider;
|
uint32_t divider { };
|
||||||
uint8_t as = 0;
|
uint32_t as { 0 };
|
||||||
uint32_t ctcss_phase_inc;
|
bool ctcss_enabled { false };
|
||||||
bool ctcss_enabled;
|
uint32_t ctcss_phase_inc { };
|
||||||
|
uint32_t ctcss_phase { 0 }, phase { 0 }, sphase { 0 };
|
||||||
|
int8_t out_sample { };
|
||||||
|
int32_t ctcss_sample { 0 }, sample { 0 }, sample_mixed { }, delta { };
|
||||||
|
|
||||||
int8_t re, im;
|
int8_t re { 0 }, im { 0 };
|
||||||
int8_t ctcss_sample, sample;
|
|
||||||
|
|
||||||
bool asked = false;
|
bool asked { false };
|
||||||
|
|
||||||
//int16_t audio_data[64];
|
//int16_t audio_data[64];
|
||||||
/*const buffer_s16_t preview_audio_buffer {
|
/*const buffer_s16_t preview_audio_buffer {
|
||||||
@ -58,10 +60,7 @@ private:
|
|||||||
sizeof(int16_t)*64
|
sizeof(int16_t)*64
|
||||||
};*/
|
};*/
|
||||||
|
|
||||||
FIFOSignalMessage sigmessage;
|
FIFOSignalMessage sigmessage { };
|
||||||
|
|
||||||
uint32_t ctcss_phase, phase, sphase;
|
|
||||||
int32_t frq;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -36,7 +36,7 @@ void JammerProcessor::execute(const buffer_c8_t& buffer) {
|
|||||||
// Find next enabled range
|
// Find next enabled range
|
||||||
do {
|
do {
|
||||||
current_range++;
|
current_range++;
|
||||||
if (current_range == 9) current_range = 0;
|
if (current_range == 24) current_range = 0; // Warning ! Should match JAMMER_MAX_CH
|
||||||
} while (!jammer_channels[current_range].enabled);
|
} while (!jammer_channels[current_range].enabled);
|
||||||
|
|
||||||
jammer_duration = jammer_channels[current_range].duration;
|
jammer_duration = jammer_channels[current_range].duration;
|
||||||
|
@ -36,7 +36,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
bool configured = false;
|
bool configured = false;
|
||||||
|
|
||||||
BasebandThread baseband_thread { 1536000, this, NORMALPRIO + 20, baseband::Direction::Transmit };
|
BasebandThread baseband_thread { 3072000, this, NORMALPRIO + 20, baseband::Direction::Transmit };
|
||||||
|
|
||||||
JammerChannel * jammer_channels { };
|
JammerChannel * jammer_channels { };
|
||||||
|
|
||||||
|
@ -630,19 +630,19 @@ class AudioTXConfigMessage : public Message {
|
|||||||
public:
|
public:
|
||||||
constexpr AudioTXConfigMessage(
|
constexpr AudioTXConfigMessage(
|
||||||
const uint32_t divider,
|
const uint32_t divider,
|
||||||
const uint32_t bw,
|
const uint32_t fm_delta,
|
||||||
const uint32_t ctcss_phase_inc,
|
const uint32_t ctcss_phase_inc,
|
||||||
const bool ctcss_enabled
|
const bool ctcss_enabled
|
||||||
) : Message { ID::AudioTXConfig },
|
) : Message { ID::AudioTXConfig },
|
||||||
divider(divider),
|
divider(divider),
|
||||||
bw(bw),
|
fm_delta(fm_delta),
|
||||||
ctcss_phase_inc(ctcss_phase_inc),
|
ctcss_phase_inc(ctcss_phase_inc),
|
||||||
ctcss_enabled(ctcss_enabled)
|
ctcss_enabled(ctcss_enabled)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t divider;
|
const uint32_t divider;
|
||||||
const uint32_t bw;
|
const uint32_t fm_delta;
|
||||||
const uint32_t ctcss_phase_inc;
|
const uint32_t ctcss_phase_inc;
|
||||||
const bool ctcss_enabled;
|
const bool ctcss_enabled;
|
||||||
};
|
};
|
||||||
|
@ -62,9 +62,9 @@ struct SharedMemory {
|
|||||||
|
|
||||||
union {
|
union {
|
||||||
ToneData tones_data;
|
ToneData tones_data;
|
||||||
JammerChannel jammer_channels[9];
|
JammerChannel jammer_channels[24];
|
||||||
uint8_t data[512];
|
uint8_t data[512];
|
||||||
} bb_data { { { { 0, 0 } }, 0, { 0 } } };
|
} bb_data { { { { 0, 0 } }, 0, { 0 } } }; // { } ?
|
||||||
};
|
};
|
||||||
|
|
||||||
extern SharedMemory& shared_memory;
|
extern SharedMemory& shared_memory;
|
||||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user