mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-10-01 01:26:06 -04: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"
|
||||
|
||||
ctcss_tone ctcss_tones[CTCSS_TONES_NB] = {
|
||||
{ "XZ", 0, 67000 },
|
||||
{ "WZ", 1, 69400 },
|
||||
{ "XA", 39, 71900 },
|
||||
{ "WA", 3, 74400 },
|
||||
{ "XB", 4, 77000 },
|
||||
{ "WB", 5, 79700 },
|
||||
{ "YZ", 6, 82500 },
|
||||
{ "YA", 7, 85400 },
|
||||
{ "YB", 8, 88500 },
|
||||
{ "ZZ", 9, 91500 },
|
||||
{ "ZA", 10, 94800 },
|
||||
{ "ZB", 11, 97400 },
|
||||
{ "1Z", 12, 100000 },
|
||||
{ "1A", 13, 103500 },
|
||||
{ "1B", 14, 107200 },
|
||||
{ "2Z", 15, 110900 },
|
||||
{ "2Z", 16, 114800 },
|
||||
{ "2B", 17, 118800 },
|
||||
{ "3Z", 18, 123000 },
|
||||
{ "3A", 19, 127300 },
|
||||
{ "3B", 20, 131800 },
|
||||
{ "4Z", 21, 136500 },
|
||||
{ "4A", 22, 141300 },
|
||||
{ "4B", 23, 146200 },
|
||||
{ "5Z", 24, 151400 },
|
||||
{ "5A", 25, 156700 },
|
||||
{ "--", 40, 159800 },
|
||||
{ "5B", 26, 162200 },
|
||||
{ "--", 41, 165500 },
|
||||
{ "6Z", 27, 167900 },
|
||||
{ "--", 42, 171300 },
|
||||
{ "6A", 28, 173800 },
|
||||
{ "--", 43, 177300 },
|
||||
{ "6B", 29, 179900 },
|
||||
{ "--", 44, 183500 },
|
||||
{ "7Z", 30, 186200 },
|
||||
{ "--", 45, 189900 },
|
||||
{ "7A", 31, 192800 },
|
||||
{ "--", 46, 196600 },
|
||||
{ "--", 47, 199500 },
|
||||
{ "M1", 32, 203500 },
|
||||
{ "8Z", 48, 206500 },
|
||||
{ "M2", 33, 210700 },
|
||||
{ "M3", 34, 218100 },
|
||||
{ "M4", 35, 225700 },
|
||||
{ "9Z", 49, 229100 },
|
||||
{ "--", 36, 233600 },
|
||||
{ "--", 37, 241800 },
|
||||
{ "--", 38, 250300 },
|
||||
{ "0Z", 50, 254100 }
|
||||
const ctcss_tone ctcss_tones[CTCSS_TONES_NB] = {
|
||||
{ "XZ", 0, 67.000 },
|
||||
{ "WZ", 1, 69.400 },
|
||||
{ "XA", 39, 71.900 },
|
||||
{ "WA", 3, 74.400 },
|
||||
{ "XB", 4, 77.000 },
|
||||
{ "WB", 5, 79.700 },
|
||||
{ "YZ", 6, 82.500 },
|
||||
{ "YA", 7, 85.400 },
|
||||
{ "YB", 8, 88.500 },
|
||||
{ "ZZ", 9, 91.500 },
|
||||
{ "ZA", 10, 94.800 },
|
||||
{ "ZB", 11, 97.400 },
|
||||
{ "1Z", 12, 100.000 },
|
||||
{ "1A", 13, 103.500 },
|
||||
{ "1B", 14, 107.200 },
|
||||
{ "2Z", 15, 110.900 },
|
||||
{ "2Z", 16, 114.800 },
|
||||
{ "2B", 17, 118.800 },
|
||||
{ "3Z", 18, 123.000 },
|
||||
{ "3A", 19, 127.300 },
|
||||
{ "3B", 20, 131.800 },
|
||||
{ "4Z", 21, 136.500 },
|
||||
{ "4A", 22, 141.300 },
|
||||
{ "4B", 23, 146.200 },
|
||||
{ "5Z", 24, 151.400 },
|
||||
{ "5A", 25, 156.700 },
|
||||
{ "--", 40, 159.800 },
|
||||
{ "5B", 26, 162.200 },
|
||||
{ "--", 41, 165.500 },
|
||||
{ "6Z", 27, 167.900 },
|
||||
{ "--", 42, 171.300 },
|
||||
{ "6A", 28, 173.800 },
|
||||
{ "--", 43, 177.300 },
|
||||
{ "6B", 29, 179.900 },
|
||||
{ "--", 44, 183.500 },
|
||||
{ "7Z", 30, 186.200 },
|
||||
{ "--", 45, 189.900 },
|
||||
{ "7A", 31, 192.800 },
|
||||
{ "--", 46, 196.600 },
|
||||
{ "--", 47, 199.500 },
|
||||
{ "M1", 32, 203.500 },
|
||||
{ "8Z", 48, 206.500 },
|
||||
{ "M2", 33, 210.700 },
|
||||
{ "M3", 34, 218.100 },
|
||||
{ "M4", 35, 225.700 },
|
||||
{ "9Z", 49, 229.100 },
|
||||
{ "--", 36, 233.600 },
|
||||
{ "--", 37, 241.800 },
|
||||
{ "--", 38, 250.300 },
|
||||
{ "0Z", 50, 254.100 }
|
||||
};
|
||||
|
@ -30,9 +30,9 @@
|
||||
struct ctcss_tone {
|
||||
char PL_code[3];
|
||||
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_*/
|
||||
|
@ -32,7 +32,8 @@
|
||||
#include <cstring>
|
||||
#include <stdio.h>
|
||||
|
||||
#define JAMMER_CH_WIDTH 500000
|
||||
#define JAMMER_CH_WIDTH 1000000
|
||||
#define JAMMER_MAX_CH 24
|
||||
|
||||
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) {
|
||||
if (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;
|
||||
|
||||
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;
|
||||
update_button(button.id);
|
||||
update_range(button.id >> 1);
|
||||
};
|
||||
};
|
||||
|
||||
@ -235,10 +238,10 @@ JammerView::JammerView(NavigationView& nav) {
|
||||
} else {
|
||||
|
||||
// Disable all ranges by default
|
||||
for (c = 0; c < 9; c++)
|
||||
for (c = 0; c < JAMMER_MAX_CH; c++)
|
||||
jammer_channels[c].enabled = false;
|
||||
|
||||
// Generate jamming "channels", maximum: 9
|
||||
// Generate jamming "channels", maximum: JAMMER_MAX_CH
|
||||
// Convert ranges min/max to center/bw
|
||||
for (size_t r = 0; r < 3; r++) {
|
||||
|
||||
@ -260,24 +263,24 @@ JammerView::JammerView(NavigationView& nav) {
|
||||
} while (range_bw_sub >= JAMMER_CH_WIDTH);
|
||||
ch_width = range_bw / num_channels;
|
||||
for (c = 0; c < num_channels; c++) {
|
||||
if (i >= 9) {
|
||||
if (i >= JAMMER_MAX_CH) {
|
||||
out_of_ranges = true;
|
||||
break;
|
||||
}
|
||||
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].duration = 15360 * options_hop.selected_index_value();
|
||||
jammer_channels[i].duration = 30720 * options_hop.selected_index_value();
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
if (i >= 9) {
|
||||
if (i >= JAMMER_MAX_CH) {
|
||||
out_of_ranges = true;
|
||||
} else {
|
||||
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].duration = 15360 * options_hop.selected_index_value();
|
||||
jammer_channels[i].duration = 30720 * options_hop.selected_index_value();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
@ -285,15 +288,15 @@ JammerView::JammerView(NavigationView& nav) {
|
||||
}
|
||||
|
||||
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;
|
||||
button_transmit.set_style(&style_cancel);
|
||||
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_baseband_bandwidth(1750000);
|
||||
transmitter_model.set_baseband_bandwidth(3500000U);
|
||||
transmitter_model.set_tx_gain(47);
|
||||
transmitter_model.enable();
|
||||
|
||||
|
@ -70,7 +70,7 @@ private:
|
||||
// Free
|
||||
{{ true, 945000000, 950000000 }, // GSM 900 BW:5M
|
||||
{ false, 0, 0 },
|
||||
{ true, 0, 0 }},
|
||||
{ false, 0, 0 }},
|
||||
|
||||
// GSM-R
|
||||
{{ true, 921000000, 925000000 }, // GSM 900 BW:4M
|
||||
@ -174,12 +174,12 @@ private:
|
||||
};
|
||||
|
||||
Text text_range_number {
|
||||
{ 18 * 8, 4, 1 * 8, 16 },
|
||||
"-"
|
||||
{ 18 * 8, 4, 2 * 8, 16 },
|
||||
"--"
|
||||
};
|
||||
Text text_range_total {
|
||||
{ 19 * 8, 4, 2 * 8, 16 },
|
||||
"/-"
|
||||
{ 20 * 8, 4, 3 * 8, 16 },
|
||||
"/--"
|
||||
};
|
||||
|
||||
Text text_speed {
|
||||
|
@ -352,8 +352,8 @@ SystemMenuView::SystemMenuView(NavigationView& nav) {
|
||||
add_items<12>({ {
|
||||
{ "Play dead", ui::Color::red(), &bitmap_icon_playdead, [&nav](){ nav.push<PlayDeadView>(); } },
|
||||
{ "Receivers", ui::Color::cyan(), &bitmap_icon_receiver, [&nav](){ nav.push<ReceiverMenuView>(); } },
|
||||
{ "Capture", ui::Color::cyan(), &bitmap_icon_capture, [&nav](){ nav.push<CaptureAppView>(); } },
|
||||
{ "Replay", ui::Color::blue(), &bitmap_icon_replay, [&nav](){ nav.push<ReplayAppView>(); } },
|
||||
{ "Capture", ui::Color::cyan(), &bitmap_icon_capture, [&nav](){ nav.push<NotImplementedView>(); } }, //CaptureAppView
|
||||
{ "Replay", ui::Color::grey(), &bitmap_icon_replay, [&nav](){ nav.push<ReplayAppView>(); } },
|
||||
{ "Code transmitters", ui::Color::green(), &bitmap_icon_codetx, [&nav](){ nav.push<TransmitterCodedMenuView>(); } },
|
||||
{ "Audio transmitters", ui::Color::green(), &bitmap_icon_audiotx, [&nav](){ nav.push<TransmitterAudioMenuView>(); } },
|
||||
{ "Close Call", ui::Color::orange(),&bitmap_icon_closecall, [&nav](){ nav.push<CloseCallView>(); } },
|
||||
|
@ -38,11 +38,12 @@ using namespace portapack;
|
||||
namespace ui {
|
||||
|
||||
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);
|
||||
|
||||
@ -67,6 +68,7 @@ void SoundBoardView::prepare_audio() {
|
||||
} else {
|
||||
pbar.set_value(0);
|
||||
transmitter_model.disable();
|
||||
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) {
|
||||
uint32_t ctcss_option;
|
||||
uint32_t ctcss_index;
|
||||
bool ctcss_enabled;
|
||||
uint32_t divider;
|
||||
|
||||
@ -122,9 +124,9 @@ void SoundBoardView::play_sound(uint16_t id) {
|
||||
transmitter_model.set_baseband_bandwidth(1750000);
|
||||
transmitter_model.enable();
|
||||
|
||||
ctcss_option = options_ctcss.selected_index();
|
||||
ctcss_index = options_ctcss.selected_index();
|
||||
|
||||
if (ctcss_option)
|
||||
if (ctcss_index)
|
||||
ctcss_enabled = true;
|
||||
else
|
||||
ctcss_enabled = false;
|
||||
@ -133,9 +135,9 @@ void SoundBoardView::play_sound(uint16_t id) {
|
||||
|
||||
baseband::set_audiotx_data(
|
||||
divider,
|
||||
number_bw.value(),
|
||||
number_bw.value() * 1000,
|
||||
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(
|
||||
NavigationView& nav
|
||||
) : nav_ (nav)
|
||||
@ -249,9 +247,6 @@ SoundBoardView::SoundBoardView(
|
||||
|
||||
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);
|
||||
|
||||
const auto button_fn = [this](Button& button) {
|
||||
|
@ -73,17 +73,15 @@ private:
|
||||
uint32_t sample_duration { 0 };
|
||||
uint8_t page = 0;
|
||||
|
||||
uint16_t lfsr_v = 0x1337;
|
||||
uint32_t lfsr_v = 0x13377331;
|
||||
|
||||
std::unique_ptr<WAVFileReader> reader { };
|
||||
|
||||
sound sounds[105];
|
||||
uint8_t max_sound { 0 };
|
||||
uint8_t max_page { 0 };
|
||||
uint32_t max_sound { };
|
||||
uint8_t max_page { };
|
||||
|
||||
uint32_t _ctcss_freq { 0 };
|
||||
|
||||
int8_t audio_buffer[2048];
|
||||
int8_t audio_buffer[1024];
|
||||
|
||||
Style style_a {
|
||||
.font = font::fixed_8x16,
|
||||
|
@ -83,8 +83,8 @@ private:
|
||||
|
||||
NumberField field_bw {
|
||||
{ 14 * 8, 0 * 16 },
|
||||
2,
|
||||
{ 1, 99 },
|
||||
3,
|
||||
{ 1, 150 },
|
||||
1,
|
||||
' '
|
||||
};
|
||||
|
@ -37,18 +37,13 @@ void AudioTXProcessor::execute(const buffer_c8_t& buffer){
|
||||
//ai = 0;
|
||||
for (size_t i = 0; i<buffer.count; i++) {
|
||||
|
||||
// Audio preview sample generation: 1536000/divider = samplerate
|
||||
// Audio preview sample generation @ 1536000/divider
|
||||
if (!as) {
|
||||
as = divider;
|
||||
audio_fifo.out(sample);
|
||||
audio_fifo.out(out_sample);
|
||||
sample = (int32_t)out_sample;
|
||||
//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)) {
|
||||
// Ask application to fill up fifo
|
||||
sigmessage.signaltype = 1;
|
||||
@ -59,36 +54,38 @@ void AudioTXProcessor::execute(const buffer_c8_t& buffer){
|
||||
as--;
|
||||
}
|
||||
|
||||
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
|
||||
frq = sample * bw;
|
||||
delta = sample_mixed * fm_delta;
|
||||
|
||||
phase = (phase + frq);
|
||||
sphase = phase + (64 << 18);
|
||||
phase += delta;
|
||||
sphase = phase + (64 << 24);
|
||||
|
||||
re = (sine_table_i8[(sphase & 0x03FC0000) >> 18]);
|
||||
im = (sine_table_i8[(phase & 0x03FC0000) >> 18]);
|
||||
re = (sine_table_i8[(sphase & 0xFF000000U) >> 24]);
|
||||
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);
|
||||
}
|
||||
|
||||
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) {
|
||||
case Message::ID::AudioTXConfig:
|
||||
|
||||
// 1<<18 = 262144
|
||||
// m = (262144 * a) / 1536000
|
||||
// a = 262144 / 1536000 (*1000 = 171)
|
||||
bw = 171 * (message->bw);
|
||||
divider = message->divider;
|
||||
ctcss_phase_inc = message->ctcss_phase_inc;
|
||||
ctcss_enabled = message->ctcss_enabled;
|
||||
fm_delta = message.fm_delta * (0xFFFFFFULL / 1536000);
|
||||
divider = message.divider;
|
||||
ctcss_enabled = message.ctcss_enabled;
|
||||
ctcss_phase_inc = message.ctcss_phase_inc;
|
||||
as = 0;
|
||||
|
||||
configured = true;
|
||||
|
@ -38,19 +38,21 @@ private:
|
||||
|
||||
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
|
||||
|
||||
uint32_t bw;
|
||||
uint32_t divider;
|
||||
uint8_t as = 0;
|
||||
uint32_t ctcss_phase_inc;
|
||||
bool ctcss_enabled;
|
||||
uint32_t fm_delta { 0 };
|
||||
uint32_t divider { };
|
||||
uint32_t as { 0 };
|
||||
bool ctcss_enabled { false };
|
||||
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 ctcss_sample, sample;
|
||||
int8_t re { 0 }, im { 0 };
|
||||
|
||||
bool asked = false;
|
||||
bool asked { false };
|
||||
|
||||
//int16_t audio_data[64];
|
||||
/*const buffer_s16_t preview_audio_buffer {
|
||||
@ -58,10 +60,7 @@ private:
|
||||
sizeof(int16_t)*64
|
||||
};*/
|
||||
|
||||
FIFOSignalMessage sigmessage;
|
||||
|
||||
uint32_t ctcss_phase, phase, sphase;
|
||||
int32_t frq;
|
||||
FIFOSignalMessage sigmessage { };
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -36,7 +36,7 @@ void JammerProcessor::execute(const buffer_c8_t& buffer) {
|
||||
// Find next enabled range
|
||||
do {
|
||||
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);
|
||||
|
||||
jammer_duration = jammer_channels[current_range].duration;
|
||||
|
@ -36,7 +36,7 @@ public:
|
||||
private:
|
||||
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 { };
|
||||
|
||||
|
@ -630,19 +630,19 @@ class AudioTXConfigMessage : public Message {
|
||||
public:
|
||||
constexpr AudioTXConfigMessage(
|
||||
const uint32_t divider,
|
||||
const uint32_t bw,
|
||||
const uint32_t fm_delta,
|
||||
const uint32_t ctcss_phase_inc,
|
||||
const bool ctcss_enabled
|
||||
) : Message { ID::AudioTXConfig },
|
||||
divider(divider),
|
||||
bw(bw),
|
||||
fm_delta(fm_delta),
|
||||
ctcss_phase_inc(ctcss_phase_inc),
|
||||
ctcss_enabled(ctcss_enabled)
|
||||
{
|
||||
}
|
||||
|
||||
const uint32_t divider;
|
||||
const uint32_t bw;
|
||||
const uint32_t fm_delta;
|
||||
const uint32_t ctcss_phase_inc;
|
||||
const bool ctcss_enabled;
|
||||
};
|
||||
|
@ -62,9 +62,9 @@ struct SharedMemory {
|
||||
|
||||
union {
|
||||
ToneData tones_data;
|
||||
JammerChannel jammer_channels[9];
|
||||
JammerChannel jammer_channels[24];
|
||||
uint8_t data[512];
|
||||
} bb_data { { { { 0, 0 } }, 0, { 0 } } };
|
||||
} bb_data { { { { 0, 0 } }, 0, { 0 } } }; // { } ?
|
||||
};
|
||||
|
||||
extern SharedMemory& shared_memory;
|
||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user