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