Remove dead code (#2304)

* remove dead code, playdead

* removed Nuoptix

* remove ui_loadmodule

* removed modules.h

* removed replay_app

* removed handwrite

* removed numbers, script

* remove emu_cc1101

* removed noop, old pocsag

* removed unused abouts

* removed tone_search

* fix format

* forgot to remove

* removed unused py

* removed modules.h too
This commit is contained in:
Totoo
2024-10-15 22:14:33 +02:00
committed by GitHub
parent 1b3359b050
commit 66aa20161d
35 changed files with 8 additions and 4342 deletions

View File

@@ -1,224 +0,0 @@
/*
* Copyright (C) 2016 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek
* Copyleft (ↄ) 2022 NotPike
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "replay_app.hpp"
#include "string_format.hpp"
#include "ui_fileman.hpp"
#include "io_file.hpp"
#include "io_convert.hpp"
#include "baseband_api.hpp"
#include "metadata_file.hpp"
#include "portapack.hpp"
#include "portapack_persistent_memory.hpp"
#include "utility.hpp"
using namespace portapack;
namespace fs = std::filesystem;
namespace ui {
void ReplayAppView::set_ready() {
ready_signal = true;
}
void ReplayAppView::on_file_changed(const fs::path& new_file_path) {
file_path = new_file_path;
File::Size file_size{};
{ // Get the size of the data file.
File data_file;
auto error = data_file.open(file_path);
if (error) {
file_error();
return;
}
file_size = data_file.size();
}
// Get original record frequency if available.
auto metadata_path = get_metadata_path(file_path);
auto metadata = read_metadata_file(metadata_path);
if (metadata) {
field_frequency.set_value(metadata->center_frequency);
sample_rate = metadata->sample_rate;
} else {
// TODO: This is interesting because it implies that the
// The capture will just be replayed at the freq set on the
// FrequencyField. Is that an intentional behavior?
sample_rate = 500000;
}
// UI Fixup.
text_sample_rate.set(unit_auto_scale(sample_rate, 3, 0) + "Hz");
progressbar.set_max(file_size);
text_filename.set(truncate(file_path.filename().string(), 12));
uint8_t sample_size = capture_file_sample_size(current()->path);
auto duration = ms_duration(file_size, sample_rate, sample_size);
text_duration.set(to_string_time_ms(duration));
button_play.focus();
}
void ReplayAppView::on_tx_progress(const uint32_t progress) {
progressbar.set_value(progress);
}
void ReplayAppView::focus() {
button_open.focus();
}
void ReplayAppView::file_error() {
nav_.display_modal("Error", "File read error.");
}
bool ReplayAppView::is_active() const {
return (bool)replay_thread;
}
void ReplayAppView::toggle() {
if (is_active()) {
stop(false);
} else {
start();
}
}
void ReplayAppView::start() {
stop(false);
std::unique_ptr<stream::Reader> reader;
auto p = std::make_unique<FileConvertReader>();
auto open_error = p->open(file_path);
if (open_error.is_valid()) {
file_error();
return; // Fixes TX bug if there's a file error
} else {
reader = std::move(p);
}
if (reader) {
button_play.set_bitmap(&bitmap_stop);
baseband::set_sample_rate(sample_rate, OversampleRate::x8);
replay_thread = std::make_unique<ReplayThread>(
std::move(reader),
read_size, buffer_count,
&ready_signal,
[](uint32_t return_code) {
ReplayThreadDoneMessage message{return_code};
EventDispatcher::send_message(message);
});
}
transmitter_model.set_sampling_rate(sample_rate * toUType(OversampleRate::x8));
transmitter_model.set_baseband_bandwidth(baseband_bandwidth);
transmitter_model.enable();
if (portapack::persistent_memory::stealth_mode()) {
DisplaySleepMessage message;
EventDispatcher::send_message(message);
}
}
void ReplayAppView::stop(const bool do_loop) {
if (is_active())
replay_thread.reset();
if (do_loop && check_loop.value()) {
start();
} else {
transmitter_model.disable();
button_play.set_bitmap(&bitmap_play);
}
ready_signal = false;
}
void ReplayAppView::handle_replay_thread_done(const uint32_t return_code) {
if (return_code == ReplayThread::END_OF_FILE) {
stop(true);
} else if (return_code == ReplayThread::READ_ERROR) {
stop(false);
file_error();
}
progressbar.set_value(0);
}
ReplayAppView::ReplayAppView(
NavigationView& nav)
: nav_(nav) {
baseband::run_image(portapack::spi_flash::image_tag_replay);
add_children({
&button_open,
&text_filename,
&text_sample_rate,
&text_duration,
&progressbar,
&field_frequency,
&tx_view, // now it handles previous rfgain, rfamp.
&check_loop,
&button_play,
&waterfall,
});
button_play.on_select = [this](ImageButton&) {
this->toggle();
};
button_open.on_select = [this, &nav](Button&) {
auto open_view = nav.push<FileLoadView>(".C*");
open_view->on_changed = [this](fs::path new_file_path) {
on_file_changed(new_file_path);
};
};
}
ReplayAppView::~ReplayAppView() {
transmitter_model.disable();
baseband::shutdown();
}
void ReplayAppView::on_hide() {
stop(false);
// TODO: Terrible kludge because widget system doesn't notify Waterfall that
// it's being shown or hidden.
waterfall.on_hide();
View::on_hide();
}
void ReplayAppView::set_parent_rect(const Rect new_parent_rect) {
View::set_parent_rect(new_parent_rect);
const ui::Rect waterfall_rect{0, header_height, new_parent_rect.width(), new_parent_rect.height() - header_height};
waterfall.set_parent_rect(waterfall_rect);
}
} /* namespace ui */

View File

@@ -1,146 +0,0 @@
/*
* Copyright (C) 2016 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef __REPLAY_APP_HPP__
#define __REPLAY_APP_HPP__
#include "app_settings.hpp"
#include "radio_state.hpp"
#include "ui_widget.hpp"
#include "ui_navigation.hpp"
#include "ui_receiver.hpp"
#include "ui_freq_field.hpp"
#include "replay_thread.hpp"
#include "ui_spectrum.hpp"
#include "ui_transmitter.hpp"
#include <string>
#include <memory>
namespace ui {
class ReplayAppView : public View {
public:
ReplayAppView(NavigationView& nav);
~ReplayAppView();
void on_hide() override;
void set_parent_rect(const Rect new_parent_rect) override;
void focus() override;
std::string title() const override { return "Replay"; };
private:
NavigationView& nav_;
TxRadioState radio_state_{};
app_settings::SettingsManager settings_{
"tx_replay", app_settings::Mode::TX};
static constexpr ui::Dim header_height = 3 * 16;
uint32_t sample_rate = 0;
int32_t tx_gain{47};
bool rf_amp{true}; // aux private var to store temporal, Replay App rf_amp user selection.
static constexpr uint32_t baseband_bandwidth = 2500000;
const size_t read_size{16384};
const size_t buffer_count{3};
void on_file_changed(const std::filesystem::path& new_file_path);
void on_tx_progress(const uint32_t progress);
void toggle();
void start();
void stop(const bool do_loop);
bool is_active() const;
void set_ready();
void handle_replay_thread_done(const uint32_t return_code);
void file_error();
std::filesystem::path file_path{};
std::unique_ptr<ReplayThread> replay_thread{};
bool ready_signal{false};
Button button_open{
{0 * 8, 0 * 16, 10 * 8, 2 * 16},
"Open file"};
Text text_filename{
{11 * 8, 0 * 16, 12 * 8, 16},
"-"};
Text text_sample_rate{
{24 * 8, 0 * 16, 6 * 8, 16},
"-"};
Text text_duration{
{11 * 8, 1 * 16, 6 * 8, 16},
"-"};
ProgressBar progressbar{
{18 * 8, 1 * 16, 12 * 8, 16}};
TxFrequencyField field_frequency{
{0 * 8, 2 * 16},
nav_};
TransmitterView2 tx_view{
{11 * 8, 2 * 16},
/*short_ui*/ true};
Checkbox check_loop{
{21 * 8, 2 * 16},
4,
"Loop",
true};
ImageButton button_play{
{28 * 8, 2 * 16, 2 * 8, 1 * 16},
&bitmap_play,
Theme::getInstance()->fg_green->foreground,
Theme::getInstance()->fg_green->background};
spectrum::WaterfallView waterfall{};
MessageHandlerRegistration message_handler_replay_thread_error{
Message::ID::ReplayThreadDone,
[this](const Message* const p) {
const auto message = *reinterpret_cast<const ReplayThreadDoneMessage*>(p);
this->handle_replay_thread_done(message.return_code);
}};
MessageHandlerRegistration message_handler_fifo_signal{
Message::ID::RequestSignal,
[this](const Message* const p) {
const auto message = static_cast<const RequestSignalMessage*>(p);
if (message->signal == RequestSignalMessage::Signal::FillRequest) {
this->set_ready();
}
}};
MessageHandlerRegistration message_handler_tx_progress{
Message::ID::TXProgress,
[this](const Message* const p) {
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
this->on_tx_progress(message.progress);
}};
};
} /* namespace ui */
#endif /*__REPLAY_APP_HPP__*/

