Multi screen support, with dyn alignment (#2801)

This commit is contained in:
Totoo
2025-10-03 19:10:10 +02:00
committed by GitHub
parent 23cabb8b8a
commit 371b6b5079
161 changed files with 4042 additions and 4157 deletions
+18 -12
View File
@@ -49,26 +49,26 @@ void ViewWavView::refresh_waveform() {
uint8_t bits_per_sample = wav_reader->bits_per_sample();
for (size_t i = 0; i < 240; i++) {
for (size_t i = 0; i < screen_width; i++) {
wav_reader->data_seek(position + (i * scale));
if (bits_per_sample == 8) {
uint8_t sample;
wav_reader->read(&sample, 1);
waveform_buffer[i] = (sample - 0x80) * 256;
} else {
wav_reader->read(&waveform_buffer[i], 2);
wav_reader->read(&waveform_buffer.data()[i], 2);
}
}
waveform.set_dirty();
// Window
uint64_t w_start = (position * 240) / wav_reader->sample_count();
uint64_t w_width = (scale * 240) / (wav_reader->sample_count() / 240);
display.fill_rectangle({0, 10 * 16 + 1, 240, 16}, Theme::getInstance()->bg_darkest->background);
uint64_t w_start = (position * screen_width) / wav_reader->sample_count();
uint64_t w_width = (scale * screen_width) / (wav_reader->sample_count() / screen_width);
display.fill_rectangle({0, 10 * 16 + 1, screen_width, 16}, Theme::getInstance()->bg_darkest->background);
display.fill_rectangle({(Coord)w_start, 21 * 8, (Dim)w_width + 1, 8}, Theme::getInstance()->bg_darkest->foreground);
display.draw_line({0, 10 * 16 + 1}, {(Coord)w_start, 21 * 8}, Theme::getInstance()->bg_darkest->foreground);
display.draw_line({239, 10 * 16 + 1}, {(Coord)(w_start + w_width), 21 * 8}, Theme::getInstance()->bg_darkest->foreground);
display.draw_line({screen_width - 1, 10 * 16 + 1}, {(Coord)(w_start + w_width), 21 * 8}, Theme::getInstance()->bg_darkest->foreground);
}
void ViewWavView::refresh_measurements() {
@@ -82,11 +82,11 @@ void ViewWavView::refresh_measurements() {
void ViewWavView::paint(Painter& painter) {
// Waveform limits
painter.draw_hline({0, 6 * 16 - 1}, 240, Theme::getInstance()->bg_medium->background);
painter.draw_hline({0, 10 * 16}, 240, Theme::getInstance()->bg_medium->background);
painter.draw_hline({0, 6 * 16 - 1}, screen_width, Theme::getInstance()->bg_medium->background);
painter.draw_hline({0, 10 * 16}, screen_width, Theme::getInstance()->bg_medium->background);
// Overall amplitude view, 0~127 to 0~255 color index
for (size_t i = 0; i < 240; i++)
for (size_t i = 0; i < screen_width; i++)
painter.draw_vline({(Coord)i, 11 * 16}, 8, spectrum_rgb2_lut[amplitude_buffer[i] << 1]);
}
@@ -128,10 +128,10 @@ void ViewWavView::load_wav(std::filesystem::path file_path) {
text_title.set(wav_reader->title());
// Fill amplitude buffer, world's worst downsampling
uint64_t skip = wav_reader->sample_count() / (240 * subsampling_factor);
uint64_t skip = wav_reader->sample_count() / (screen_width * subsampling_factor);
uint8_t bits_per_sample = wav_reader->bits_per_sample();
for (size_t i = 0; i < 240; i++) {
for (size_t i = 0; i < screen_width; i++) {
average = 0;
for (size_t s = 0; s < subsampling_factor; s++) {
@@ -163,7 +163,7 @@ void ViewWavView::reset_controls() {
field_pos_seconds.set_range(0, wav_reader->ms_duration() / 1000);
field_pos_milliseconds.set_range(0, (wav_reader->ms_duration() < 1000) ? wav_reader->ms_duration() % 1000 : 999);
field_pos_samples.set_range(0, wav_reader->sample_count() - 1);
field_scale.set_range(1, std::min(99999ul, wav_reader->sample_count() / 240));
field_scale.set_range(1, std::min(99999ul, wav_reader->sample_count() / screen_width));
}
bool ViewWavView::is_active() {
@@ -262,6 +262,12 @@ void ViewWavView::on_playback_progress(const uint32_t progress) {
ViewWavView::ViewWavView(
NavigationView& nav)
: nav_(nav) {
waveform_buffer.resize(screen_width);
amplitude_buffer.resize(screen_width);
waveform.set_length(screen_width);
waveform.set_data((int16_t*)waveform_buffer.data());
for (auto& v : waveform_buffer) v = 0;
for (auto& v : amplitude_buffer) v = 0;
baseband::run_prepared_image(portapack::memory::map::m4_code.base());
wav_reader = std::make_unique<WAVFileReader>();
+23 -22
View File
@@ -73,8 +73,8 @@ class ViewWavView : public View {
std::unique_ptr<WAVFileReader> wav_reader{};
int16_t waveform_buffer[240]{};
uint8_t amplitude_buffer[240]{};
std::vector<int16_t> waveform_buffer{};
std::vector<uint8_t> amplitude_buffer{};
int32_t scale{1};
uint64_t ns_per_pixel{};
uint64_t position{};
@@ -83,53 +83,54 @@ class ViewWavView : public View {
bool waveform_update_needed{false};
Labels labels{
{{0 * 8, 0 * 16}, "File:", Theme::getInstance()->fg_light->foreground},
{{UI_POS_X(0), UI_POS_Y(0)}, "File:", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 1 * 16}, "-bit mono", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 2 * 16}, "Title:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 3 * 16}, "Duration:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 12 * 16}, "Position: . s Scale:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 13 * 16}, " Sample:", Theme::getInstance()->fg_light->foreground},
{{0 * 8, 14 * 16}, "Cursor A:", Theme::getInstance()->fg_darkcyan->foreground},
{{0 * 8, 15 * 16}, "Cursor B:", Theme::getInstance()->fg_magenta->foreground},
{{0 * 8, 16 * 16}, "Delta:", Theme::getInstance()->fg_light->foreground},
{{24 * 8, 18 * 16}, "Vol:", Theme::getInstance()->fg_light->foreground}};
{{UI_POS_X(0), 2 * 16}, "Title:", Theme::getInstance()->fg_light->foreground},
{{UI_POS_X(0), 3 * 16}, "Duration:", Theme::getInstance()->fg_light->foreground},
{{UI_POS_X(0), 12 * 16}, "Position: . s Scale:", Theme::getInstance()->fg_light->foreground},
{{UI_POS_X(0), 13 * 16}, " Sample:", Theme::getInstance()->fg_light->foreground},
{{UI_POS_X(0), 14 * 16}, "Cursor A:", Theme::getInstance()->fg_darkcyan->foreground},
{{UI_POS_X(0), 15 * 16}, "Cursor B:", Theme::getInstance()->fg_magenta->foreground},
{{UI_POS_X(0), 16 * 16}, "Delta:", Theme::getInstance()->fg_light->foreground},
{{UI_POS_X_RIGHT(6), UI_POS_Y_BOTTOM(2)}, "Vol:", Theme::getInstance()->fg_light->foreground}};
Text text_filename{
{5 * 8, 0 * 16, 18 * 8, 16},
{UI_POS_X(5), UI_POS_Y(0), UI_POS_WIDTH_REMAINING(12), UI_POS_HEIGHT(1)},
""};
Text text_samplerate{
{12 * 8, 1 * 16, 10 * 8, 16},
{12 * 8, 1 * 16, 10 * 8, UI_POS_HEIGHT(1)},
""};
Text text_title{
{6 * 8, 2 * 16, 17 * 8, 16},
{6 * 8, 2 * 16, 17 * 8, UI_POS_HEIGHT(1)},
""};
Text text_duration{
{9 * 8, 3 * 16, 20 * 8, 16},
{9 * 8, 3 * 16, 20 * 8, UI_POS_HEIGHT(1)},
""};
Text text_bits_per_sample{
{0 * 8, 1 * 16, 2 * 8, 16},
{UI_POS_X(0), 1 * 16, 2 * 8, UI_POS_HEIGHT(1)},
"16"};
Button button_open{
{24 * 8, 8, 6 * 8, 2 * 16},
{UI_POS_X_RIGHT(6), 8, UI_POS_WIDTH(6), UI_POS_HEIGHT(2)},
"Open"};
ImageButton button_play{
{24 * 8, 17 * 16, 2 * 8, 1 * 16},
{UI_POS_X_RIGHT(6), UI_POS_Y_BOTTOM(3), UI_POS_WIDTH(2), UI_POS_HEIGHT(1)},
&bitmap_play,
Theme::getInstance()->fg_green->foreground,
Theme::getInstance()->fg_green->background};
AudioVolumeField field_volume{
{screen_width - 2 * 8, 18 * 16}};
{UI_POS_X_RIGHT(2), UI_POS_Y_BOTTOM(2)}};
Waveform waveform{
{0, 5 * 16, screen_width, 64},
waveform_buffer,
{0, UI_POS_Y(5), screen_width, UI_POS_HEIGHT(4)},
waveform_buffer.data(),
240,
0,
false,
Theme::getInstance()->bg_darkest->foreground};
ProgressBar progressbar{
{0 * 8, 11 * 16, screen_width, 4}};
{UI_POS_X(0), 11 * 16, screen_width, 4}};
NumberField field_pos_seconds{
{9 * 8, 12 * 16},