Deluge Firmware 1.3.0
Build date: 2025.11.04
Loading...
Searching...
No Matches
audio_recorder.h
1/*
2 * Copyright (c) 2014-2023 Synthstrom Audible Limited
3 *
4 * This file is part of The Synthstrom Audible Deluge Firmware.
5 *
6 * The Synthstrom Audible Deluge Firmware is free software: you can redistribute it and/or modify it under the
7 * terms of the GNU General Public License as published by the Free Software Foundation,
8 * either version 3 of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
11 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with this program.
15 * If not, see <https://www.gnu.org/licenses/>.
16 */
17#pragma once
18#include "gui/l10n/l10n.h"
19#include "gui/menu_item/formatted_title.h"
20#include "gui/menu_item/menu_item.h"
21#include "gui/ui/audio_recorder.h"
22#include "gui/ui/sound_editor.h"
23#include "gui/ui_timer_manager.h"
24#include "processing/sound/sound.h"
25#include "storage/flash_storage.h"
26
27namespace deluge::gui::menu_item::osc {
28class AudioRecorder final : public MenuItem, FormattedTitle {
29public:
30 AudioRecorder(l10n::String newName, uint8_t sourceId)
31 : MenuItem(newName), FormattedTitle(newName, sourceId + 1), source_id_{sourceId} {}
32
33 [[nodiscard]] std::string_view getTitle() const override { return FormattedTitle::title(); }
34 [[nodiscard]] std::string_view getName() const override { return FormattedTitle::title(); }
35
36 void beginSession(MenuItem* navigatedBackwardFrom) override {
37 soundEditor.shouldGoUpOneLevelOnBegin = true;
38 soundEditor.setCurrentSource(source_id_);
39
40 if (parentMenuHeadingTo != nullptr && menuItemHeadingTo != nullptr) {
41 parentMenuHeadingTo->focusChild(menuItemHeadingTo);
42 soundEditor.navigationDepth = 0;
43 soundEditor.menuItemNavigationRecord[soundEditor.navigationDepth] = parentMenuHeadingTo;
44 soundEditor.shouldGoUpOneLevelOnBegin = false;
45
46 parentMenuHeadingTo = nullptr;
47 menuItemHeadingTo = nullptr;
48 }
49
50 if (bool success = openUI(&audioRecorder); !success) {
51 if (getCurrentUI() == &soundEditor) {
52 soundEditor.goUpOneLevel();
53 }
54 return uiTimerManager.unsetTimer(TimerName::SHORTCUT_BLINK);
55 }
56
57 audioRecorder.process();
58 }
59
60 bool isRelevant(ModControllableAudio* modControllable, int32_t) override {
61 const auto sound = static_cast<Sound*>(modControllable);
62 return sound->getSynthMode() == SynthMode::SUBTRACTIVE;
63 }
64
65 MenuPermission checkPermissionToBeginSession(ModControllableAudio* modControllable, int32_t,
66 ::MultiRange** currentRange) override {
67 if (!isRelevant(modControllable, source_id_)) {
68 display->displayPopup(l10n::get(l10n::String::STRING_FOR_CANT_RECORD_AUDIO_FM_MODE));
69 return MenuPermission::NO;
70 }
71
72 Sound* sound = static_cast<Sound*>(modControllable);
73 return soundEditor.checkPermissionToBeginSessionForRangeSpecificParam(sound, source_id_, currentRange);
74 }
75
76 [[nodiscard]] bool allowToBeginSessionFromHorizontalMenu() override { return true; }
77 [[nodiscard]] int32_t getColumnSpan() const override { return 2; }
78 [[nodiscard]] bool showColumnLabel() const override { return false; }
79 [[nodiscard]] bool showNotification() const override { return false; }
80
81 void renderInHorizontalMenu(const HorizontalMenuSlotParams& slot) override {
82 using namespace hid::display;
83 oled_canvas::Canvas& image = OLED::main;
84
85 // Draw "rec" part
86 const uint8_t start_x = slot.start_x + 8;
87 const uint8_t start_y = slot.start_y + kHorizontalMenuSlotYOffset + 6;
88 constexpr uint8_t circle_radius = 3;
89 image.drawCircle(start_x + circle_radius + 1, start_y + circle_radius + 1, circle_radius, true);
90 image.drawString("rec", start_x + circle_radius * 2 + 5, start_y, kTextSpacingX, kTextSpacingY);
91
92 // Draw the source number
93 DEF_STACK_STRING_BUF(buf, kShortStringBufferSize);
94 buf.appendInt(source_id_ + 1);
95 uint8_t source_x = slot.start_x + slot.width - kTextBigSpacingX - 7;
96 uint8_t source_y = slot.start_y + kHorizontalMenuSlotYOffset + 4;
97
98 const bool full_inversion = FlashStorage::accessibilityMenuHighlighting == MenuHighlighting::FULL_INVERSION;
99 if (full_inversion || parent->getCurrentItem() == this) {
100 image.drawString(buf.data(), source_x, source_y, kTextBigSpacingX, kTextBigSizeY);
101 }
102 else {
103 image.drawString(buf.data(), source_x - 1, source_y + 2, kTextSpacingX, kTextSpacingY);
104 }
105
106 // Draw separator in the middle
107 if (!full_inversion && source_id_ == 0) {
108 const uint8_t y0 = slot.start_y + kHorizontalMenuSlotYOffset + 1;
109 const uint8_t y1 = y0 + 18;
110 for (uint8_t y = y0; y <= y1; y += 2) {
111 image.drawPixel(slot.start_x + slot.width - 1, y);
112 }
113 }
114 }
115
116 HorizontalMenu* parentMenuHeadingTo{nullptr};
117 MenuItem* menuItemHeadingTo{nullptr};
118
119private:
120 uint8_t source_id_;
121};
122} // namespace deluge::gui::menu_item::osc
Definition mod_controllable_audio.h:47
Definition sound.h:71
Definition multi_range.h:24
bool allowToBeginSessionFromHorizontalMenu() override
Allow entering menu session by selecting the menu item twice in Horizontal menu.
Definition audio_recorder.h:76
int32_t getColumnSpan() const override
Get the number of occupied virtual columns in Horizontal menu.
Definition audio_recorder.h:77
bool showColumnLabel() const override
Show a label for the parameter in Horizontal menu.
Definition audio_recorder.h:78
void beginSession(MenuItem *navigatedBackwardFrom) override
Begin an editing session with this menu item.
Definition audio_recorder.h:36
bool showNotification() const override
Show a popup with the full name and value of the editing parameter at the top of Horizontal menu.
Definition audio_recorder.h:79
bool isRelevant(ModControllableAudio *modControllable, int32_t) override
Check if this MenuItem should show up in a containing deluge::gui::menu_item::Submenu.
Definition audio_recorder.h:60
std::string_view getName() const override
Get the actual name for use on OLED for deluge::gui::menu_item::Submenu s.
Definition audio_recorder.h:34
std::string_view getTitle() const override
Get the title to be used when rendering on OLED, both as a deluge::gui::menu_item::Submenu and when d...
Definition audio_recorder.h:33
Definition menu_item.h:33