View File

@@ -1,138 +0,0 @@
/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "cpld_update.hpp"
#include "portapack.hpp"
#include "event_m0.hpp"
#include "ui_about.hpp"
#include "portapack_shared_memory.hpp"
#include "portapack_persistent_memory.hpp"
#include "lpc43xx_cpp.hpp"
#include <math.h>
#include <cstring>
using namespace lpc43xx;
using namespace portapack;
namespace ui {
// This is pretty much WaterfallView but in the opposite direction
CreditsWidget::CreditsWidget(
Rect parent_rect)
: Widget{parent_rect} {
}
void CreditsWidget::paint(Painter&) {
}
void CreditsWidget::on_show() {
clear();
const auto screen_r = screen_rect();
display.scroll_set_area(screen_r.top(), screen_r.bottom());
}
void CreditsWidget::on_hide() {
display.scroll_disable();
}
void CreditsWidget::new_row(
const std::array<Color, 240>& pixel_row) {
// Glitch be here (see comment in main.cpp)
const auto draw_y = display.scroll(-1);
display.draw_pixels(
{{0, draw_y - 1}, {240, 1}},
pixel_row);
}
void CreditsWidget::clear() {
display.fill_rectangle(
screen_rect(),
Theme::getInstance()->bg_darkest->background);
}
void AboutView::update() {
size_t i = 0;
std::array<Color, 240> pixel_row;
slow_down++;
if (slow_down % 3 < 2) return;
if (!timer) {
if (loop) {
credits_index = 0;
loop = false;
}
text = credits[credits_index].text;
timer = credits[credits_index].delay;
start_pos = credits[credits_index].start_pos;
if (timer < 0) {
timer = 240;
loop = true;
} else
timer += 16;
render_line = 0;
credits_index++;
} else
timer--;
if (render_line < 16) {
for (const auto c : text) {
const auto glyph = style().font.glyph(c);
const size_t start = (glyph.size().width() / 8) * render_line;
for (Dim c = 0; c < glyph.size().width(); c++) {
const auto pixel = glyph.pixels()[start + (c >> 3)] & (1U << (c & 0x7));
pixel_row[start_pos + i + c] = pixel ? Theme::getInstance()->bg_darkest->foreground : Theme::getInstance()->bg_darkest->background;
}
const auto advance = glyph.advance();
i += advance.x();
}
render_line++;
}
credits_display.new_row(pixel_row);
}
AboutView::AboutView(
NavigationView& nav) {
add_children({&credits_display,
&button_ok});
button_ok.on_select = [&nav](Button&) {
nav.pop();
};
}
void AboutView::focus() {
button_ok.focus();
}
} /* namespace ui */

View File

@@ -1,119 +0,0 @@
/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef __UI_ABOUT_H__
#define __UI_ABOUT_H__
#include "ui_widget.hpp"
#include "ui_navigation.hpp"
#include <cstdint>
namespace ui {
class CreditsWidget : public Widget {
public:
CreditsWidget(Rect parent_rect);
void on_show() override;
void on_hide() override;
void paint(Painter&) override;
void new_row(const std::array<Color, 240>& pixel_row);
private:
void clear();
};
class AboutView : public View {
public:
AboutView(NavigationView& nav);
void focus() override;
std::string title() const override { return "About"; };
private:
void update();
uint8_t credits_index{0};
uint8_t render_line{0};
Coord start_pos{0};
uint8_t slow_down{0};
int32_t timer{0};
bool loop{false};
std::string text{};
typedef struct credits_t {
size_t start_pos;
std::string text;
int32_t delay;
} credits_t;
// TODO: Make this dinamically centered and parse \n as the delay value so it is easy to maintain
const credits_t credits[26] = {
// 012345678901234567890123456789
{60, "PortaPack Mayhem", 0},
{60, "PortaPack|HAVOC", 0},
{11 * 8, "Gurus J. Boone", 0},
{18 * 8, "M. Ossmann", 16},
{11 * 8, "HAVOC Furrtek", 16},
{7 * 8, "POCSAG rx T. Sailer", 0},
{18 * 8, "E. Oenal", 16},
{0 * 8, "Radiosonde infos F4GMU", 0},
{18 * 8, "RS1729", 16},
{4 * 8, "RDS waveform C. Jacquet", 16},
{7 * 8, "Xy. infos cLx", 16},
{2 * 8, "OOK scan trick Samy Kamkar", 16},
{7 * 8, "World map NASA", 16},
{0 * 8, "TouchTunes infos Notpike", 16},
{4 * 8, "Subaru infos Tom", 0},
{18 * 8, "Wimmenhove", 16},
{1 * 8, "GPS,TV,BTLE,NRF Shao", 24},
{6 * 8, "Thanks & donators", 16},
{1 * 8, "Rainer Matla Keld Norman", 0},
{1 * 8, " Giorgio C. DC1RDB", 0},
{1 * 8, " Sigmounte Waax", 0},
{1 * 8, " Windyoona Channels", 0},
{1 * 8, " F4GEV Pyr3x", 0},
{1 * 8, " HB3YOE", 24},
{11 * 8, "MMXVIII", -1}};
CreditsWidget credits_display{
{0, 16, 240, 240}};
Button button_ok{
{72, 272, 96, 24},
"OK"};
MessageHandlerRegistration message_handler_update{
Message::ID::DisplayFrameSync,
[this](const Message* const) {
this->update();
}};
};
} /* namespace ui */
#endif /*__UI_ABOUT_H__*/

