Line data Source code
1 : #include "gui/views/gui_settings.h"
2 :
3 : #include <imgui.h>
4 :
5 : #include <cstdio>
6 :
7 : #include "gui/theme/theme.h"
8 :
9 : namespace Amplitron {
10 :
11 6 : void GuiSettings::render(bool& show) {
12 6 : const SettingsProps& p = props_;
13 :
14 6 : ImGui::SetNextWindowSize(ImVec2(600, 700), ImGuiCond_FirstUseEver);
15 6 : if (!ImGui::Begin("Audio Settings", &show)) {
16 0 : ImGui::End();
17 0 : return;
18 : }
19 :
20 : // ── Signal routing summary ──
21 6 : ImGui::TextColored(Theme::Gold(), "SIGNAL ROUTING");
22 6 : ImGui::BeginChild("RoutingSummary", ImVec2(0, 60), true);
23 6 : ImGui::TextColored(Theme::Live(), "Guitar IN:");
24 6 : ImGui::SameLine();
25 6 : ImGui::Text("%s", p.input_device_name.c_str());
26 6 : ImGui::TextColored(ImVec4(0.35f, 0.60f, 0.95f, 1.0f), "Speaker OUT:");
27 6 : ImGui::SameLine();
28 6 : ImGui::Text("%s", p.output_device_name.c_str());
29 6 : ImGui::EndChild();
30 :
31 6 : if (!p.device_error.empty()) {
32 6 : ImGui::Spacing();
33 8 : ImGui::TextColored(ImVec4(1.0f, 0.3f, 0.3f, 1.0f), "Device error: %s",
34 2 : p.device_error.c_str());
35 6 : ImGui::SameLine();
36 6 : if (ImGui::SmallButton("Dismiss") && p.on_clear_error) p.on_clear_error();
37 2 : }
38 :
39 6 : ImGui::Spacing();
40 :
41 : // ── Latency ──
42 6 : ImGui::TextColored(Theme::Gold(), "LATENCY");
43 6 : ImGui::Text("Buffer Size (lower = less latency, more CPU):");
44 6 : const int buf_sizes[] = {32, 64, 128, 256, 512};
45 6 : const char* buf_labels[] = {"32", "64", "128", "256", "512"};
46 6 : int current_idx = 1;
47 18 : for (int i = 0; i < 5; ++i)
48 18 : if (buf_sizes[i] == p.buffer_size) {
49 6 : current_idx = i;
50 6 : break;
51 : }
52 6 : if (ImGui::Combo("Buffer Size", ¤t_idx, buf_labels, 5)) {
53 0 : if (p.on_buffer_size_changed) p.on_buffer_size_changed(buf_sizes[current_idx]);
54 0 : }
55 6 : ImGui::Text("Estimated latency: %.1f ms", p.latency_ms);
56 :
57 : #ifdef AMPLITRON_ANDROID_OBOE
58 : ImGui::TextColored(ImVec4(0.2f, 0.9f, 0.4f, 1.0f), "Audio backend: Oboe (%s)",
59 : p.oboe_mode_label);
60 : #endif
61 :
62 : // CPU load
63 6 : ImVec4 load_color = (p.cpu_load > 0.80f) ? ImVec4(1.0f, 0.2f, 0.2f, 1.0f)
64 0 : : (p.cpu_load > 0.50f) ? ImVec4(1.0f, 0.8f, 0.2f, 1.0f)
65 4 : : ImVec4(0.2f, 0.8f, 0.2f, 1.0f);
66 6 : ImGui::Spacing();
67 6 : ImGui::TextColored(load_color, "CPU Load: %.0f%%", p.cpu_load * 100.0f);
68 6 : ImGui::SameLine();
69 6 : ImGui::ProgressBar(p.cpu_load, ImVec2(150, 0));
70 :
71 6 : if (p.suggested_buf != p.buffer_size) {
72 6 : ImGui::SameLine();
73 2 : char suggest_label[64];
74 6 : std::snprintf(suggest_label, sizeof(suggest_label), "Switch to %d", p.suggested_buf);
75 6 : if (ImGui::SmallButton(suggest_label) && p.on_buffer_size_changed)
76 0 : p.on_buffer_size_changed(p.suggested_buf);
77 2 : }
78 :
79 6 : bool auto_buf = p.auto_buf;
80 6 : if (ImGui::Checkbox("Auto-tune buffer size", &auto_buf) && p.on_auto_buf_changed)
81 0 : p.on_auto_buf_changed(auto_buf);
82 :
83 6 : ImGui::Spacing();
84 :
85 : // ── Sample rate ──
86 6 : const int rates[] = {44100, 48000, 96000};
87 6 : const char* rate_labels[] = {"44100", "48000", "96000"};
88 6 : int sr_idx = 1;
89 6 : for (int i = 0; i < 3; ++i)
90 6 : if (rates[i] == p.sample_rate) {
91 6 : sr_idx = i;
92 6 : break;
93 : }
94 6 : if (ImGui::Combo("Sample Rate", &sr_idx, rate_labels, 3)) {
95 0 : if (p.on_sample_rate_changed) p.on_sample_rate_changed(rates[sr_idx]);
96 0 : }
97 :
98 6 : ImGui::Separator();
99 :
100 : // ── Input devices ──
101 6 : ImGui::TextColored(Theme::Gold(), "INPUT DEVICE (USB Guitar Cable)");
102 6 : ImGui::TextWrapped(
103 : "Select your USB guitar cable or audio interface. USB devices are highlighted with [USB].");
104 6 : ImGui::BeginChild("InputDevices", ImVec2(0, 120), true);
105 6 : for (const auto& dev : p.input_devices) {
106 0 : ImGui::PushID(dev.index);
107 0 : bool is_selected = (dev.index == p.current_input);
108 0 : std::string label = dev.name + (dev.is_usb ? " [USB]" : "");
109 0 : if (dev.is_usb) ImGui::PushStyleColor(ImGuiCol_Text, Theme::GoldHot());
110 0 : if (ImGui::Selectable(label.c_str(), is_selected) && p.on_input_device_changed)
111 0 : p.on_input_device_changed(dev.index);
112 0 : if (dev.is_usb) ImGui::PopStyleColor();
113 0 : ImGui::PopID();
114 0 : }
115 6 : ImGui::EndChild();
116 :
117 6 : ImGui::Spacing();
118 :
119 : // ── Output devices ──
120 6 : ImGui::TextColored(Theme::Gold(), "OUTPUT DEVICE (Speakers/Headphones)");
121 6 : ImGui::BeginChild("OutputDevices", ImVec2(0, 120), true);
122 6 : for (const auto& dev : p.output_devices) {
123 0 : ImGui::PushID(dev.index);
124 0 : bool is_selected = (dev.index == p.current_output);
125 0 : std::string label = dev.name + (dev.is_usb ? " [USB - not recommended]" : "");
126 0 : if (dev.is_usb) ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.6f, 0.6f, 0.6f, 0.7f));
127 0 : if (ImGui::Selectable(label.c_str(), is_selected) && p.on_output_device_changed)
128 0 : p.on_output_device_changed(dev.index);
129 0 : if (dev.is_usb) ImGui::PopStyleColor();
130 0 : ImGui::PopID();
131 0 : }
132 6 : ImGui::EndChild();
133 :
134 6 : ImGui::Separator();
135 6 : ImGui::TextDisabled(
136 : "MIDI settings are managed in a separate window (Utilities > MIDI Settings).");
137 :
138 6 : ImGui::End();
139 2 : }
140 :
141 : } // namespace Amplitron
|