View File

@@ -1,413 +0,0 @@
/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include <ch.h>
#include "demofont.hpp"
#include "ymdata.hpp"
#include "cpld_update.hpp"
#include "portapack.hpp"
#include "audio.hpp"
#include "event_m0.hpp"
#include "ui_about.hpp"
#include "touch.hpp"
#include "sine_table.hpp"
#include "portapack_shared_memory.hpp"
#include "portapack_persistent_memory.hpp"
#include "lpc43xx_cpp.hpp"
#include <math.h>
#include <cstring>
using namespace lpc43xx;
using namespace portapack;
namespace ui {
void AboutView::on_show() {
transmitter_model.set_target_frequency(1337000000); // TODO: Change
transmitter_model.set_baseband_configuration({
.mode = 0,
.sampling_rate = 1536000,
.decimation_factor = 1,
});
transmitter_model.set_rf_amp(true);
transmitter_model.set_lna(40);
transmitter_model.set_vga(40);
transmitter_model.enable();
baseband::set_audiotx_data(32, 50, false, 0);
// audio::headphone::set_volume(volume_t::decibel(0 - 99) + audio::headphone::volume_range().max);
}
void AboutView::render_video() {
uint8_t p, r, luma, chroma, cy;
ui::Color cc;
char ch;
float s;
// Send framebuffer to LCD. Gotta go fast !
display.render_box({30, 112}, {180, 72}, framebuffer);
// Clear framebuffer to black
memset(framebuffer, 0, 180 * 72 * sizeof(ui::Color));
// Drum hit palette animation
if (drum > 1) drum--;
// Render copper bars from Y buffer
for (p = 0; p < 72; p++) {
luma = copperbuffer[p] & 0x0F; // 0 is transparent
if (luma) {
chroma = copperbuffer[p] >> 4;
cc = ui::Color(std::min((coppercolor[chroma][0] / luma) * drum, 255), std::min((coppercolor[chroma][1] / luma) * drum, 255), std::min((coppercolor[chroma][2] / luma) * drum, 255));
for (r = 0; r < 180; r++)
framebuffer[(p * 180) + r] = cc;
}
}
// Scroll in/out state machine
if (anim_state == 0) {
// Scroll in
if (ofy < 8) {
ofy++;
anim_state = 0;
} else {
anim_state = 1;
}
if (ofx < (int16_t)(180 - (strlen(credits[credits_index].name) * 16) - 8)) {
ofx += 8;
anim_state = 0;
}
} else if (anim_state == 1) {
// Just wait
if (credits_timer == (30 * 3)) {
credits_timer = 0;
anim_state = 2;
} else {
credits_timer++;
}
} else {
// Scroll out
if (credits[credits_index].change == true) {
if (ofy > -24) {
ofy--;
anim_state = 2;
} else {
anim_state = 0;
}
} else {
anim_state = 0;
}
if (ofx < 180) {
ofx += 8;
anim_state = 2;
}
// Switch to next text
if (anim_state == 0) {
if (credits_index == 9)
credits_index = 0;
else
credits_index++;
ofx = -(strlen(credits[credits_index].name) * 16) - 16;
}
}
// Sine text ("role")
p = 0;
while ((ch = credits[credits_index].role[p])) {
draw_demoglyph({(ui::Coord)(8 + (p * 16)), (ui::Coord)(ofy + (sine_table_f32[((p * 16) + (phase >> 5)) & 0xFF] * 8))}, ch, paletteA);
p++;
}
// Scroll text (name)
p = 0;
while ((ch = credits[credits_index].name[p])) {
draw_demoglyph({(ui::Coord)(ofx + (p * 16)), 56}, ch, paletteB);
p++;
}
// Clear bars Y buffer
memset(copperbuffer, 0, 72);
// Render bars to Y buffer
for (p = 0; p < 5; p++) {
cy = copperbars[p];
for (r = 0; r < 16; r++)
copperbuffer[cy + r] = copperluma[r] + (p << 4);
}
// Animate bars positions
for (p = 0; p < 5; p++) {
s = sine_table_f32[((p * 32) + (phase / 24)) & 0xFF];
s += sine_table_f32[((p * 16) + (phase / 35)) & 0xFF];
copperbars[p] = 28 + (uint8_t)(s * 14);
}
phase += 128;
}
void AboutView::draw_demoglyph(ui::Point p, char ch, ui::Color* pal) {
uint8_t x, y, c, cl, cr;
uint16_t che;
int16_t lbx, il;
// Map ASCII to font bitmap
if ((ch >= 32) && (ch < 96))
che = char_map[ch - 32];
else
che = 0xFF;
if (che < 0xFF) {
che = (che * 128) + 48; // Start in bitmap
il = (180 * p.y) + p.x; // Start il framebuffer
for (y = 0; y < 16; y++) {
if (p.y + y >= 72) break; // Over bottom of framebuffer, abort
if (p.y + y >= 0) {
for (x = 0; x < 8; x++) {
c = demofont_bin[x + (y * 8) + che]; // Split byte in 2 4BPP pixels
cl = c >> 4;
cr = c & 0x0F;
lbx = p.x + (x * 2);
if (cl && (lbx < 180) && (lbx >= 0)) framebuffer[il] = pal[cl];
lbx++;
il++;
if (cr && (lbx < 180) && (lbx >= 0)) framebuffer[il] = pal[cr];
il++;
}
il += 180 - 16;
} else {
il += 180;
}
}
}
}
void AboutView::render_audio() {
uint8_t i, ymdata;
uint16_t ym_render_cnt;
// This is heavily inspired by MAME's ay8910.cpp and the YM2149's datasheet
// Render 1024 music samples
for (ym_render_cnt = 0; ym_render_cnt < 1024; ym_render_cnt++) {
// Update registers at 48000/960 = 50Hz
if (ym_sample_cnt == 0) {
// "Decompress" on the fly and update YM registers
for (i = 0; i < 14; i++) {
if (!ym_regs[i].cnt) {
// New run
ymdata = ymdata_bin[ym_regs[i].ptr++];
ym_regs[i].cnt = ymdata & 0x7F;
if (ymdata & 0x80) {
ym_regs[i].same = true;
ym_regs[i].value = ymdata_bin[ym_regs[i].ptr++];
} else {
ym_regs[i].same = false;
}
// Detect drum on channel B
if (i == 3)
if (ym_regs[3].value > 2) drum = 4;
}
if (ym_regs[i].same == false) {
ym_regs[i].value = ymdata_bin[ym_regs[i].ptr++];
if (i == 13) {
// Update envelope attributes
ym_env_att = (ym_regs[13].value & 4) ? 0x1F : 0x00;
if (!(ym_regs[13].value & 8)) {
ym_env_hold = 1;
ym_env_alt = ym_env_att;
} else {
ym_env_hold = ym_regs[13].value & 1;
ym_env_alt = ym_regs[13].value & 2;
}
// Reset envelope counter
ym_env_step = 0x1F;
ym_env_holding = 0;
ym_env_vol = (ym_env_step ^ ym_env_att);
}
}
ym_regs[i].cnt--;
}
ym_frame++;
}
// Square wave oscillators
// 2457600/16/48000 = 3.2, but 4 sounds better than 3...
for (i = 0; i < 3; i++) {
ym_osc_cnt[i] += 4;
if (ym_osc_cnt[i] >= (ym_regs[i * 2].value | ((ym_regs[(i * 2) + 1].value & 0x0f) << 8))) {
ym_osc_cnt[i] = 0;
ym_osc_out[i] ^= 1;
}
}
// Noise generator
ym_noise_cnt += 4;
if (ym_noise_cnt >= ((ym_regs[6].value & 0x1F) * 2)) {
ym_noise_cnt = 0;
ym_rng ^= (((ym_rng & 1) ^ ((ym_rng >> 3) & 1)) << 17);
ym_rng >>= 1;
}
// Mix tones and noise
for (i = 0; i < 3; i++)
ym_ch[i] = (ym_osc_out[i] | ((ym_regs[7].value >> i) & 1)) & ((ym_rng & 1) | ((ym_regs[7].value >> (i + 3)) & 1));
// Envelope generator
if (!ym_env_holding) {
ym_env_cnt += 8;
if (ym_env_cnt >= (ym_regs[11].value | (ym_regs[12].value << 8))) {
ym_env_cnt = 0;
ym_env_step--;
if (ym_env_step < 0) {
if (ym_env_hold) {
if (ym_env_alt)
ym_env_att ^= 0x1F;
ym_env_holding = 1;
ym_env_step = 0;
} else {
if (ym_env_alt && (ym_env_step & 0x20))
ym_env_att ^= 0x1F;
ym_env_step &= 0x1F;
}
}
}
}
ym_env_vol = (ym_env_step ^ ym_env_att);
ym_out = 0;
for (i = 0; i < 3; i++) {
if (ym_regs[i + 8].value & 0x10) {
// Envelope mode
ym_out += (ym_ch[i] ? ym_env_vol : 0);
} else {
// Fixed mode
ym_out += (ym_ch[i] ? (ym_regs[i + 8].value & 0x0F) : 0);
}
}
ym_buffer[ym_render_cnt] = (ym_out * 2) - 45;
if (ym_sample_cnt < 960) {
ym_sample_cnt++;
} else {
ym_sample_cnt = 0;
}
// Loop
if (ym_frame == ym_frames) ym_init();
}
}
void AboutView::update() {
if (framebuffer) {
// Update 1 out of 2 frames, 60Hz is very laggy
if (refresh_cnt & 1) render_video();
refresh_cnt++;
}
// Slowly increase volume to avoid jumpscare
if (headphone_vol < (70 << 2)) {
audio::headphone::set_volume(volume_t::decibel((headphone_vol / 4) - 99) + audio::headphone::volume_range().max);
headphone_vol++;
}
}
void AboutView::ym_init() {
uint8_t reg;
for (reg = 0; reg < 14; reg++) {
ym_regs[reg].cnt = 0;
// Pick up start pointers for each YM registers RLE blocks
ym_regs[reg].ptr = ((uint16_t)(ymdata_bin[(reg * 2) + 3]) << 8) + ymdata_bin[(reg * 2) + 2];
ym_regs[reg].same = false; // Useless ?
ym_regs[reg].value = 0; // Useless ?
}
ym_frame = 0;
}
AboutView::AboutView(
NavigationView& nav) {
uint8_t p, c;
baseband::run_image(portapack::spi_flash::image_tag_audio_tx);
add_children({{
&text_title,
&text_firmware,
&text_cpld_hackrf,
&text_cpld_hackrf_status,
&button_ok,
}});
if (cpld_hackrf_verify_eeprom()) {
text_cpld_hackrf_status.set(" OK");
} else {
text_cpld_hackrf_status.set("BAD");
}
// Politely ask for about 26kB
framebuffer = (ui::Color*)chHeapAlloc(0x0, 180 * 72 * sizeof(ui::Color));
if (framebuffer) {
memset(framebuffer, 0, 180 * 72 * sizeof(ui::Color));
// Copy original font palette
c = 0;
for (p = 0; p < 48; p += 3)
paletteA[c++] = ui::Color(demofont_bin[p], demofont_bin[p + 1], demofont_bin[p + 2]);
// Increase red in another one
c = 0;
for (p = 0; p < 48; p += 3)
paletteB[c++] = ui::Color(std::min(demofont_bin[p] + 64, 255), demofont_bin[p + 1], demofont_bin[p + 2]);
}
// Init YM synth
ym_frames = ((uint16_t)(ymdata_bin[1]) << 8) + ymdata_bin[0];
ym_init();
button_ok.on_select = [this, &nav](Button&) {
if (framebuffer) chHeapFree(framebuffer); // Do NOT forget this
nav.pop();
};
}
AboutView::~AboutView() {
transmitter_model.disable();
baseband::shutdown();
}
void AboutView::focus() {
button_ok.focus();
}
} /* namespace ui */

View File

@@ -1,168 +0,0 @@
/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef __UI_ABOUT_H__
#define __UI_ABOUT_H__
#include "ui_widget.hpp"
#include "ui_menu.hpp"
#include "ui_navigation.hpp"
#include "transmitter_model.hpp"
#include "baseband_api.hpp"
#include <cstdint>
namespace ui {
class AboutView : public View {
public:
AboutView(NavigationView& nav);
~AboutView();
void on_show() override;
void focus() override;
private:
void ym_init();
void update();
void render_video();
void render_audio();
void draw_demoglyph(ui::Point p, char ch, ui::Color* pal);
uint16_t debug_cnt = 0;
typedef struct ymreg_t {
uint8_t value;
uint8_t cnt;
uint16_t ptr;
bool same;
} ymreg_t;
uint16_t headphone_vol = 5 << 2;
ymreg_t ym_regs[14];
uint16_t ym_frames;
uint16_t ym_frame;
uint8_t drum = 0;
uint16_t ym_osc_cnt[3];
uint32_t ym_rng = 1;
uint16_t ym_noise_cnt;
uint8_t ym_env_att, ym_env_hold, ym_env_alt, ym_env_holding, ym_env_vol;
int8_t ym_env_step;
uint16_t ym_env_cnt;
uint8_t ym_osc_out[3];
uint8_t ym_ch[3];
uint8_t ym_out;
uint16_t ym_sample_cnt = 0;
int8_t ym_buffer[1024];
uint8_t refresh_cnt;
ui::Color paletteA[16];
ui::Color paletteB[16];
ui::Color* framebuffer;
uint32_t phase = 0;
uint8_t copperbars[5] = {0};
uint8_t copperbuffer[72] = {0};
uint8_t anim_state = 0;
uint8_t credits_index = 0;
uint16_t credits_timer = 0;
int16_t ofx = -180, ofy = -24;
const uint8_t char_map[64] = {0xFF, 27, 46, 0xFF, 0xFF, 0xFF, 28, 45,
58, 59, 0xFF, 43, 40, 57, 26, 42,
29, 30, 31, 32, 33, 34, 35, 36,
37, 38, 41, 0xFF, 0xFF, 0xFF, 0xFF, 44,
0xFF, 0, 1, 2, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22,
23, 24, 25, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
const uint8_t copperluma[16] = {8, 7, 6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6, 7, 8};
const uint8_t coppercolor[5][3] = {{255, 0, 0},
{0, 255, 0},
{0, 0, 255},
{255, 0, 255},
{255, 255, 0}};
typedef struct credits_t {
char role[12];
char name[12];
bool change;
} credits_t;
// 0123456789A 0123456789A
const credits_t credits[10] = {{"GURUS", "J. BOONE", false},
{"GURUS", "M. OSSMANN", true},
{"BUGS", "FURRTEK", true},
{"RDS WAVE", "C. JACQUET", true},
{"POCSAG RX", "T. SAILER", false},
{"POCSAG RX", "E. OENAL", true},
{"XYLOS DATA", "CLX", true},
{"GREETS TO", "SIGMOUNTE", false},
{"GREETS TO", "WINDYOONA", true},
{"THIS MUSIC", "BIG ALEC", true}};
Text text_title{
{100, 32, 40, 16},
"About",
};
Text text_firmware{
{0, 236, 240, 16},
"Version " VERSION_STRING,
};
Text text_cpld_hackrf{
{0, 252, 11 * 8, 16},
"HackRF CPLD",
};
Text text_cpld_hackrf_status{
{240 - 3 * 8, 252, 3 * 8, 16},
"???"};
Button button_ok{
{72, 272, 96, 24},
"OK"};
MessageHandlerRegistration message_handler_update{
Message::ID::DisplayFrameSync,
[this](const Message* const) {
this->update();
}};
MessageHandlerRegistration message_handler_fifo_signal{
Message::ID::FIFOSignal,
[this](const Message* const p) {
const auto message = static_cast<const FIFOSignalMessage*>(p);
if (message->signaltype == 1) {
this->render_audio();
baseband::set_fifo_data(ym_buffer);
}
}};
};
} /* namespace ui */
#endif /*__UI_ABOUT_H__*/

View File

@@ -1,288 +0,0 @@
/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "ui_numbers.hpp"
#include "string_format.hpp"
#include "portapack.hpp"
#include "hackrf_hal.hpp"
#include "portapack_shared_memory.hpp"
#include <cstring>
#include <stdio.h>
using namespace portapack;
namespace ui {
// TODO: This app takes way too much space, find a way to shrink/simplify or make it an SD card module (loadable)
void NumbersStationView::focus() {
if (file_error)
nav_.display_modal("No voices", "No valid voices found in\nthe /numbers directory.", ABORT);
else
button_exit.focus();
}
NumbersStationView::~NumbersStationView() {
transmitter_model.disable();
baseband::shutdown();
}
NumbersStationView::wav_file_t* NumbersStationView::get_wav(uint32_t index) {
return &current_voice->available_wavs[index];
}
void NumbersStationView::prepare_audio() {
uint8_t code;
wav_file_t* wav_file;
if (sample_counter >= sample_length) {
if (segment == ANNOUNCE) {
if (!announce_loop) {
code_index = 0;
segment = MESSAGE;
} else {
wav_file = get_wav(11);
reader->open(current_voice->dir + file_names[wav_file->index].name + ".wav");
sample_length = wav_file->length;
announce_loop--;
}
}
if (segment == MESSAGE) {
if (code_index == 25) {
transmitter_model.disable();
return;
}
code = symfield_code.get_offset(code_index);
if (code >= 10) {
memset(audio_buffer, 0, 1024);
if (code == 10) {
pause = 11025; // p: 0.25s @ 44100Hz
} else if (code == 11) {
pause = 33075; // P: 0.75s @ 44100Hz
} else if (code == 12) {
transmitter_model.disable();
return;
}
} else {
wav_file = get_wav(code);
reader->open(current_voice->dir + file_names[code].name + ".wav");
sample_length = wav_file->length;
}
code_index++;
}
sample_counter = 0;
}
if (!pause) {
auto bytes_read = reader->read(audio_buffer, 1024).value();
// Unsigned to signed, pretty stupid :/
for (size_t n = 0; n < bytes_read; n++)
audio_buffer[n] -= 0x80;
for (size_t n = bytes_read; n < 1024; n++)
audio_buffer[n] = 0;
sample_counter += 1024;
} else {
if (pause >= 1024) {
pause -= 1024;
} else {
sample_counter = sample_length;
pause = 0;
}
}
baseband::set_fifo_data(audio_buffer);
}
void NumbersStationView::start_tx() {
// sample_length = sound_sizes[10]; // Announce
sample_counter = sample_length;
code_index = 0;
announce_loop = 2;
segment = ANNOUNCE;
prepare_audio();
transmitter_model.set_rf_amp(true);
transmitter_model.enable();
baseband::set_audiotx_data(
(1536000 / 44100) - 1, // TODO: Read wav file's samplerate
12000,
1,
false,
0);
}
void NumbersStationView::on_tick_second() {
armed_blink = not armed_blink;
if (armed_blink)
check_armed.set_style(Theme::getInstance()->fg_red);
else
check_armed.set_style(&style());
check_armed.set_dirty();
}
void NumbersStationView::on_voice_changed(size_t index) {
std::string code_list;
for (const auto& wavs : voices[index].available_wavs)
code_list += wavs.code;
symfield_code.set_symbol_list(code_list);
current_voice = &voices[index];
}
bool NumbersStationView::check_wav_validity(const std::string dir, const std::string file) {
if (reader->open("/numbers/" + dir + "/" + file)) {
// Check format (mono, 8 bits)
if ((reader->channels() == 1) && (reader->bits_per_sample() == 8))
return true;
else
return false;
} else
return false;
}
NumbersStationView::NumbersStationView(
NavigationView& nav)
: nav_(nav) {
std::vector<std::filesystem::path> directory_list;
using option_t = std::pair<std::string, int32_t>;
using options_t = std::vector<option_t>;
options_t voice_options;
voice_t temp_voice{};
bool valid;
uint32_t c;
// uint8_t y, m, d, dayofweek;
reader = std::make_unique<WAVFileReader>();
// Search for valid voice directories
directory_list = scan_root_directories("/numbers");
if (!directory_list.size()) {
file_error = true;
return;
}
for (const auto& dir : directory_list) {
c = 0;
for (const auto& file_name : file_names) {
valid = check_wav_validity(dir.string(), file_name.name + ".wav");
if ((!valid) && (file_name.required)) {
temp_voice.available_wavs.clear();
break; // Invalid required file means invalid voice
} else if (valid) {
temp_voice.available_wavs.push_back({file_name.code, c++, 0, 0}); // TODO: Needs length and samplerate
}
}
if (!temp_voice.available_wavs.empty()) {
// Voice can be used, are there accent files ?
c = 0;
for (const auto& file_name : file_names) {
valid = check_wav_validity(dir.string(), file_name.name + "a.wav");
if ((!valid) && (file_name.required)) {
c = 0;
break; // Invalid required file means accents can't be used
} else if (valid) {
c++;
}
}
temp_voice.accent = c ? true : false;
temp_voice.dir = dir.string();
voices.push_back(temp_voice);
}
}
if (voices.empty()) {
file_error = true;
return;
}
baseband::run_image(portapack::spi_flash::image_tag_audio_tx);
add_children({&labels,
&symfield_code,
&check_armed,
&options_voices,
&text_voice_flags,
//&button_tx_now,
&button_exit});
for (const auto& voice : voices)
voice_options.emplace_back(voice.dir.substr(0, 4), 0);
options_voices.set_options(voice_options);
options_voices.on_change = [this](size_t i, int32_t) {
this->on_voice_changed(i);
};
options_voices.set_selected_index(0);
check_armed.set_value(false);
check_armed.on_select = [this](Checkbox&, bool v) {
if (v) {
armed_blink = false;
signal_token_tick_second = rtc_time::signal_tick_second += [this]() {
this->on_tick_second();
};
} else {
check_armed.set_style(&style());
rtc_time::signal_tick_second -= signal_token_tick_second;
}
};
// DEBUG
symfield_code.set_offset(0, 10);
symfield_code.set_offset(1, 3);
symfield_code.set_offset(2, 4);
symfield_code.set_offset(3, 11);
symfield_code.set_offset(4, 6);
symfield_code.set_offset(5, 1);
symfield_code.set_offset(6, 9);
symfield_code.set_offset(7, 7);
symfield_code.set_offset(8, 8);
symfield_code.set_offset(9, 0);
symfield_code.set_offset(10, 12); // End
/*
dayofweek = rtc_time::current_day_of_week();
text_title.set(day_of_week[dayofweek]);
*/
button_exit.on_select = [&nav](Button&) {
nav.pop();
};
}
} /* namespace ui */

View File

@@ -1,175 +0,0 @@
/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef __UI_NUMBERS_H__
#define __UI_NUMBERS_H__
#include "ui.hpp"
#include "ui_widget.hpp"
#include "ui_receiver.hpp"
#include "ui_navigation.hpp"
#include "rtc_time.hpp"
#include "clock_manager.hpp"
#include "baseband_api.hpp"
#include "utility.hpp"
#include "message.hpp"
#include "file.hpp"
#include "io_wave.hpp"
#include "radio_state.hpp"
namespace ui {
class NumbersStationView : public View {
public:
NumbersStationView(NavigationView& nav);
~NumbersStationView();
NumbersStationView(const NumbersStationView&) = delete;
NumbersStationView(NumbersStationView&&) = delete;
NumbersStationView& operator=(const NumbersStationView&) = delete;
NumbersStationView& operator=(NumbersStationView&&) = delete;
void focus() override;
std::string title() const override { return "Station"; };
private:
NavigationView& nav_;
TxRadioState radio_state_{
0 /* frequency */,
1750000 /* bandwidth */,
1536000 /* sampling rate */
};
// Sequencing state machine
enum segments {
IDLE = 0,
ANNOUNCE,
MESSAGE,
SIGNOFF
};
typedef struct {
char code;
uint32_t index;
uint32_t length;
uint32_t samplerate;
} wav_file_t;
struct voice_t {
std::string dir;
std::vector<wav_file_t> available_wavs;
bool accent;
};
std::vector<voice_t> voices{};
voice_t* current_voice{};
struct wav_file_list_t {
std::string name;
bool required;
char code;
};
const std::vector<wav_file_list_t> file_names = {
{"0", true, '0'},
{"1", true, '1'},
{"2", true, '2'},
{"3", true, '3'},
{"4", true, '4'},
{"5", true, '5'},
{"6", true, '6'},
{"7", true, '7'},
{"8", true, '8'},
{"9", true, '9'},
{"announce", false, 'A'}};
segments segment{IDLE};
bool armed{false};
bool file_error{false};
// const uint8_t month_table[12] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 };
// const char * day_of_week[7] = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };
std::unique_ptr<WAVFileReader> reader{};
uint8_t code_index{0}, announce_loop{0};
uint32_t sample_counter{0};
uint32_t sample_length{0};
int8_t audio_buffer[1024]{};
uint32_t pause{0};
bool armed_blink{false};
SignalToken signal_token_tick_second{};
wav_file_t* get_wav(uint32_t index);
bool check_wav_validity(const std::string dir, const std::string file);
void on_voice_changed(size_t index);
void on_tick_second();
void prepare_audio();
void start_tx();
Labels labels{
{{2 * 8, 5 * 8}, "Voice: Flags:", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 8 * 8}, "Code:", Theme::getInstance()->fg_light->foreground}};
OptionsField options_voices{
{8 * 8, 1 * 8},
4,
{}};
Text text_voice_flags{
{19 * 8, 1 * 8, 2 * 8, 16},
""};
SymField symfield_code{
{1 * 8, 10 * 8},
25,
SymField::Type::Custom};
Checkbox check_armed{
{2 * 8, 13 * 16},
5,
"Armed"};
/*
Button button_tx_now {
{ 18 * 8, 13 * 16, 10 * 8, 32 },
"TX now"};
*/
Button button_exit{
{21 * 8, 16 * 16, 64, 32},
"Exit"};
MessageHandlerRegistration message_handler_fifo_signal{
Message::ID::RequestSignal,
[this](const Message* const p) {
const auto message = static_cast<const RequestSignalMessage*>(p);
if (message->signal == RequestSignalMessage::Signal::FillRequest) {
this->prepare_audio();
}
}};
};
} /* namespace ui */
#endif /*__UI_NUMBERS_H__*/

View File

@@ -1,185 +0,0 @@
/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "ui_nuoptix.hpp"
#include "ch.h"
#include "portapack.hpp"
#include "lfsr_random.hpp"
#include "string_format.hpp"
#include "portapack_shared_memory.hpp"
#include <cstring>
#include <vector>
using namespace portapack;
namespace ui {
void NuoptixView::focus() {
number_timecode.focus();
}
NuoptixView::~NuoptixView() {
transmitter_model.disable();
baseband::shutdown();
}
void NuoptixView::on_tx_progress(const uint32_t progress, const bool done) {
if (done)
transmit(false);
else
progressbar.set_value(progress);
}
void NuoptixView::transmit(bool setup) {
uint8_t mod, tone_code;
uint8_t c;
uint8_t dtmf_message[6];
rtc::RTC datetime;
if (!tx_mode) {
transmitter_model.disable();
return;
}
if (tx_mode == IMPROVISE)
timecode = lfsr_iterate(timecode) % 1999; // Could be 9999 but that would be one long audio track !
if (setup) {
progressbar.set_max(6 * 2);
if (tx_mode == IMPROVISE) {
// Seed from RTC
rtcGetTime(&RTCD1, &datetime);
timecode = datetime.day() + datetime.second();
} else {
timecode = number_timecode.value();
}
transmitter_model.set_rf_amp(true);
transmitter_model.enable();
dtmf_message[0] = '*'; // "Pre-tone for restart" method #1
dtmf_message[1] = 'A'; // "Restart" method #1
} else {
dtmf_message[0] = '#';
dtmf_message[1] = (timecode / 1000) % 10;
chThdSleepMilliseconds(92); // 141-49ms
number_timecode.set_value(timecode);
}
progressbar.set_value(0);
dtmf_message[2] = (timecode / 100) % 10;
dtmf_message[3] = (timecode / 10) % 10;
dtmf_message[4] = timecode % 10;
mod = 0;
for (c = 1; c < 5; c++)
if (dtmf_message[c] <= 9)
mod += dtmf_message[c];
mod = 10 - (mod % 10);
if (mod == 10) mod = 0; // Is this right ?
text_mod.set("Mod: " + to_string_dec_uint(mod));
dtmf_message[5] = mod;
for (c = 0; c < 6; c++) {
tone_code = dtmf_message[c];
if (tone_code == 'A')
tone_code = 10;
else if (tone_code == 'B')
tone_code = 11;
else if (tone_code == 'C')
tone_code = 12;
else if (tone_code == 'D')
tone_code = 13;
else if (tone_code == '#')
tone_code = 14;
else if (tone_code == '*')
tone_code = 15;
shared_memory.bb_data.tones_data.message[c * 2] = tone_code;
shared_memory.bb_data.tones_data.message[c * 2 + 1] = 0xFF; // Silence
}
for (c = 0; c < 16; c++) {
baseband::set_tone(c * 2, dtmf_deltas[c][0], NUOPTIX_TONE_LENGTH);
baseband::set_tone(c * 2 + 1, dtmf_deltas[c][1], NUOPTIX_TONE_LENGTH);
}
shared_memory.bb_data.tones_data.silence = NUOPTIX_TONE_LENGTH; // 49ms tone, 49ms space
audio::set_rate(audio::Rate::Hz_24000);
baseband::set_tones_config(transmitter_model.channel_bandwidth(), 0, 6 * 2, true, true);
timecode++;
}
NuoptixView::NuoptixView(
NavigationView& nav) {
baseband::run_image(portapack::spi_flash::image_tag_tones);
add_children({&number_timecode,
&text_timecode,
&text_mod,
&progressbar,
&tx_view});
number_timecode.set_value(1);
tx_view.on_edit_frequency = [this, &nav]() {
auto new_view = nav.push<FrequencyKeypadView>(transmitter_model.target_frequency());
new_view->on_changed = [this](rf::Frequency f) {
transmitter_model.set_target_frequency(f);
};
};
tx_view.on_start = [this]() {
tx_view.set_transmitting(true);
tx_mode = NORMAL;
transmit(true);
};
tx_view.on_stop = [this]() {
tx_view.set_transmitting(false);
tx_mode = IDLE;
};
/*button_impro.on_select = [this](Button&){
if (tx_mode == IMPROVISE) {
tx_mode = IDLE;
button_impro.set_text("IMPROVISE");
} else if (tx_mode == IDLE) {
tx_mode = IMPROVISE;
button_impro.set_text("STOP");
transmit(true);
}
};*/
}
} // namespace ui

View File

@@ -1,109 +0,0 @@
/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef __UI_NUOPTIX_H__
#define __UI_NUOPTIX_H__
#include "ui.hpp"
#include "ui_widget.hpp"
#include "baseband_api.hpp"
#include "ui_navigation.hpp"
#include "ui_transmitter.hpp"
#include "rtc_time.hpp"
#include "tonesets.hpp"
#include "message.hpp"
#include "volume.hpp"
#include "audio.hpp"
#include "radio_state.hpp"
#define NUOPTIX_TONE_LENGTH ((TONES_SAMPLERATE * 0.049) - 1) // 49ms
namespace ui {
class NuoptixView : public View {
public:
NuoptixView(NavigationView& nav);
~NuoptixView();
void focus() override;
std::string title() const override { return "Nuoptix sync"; };
private:
enum tx_modes {
IDLE = 0,
NORMAL,
IMPROVISE
};
TxRadioState radio_state_{
0 /* frequency */,
1750000 /* bandwidth */,
1536000 /* sampling rate */
};
tx_modes tx_mode{IDLE};
void transmit(bool setup);
void on_tx_progress(const uint32_t progress, const bool done);
uint32_t timecode{0};
Text text_timecode{
{10 * 8, 2 * 16, 9 * 8, 16},
"Timecode:"};
NumberField number_timecode{
{13 * 8, 3 * 16},
4,
{1, 9999},
1,
'0'};
Text text_mod{
{10 * 8, 5 * 16, 6 * 8, 16},
"Mod: "};
ProgressBar progressbar{
{16, 14 * 16, 208, 16}};
/*Button button_impro {
{ 64, 184, 112, 40 },
"IMPROVISE"
};*/
TransmitterView tx_view{
16 * 16,
10000,
15};
MessageHandlerRegistration message_handler_tx_progress{
Message::ID::TXProgress,
[this](const Message* const p) {
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
this->on_tx_progress(message.progress, message.done);
}};
};
} /* namespace ui */
#endif /*__UI_NUOPTIX_H__*/

View File

@@ -28,7 +28,6 @@
#include "file.hpp"
#include "file_reader.hpp"
#include "tone_key.hpp"
#include "replay_app.hpp"
#include "string_format.hpp"
#include "ui_fileman.hpp"
#include "io_file.hpp"

View File

@@ -1,106 +0,0 @@
/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "ui_script.hpp"
#include "portapack.hpp"
#include "event_m0.hpp"
#include <cstring>
using namespace portapack;
namespace ui {
void ScriptView::on_frequency_select() {
// button_edit_freq.focus();
}
void ScriptView::on_edit_freq(rf::Frequency f) {
(void)f;
// frequencies[menu_view.highlighted()].value = f;
setup_list();
}
void ScriptView::on_edit_desc(NavigationView& nav) {
(void)nav;
}
void ScriptView::on_delete() {
// frequencies.erase(frequencies.begin() + menu_view.highlighted());
setup_list();
}
void ScriptView::setup_list() {
// size_t n;
menu_view.clear();
/*for (n = 0; n < frequencies.size(); n++) {
menu_view.add_item({ freqman_item_string(frequencies[n]), Theme::getInstance()->bg_darkest->foreground, nullptr, [this](){ on_frequency_select(); } });
}*/
menu_view.set_parent_rect({0, 0, 240, 168});
menu_view.set_highlighted(menu_view.highlighted()); // Refresh
}
void ScriptView::focus() {
menu_view.focus();
}
ScriptView::ScriptView(
NavigationView& nav) {
add_children({&menu_view,
&text_edit,
&button_edit_freq,
&button_edit_desc,
&button_del,
&button_exit});
setup_list();
button_edit_freq.on_select = [this, &nav](Button&) {
/*auto new_view = nav.push<FrequencyKeypadView>(frequencies[menu_view.highlighted()].value);
new_view->on_changed = [this](rf::Frequency f) {
on_edit_freq(f);
};*/
};
button_edit_desc.on_select = [this, &nav](Button&) {
on_edit_desc(nav);
};
button_del.on_select = [this, &nav](Button&) {
nav.push<ModalMessageView>("Confirm", "Are you sure?", YESNO,
[this](bool choice) {
if (choice) {
on_delete();
}
});
};
button_exit.on_select = [this, &nav](Button&) {
nav.pop();
};
}
} // namespace ui

View File

@@ -1,88 +0,0 @@
/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "ui.hpp"
#include "ui_widget.hpp"
#include "ui_painter.hpp"
#include "ui_menu.hpp"
#include "ui_navigation.hpp"
#include "ui_receiver.hpp"
#include "ui_textentry.hpp"
#include "rtc_time.hpp"
namespace ui {
enum script_keyword {
STOP = 0,
WAIT_N,
WAIT_RTC,
IF,
LOOP,
END,
TX,
RX
};
struct script_line {
script_keyword keyword;
};
class ScriptView : public View {
public:
ScriptView(NavigationView& nav);
void focus() override;
std::string title() const override { return "Script editor"; };
private:
void on_frequency_select();
void on_edit_freq(rf::Frequency f);
void on_edit_desc(NavigationView& nav);
void on_delete();
void setup_list();
std::vector<script_line> script{};
MenuView menu_view{
{0, 0, 240, 168},
true};
Text text_edit{
{16, 194, 5 * 8, 16},
"Edit:"};
Button button_edit_freq{
{16, 194 + 16, 88, 32},
"Frequency"};
Button button_edit_desc{
{16, 194 + 16 + 34, 88, 32},
"Description"};
Button button_del{
{160, 192, 72, 64},
"Delete"};
Button button_exit{
{160, 264, 72, 32},
"Exit"};
};
} /* namespace ui */

View File

@@ -1,54 +0,0 @@
/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2018 Furrtek
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "ui_tone_search.hpp"
#include "baseband_api.hpp"
#include "string_format.hpp"
using namespace portapack;
namespace ui {
void ToneSearchView::focus() {
// field_frequency_min.focus();
}
ToneSearchView::~ToneSearchView() {
receiver_model.disable();
baseband::shutdown();
}
ToneSearchView::ToneSearchView(
NavigationView& nav)
: nav_(nav) {
// baseband::run_image(portapack::spi_flash::image_tag_wideband_spectrum);
add_children({
&labels,
&field_lna,
&field_vga,
&field_rf_amp,
});
}
} /* namespace ui */

View File

@@ -1,68 +0,0 @@
/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2018 Furrtek
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "receiver_model.hpp"
#include "ui_receiver.hpp"
namespace ui {
class ToneSearchView : public View {
public:
ToneSearchView(NavigationView& nav);
~ToneSearchView();
void focus() override;
std::string title() const override { return "Tone search"; };
private:
NavigationView& nav_;
Labels labels{
{{0 * 8, 0 * 8}, "LNA: VGA: AMP:", Theme::getInstance()->fg_light->foreground}};
LNAGainField field_lna{
{4 * 8, 0 * 16}};
VGAGainField field_vga{
{11 * 8, 0 * 16}};
RFAmpField field_rf_amp{
{18 * 8, 0 * 16}};
/*
MessageHandlerRegistration message_handler_frame_sync {
Message::ID::DisplayFrameSync,
[this](const Message* const) {
if( this->fifo ) {
ChannelSpectrum channel_spectrum;
while( fifo->out(channel_spectrum) ) {
this->on_channel_spectrum(channel_spectrum);
}
}
this->do_timers();
}
};*/
};
} /* namespace ui */