yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
music_playback_control_panel.h
Go to the documentation of this file.
1#ifndef YAZE_APP_EDITOR_MUSIC_PANELS_MUSIC_PLAYBACK_CONTROL_PANEL_H_
2#define YAZE_APP_EDITOR_MUSIC_PANELS_MUSIC_PLAYBACK_CONTROL_PANEL_H_
3
4#include <array>
5#include <chrono>
6#include <cmath>
7#include <cstdint>
8#include <cstdio>
9#include <functional>
10#include <string>
11#include "util/i18n/tr.h"
12
15#include "app/gui/core/icons.h"
16#include "app/gui/core/input.h"
20#include "imgui/imgui.h"
22
23namespace yaze {
24namespace editor {
25
31 public:
33 int* current_song_index,
34 music::MusicPlayer* music_player)
35 : music_bank_(music_bank),
36 current_song_index_(current_song_index),
37 music_player_(music_player) {}
38
39 // ==========================================================================
40 // WindowContent Identity
41 // ==========================================================================
42
43 std::string GetId() const override { return "music.tracker"; }
44 std::string GetDisplayName() const override { return "Playback Control"; }
45 std::string GetIcon() const override { return ICON_MD_PLAY_CIRCLE; }
46 std::string GetEditorCategory() const override { return "Music"; }
50 int GetPriority() const override { return 10; }
51
52 // ==========================================================================
53 // Callback Setters
54 // ==========================================================================
55
56 void SetOnOpenSong(std::function<void(int)> callback) {
57 on_open_song_ = callback;
58 }
59
60 void SetOnOpenPianoRoll(std::function<void(int)> callback) {
61 on_open_piano_roll_ = callback;
62 }
63
64 // ==========================================================================
65 // WindowContent Drawing
66 // ==========================================================================
67
68 void Draw(bool* p_open) override {
70 ImGui::TextDisabled(tr("Music system not initialized"));
71 return;
72 }
73
75 ImGui::Separator();
79
80 // Debug controls (collapsed by default)
82
83 // Help section (collapsed by default)
84 if (ImGui::CollapsingHeader(ICON_MD_KEYBOARD " Keyboard Shortcuts")) {
85 ImGui::BulletText(tr("Space: Play/Pause toggle"));
86 ImGui::BulletText(tr("Escape: Stop playback"));
87 ImGui::BulletText(tr("+/-: Increase/decrease speed"));
88 ImGui::BulletText(tr("Arrow keys: Navigate in tracker/piano roll"));
89 ImGui::BulletText(tr("Z,S,X,D,C,V,G,B,H,N,J,M: Piano keyboard (C to B)"));
90 ImGui::BulletText(tr("Ctrl+Wheel: Zoom (Piano Roll)"));
91 }
92 }
93
94 private:
95 void DrawToolset() {
96 auto state =
98 bool can_play = music_player_ && music_player_->IsAudioReady();
100
101 if (!can_play)
102 ImGui::BeginDisabled();
103
104 // Transport controls
105 if (state.is_playing && !state.is_paused) {
106 gui::StyleColorGuard pause_guard(ImGuiCol_Button,
108 if (ImGui::Button(ICON_MD_PAUSE "##Pause"))
110 if (ImGui::IsItemHovered())
111 ImGui::SetTooltip(tr("Pause (Space)"));
112 } else if (state.is_paused) {
113 gui::StyleColorGuard resume_guard(ImGuiCol_Button,
115 if (ImGui::Button(ICON_MD_PLAY_ARROW "##Resume"))
117 if (ImGui::IsItemHovered())
118 ImGui::SetTooltip(tr("Resume (Space)"));
119 } else {
120 if (ImGui::Button(ICON_MD_PLAY_ARROW "##Play"))
122 if (ImGui::IsItemHovered())
123 ImGui::SetTooltip(tr("Play (Space)"));
124 }
125
126 ImGui::SameLine();
127 if (ImGui::Button(ICON_MD_STOP "##Stop"))
129 if (ImGui::IsItemHovered())
130 ImGui::SetTooltip(tr("Stop (Escape)"));
131
132 if (!can_play)
133 ImGui::EndDisabled();
134
135 // Song label with playing indicator
136 ImGui::SameLine();
137 if (song) {
138 if (state.is_playing && !state.is_paused) {
139 float t = static_cast<float>(ImGui::GetTime() * 3.0);
140 float alpha = 0.5f + 0.5f * std::sin(t);
141 auto c = gui::GetSuccessColor();
142 ImGui::TextColored(ImVec4(c.x, c.y, c.z, alpha), ICON_MD_GRAPHIC_EQ);
143 ImGui::SameLine();
144 } else if (state.is_paused) {
145 ImGui::TextColored(gui::GetWarningColor(), ICON_MD_PAUSE_CIRCLE);
146 ImGui::SameLine();
147 }
148 ImGui::Text("%s", song->name.c_str());
149 if (song->modified) {
150 ImGui::SameLine();
151 ImGui::TextColored(gui::GetWarningColor(), ICON_MD_EDIT);
152 }
153 } else {
154 ImGui::TextDisabled(tr("No song selected"));
155 }
156
157 // Time display
158 if (state.is_playing || state.is_paused) {
159 ImGui::SameLine();
160 float seconds = state.ticks_per_second > 0
161 ? state.current_tick / state.ticks_per_second
162 : 0.0f;
163 int mins = static_cast<int>(seconds) / 60;
164 int secs = static_cast<int>(seconds) % 60;
165 ImGui::TextColored(gui::GetInfoColor(), " %d:%02d", mins, secs);
166 }
167
168 // Right-aligned controls
169 float right_offset = ImGui::GetWindowWidth() - 200;
170 if (right_offset > 200) {
171 ImGui::SameLine(right_offset);
172
173 ImGui::Text(ICON_MD_SPEED);
174 ImGui::SameLine();
175 ImGui::SetNextItemWidth(70);
176 float speed = state.playback_speed;
177 if (gui::SliderFloatWheel("##Speed", &speed, 0.25f, 2.0f, "%.2fx",
178 0.1f)) {
179 if (music_player_)
181 }
182 if (ImGui::IsItemHovered())
183 ImGui::SetTooltip(tr("Playback speed (+/- keys)"));
184
185 ImGui::SameLine();
186 ImGui::Text(ICON_MD_VOLUME_UP);
187 ImGui::SameLine();
188 ImGui::SetNextItemWidth(60);
189 if (gui::SliderIntWheel("##Vol", &current_volume_, 0, 100, "%d%%", 5)) {
190 if (music_player_)
192 }
193 if (ImGui::IsItemHovered())
194 ImGui::SetTooltip(tr("Volume"));
195 }
196 }
197
200
201 if (song) {
202 ImGui::Text(tr("Selected Song:"));
203 ImGui::SameLine();
204 ImGui::TextColored(gui::GetInfoColor(), "[%02X] %s",
205 *current_song_index_ + 1, song->name.c_str());
206
207 ImGui::SameLine();
208 ImGui::TextDisabled(tr("| %zu segments"), song->segments.size());
209 if (song->modified) {
210 ImGui::SameLine();
211 ImGui::TextColored(gui::GetWarningColor(), ICON_MD_EDIT " Modified");
212 }
213 }
214 }
215
217 auto state =
220
221 if (state.is_playing || state.is_paused) {
222 ImGui::Separator();
223
224 // Timeline progress
225 if (song && !song->segments.empty()) {
226 uint32_t total_duration = 0;
227 for (const auto& seg : song->segments) {
228 total_duration += seg.GetDuration();
229 }
230
231 float progress =
232 (total_duration > 0)
233 ? static_cast<float>(state.current_tick) / total_duration
234 : 0.0f;
235 progress = std::clamp(progress, 0.0f, 1.0f);
236
237 float current_seconds =
238 state.ticks_per_second > 0
239 ? state.current_tick / state.ticks_per_second
240 : 0.0f;
241 float total_seconds = state.ticks_per_second > 0
242 ? total_duration / state.ticks_per_second
243 : 0.0f;
244
245 int cur_min = static_cast<int>(current_seconds) / 60;
246 int cur_sec = static_cast<int>(current_seconds) % 60;
247 int tot_min = static_cast<int>(total_seconds) / 60;
248 int tot_sec = static_cast<int>(total_seconds) % 60;
249
250 ImGui::Text("%d:%02d / %d:%02d", cur_min, cur_sec, tot_min, tot_sec);
251 ImGui::SameLine();
252 ImGui::ProgressBar(progress, ImVec2(-1, 0), "");
253 }
254
255 ImGui::Text(tr("Segment: %d | Tick: %u"), state.current_segment_index + 1,
256 state.current_tick);
257 ImGui::SameLine();
258 ImGui::TextDisabled(tr("| %.1f ticks/sec | %.2fx speed"),
259 state.ticks_per_second, state.playback_speed);
260 }
261 }
262
264 ImGui::Separator();
265
266 if (ImGui::Button(ICON_MD_OPEN_IN_NEW " Open Tracker")) {
267 if (on_open_song_)
269 }
270 if (ImGui::IsItemHovered())
271 ImGui::SetTooltip(tr("Open song in dedicated tracker window"));
272
273 ImGui::SameLine();
274 if (ImGui::Button(ICON_MD_PIANO " Open Piano Roll")) {
277 }
278 if (ImGui::IsItemHovered())
279 ImGui::SetTooltip(tr("Open piano roll view for this song"));
280 }
281
283 if (!music_player_)
284 return;
285
286 if (!ImGui::CollapsingHeader(ICON_MD_BUG_REPORT " Debug Controls"))
287 return;
288
289 ImGui::Indent();
290
291 // Pause updates checkbox
292 ImGui::Checkbox(tr("Pause Updates"), &debug_paused_);
293 ImGui::SameLine();
294 if (ImGui::Button(tr("Snapshot"))) {
295 // Force capture current values
296 debug_paused_ = true;
297 }
298 ImGui::SameLine();
299 ImGui::TextDisabled(tr("(Freeze display to read values)"));
300
301 // Capture current state (unless paused)
302 if (!debug_paused_) {
307
308 // Track statistics using wall-clock time for accuracy
310 auto now = std::chrono::steady_clock::now();
311
312 // Initialize on first call
313 if (last_stats_time_.time_since_epoch().count() == 0) {
314 last_stats_time_ = now;
317 }
318
319 auto elapsed =
320 std::chrono::duration<double>(now - last_stats_time_).count();
321
322 // Update stats every 0.5 seconds
323 if (elapsed >= 0.5) {
324 uint64_t cycle_delta = cached_apu_.cycles - last_cycles_for_rate_;
325 int32_t queue_delta =
326 static_cast<int32_t>(cached_audio_.queued_frames) -
327 static_cast<int32_t>(last_queued_for_rate_);
328
329 // Calculate actual rates based on elapsed wall-clock time
330 avg_cycle_rate_ = static_cast<uint64_t>(cycle_delta / elapsed);
331 avg_queue_delta_ = static_cast<int32_t>(queue_delta / elapsed);
332
333 // Reset for next measurement
334 last_stats_time_ = now;
337 }
338 } else {
339 // Reset when stopped
340 last_stats_time_ = std::chrono::steady_clock::time_point();
341 }
342 }
343
344 // === Quick Summary (always visible) ===
345 ImGui::Separator();
346 ImVec4 status_color = cached_audio_.is_playing ? gui::GetSuccessColor()
348 ImGui::TextColored(status_color,
349 cached_audio_.is_playing ? "PLAYING" : "STOPPED");
350 ImGui::SameLine();
351 ImGui::Text(tr("| Queue: %u frames"), cached_audio_.queued_frames);
352 ImGui::SameLine();
353 ImGui::Text(tr("| DSP: %u/2048"), cached_dsp_.sample_offset);
354
355 // Queue trend indicator
356 ImGui::SameLine();
357 if (avg_queue_delta_ > 50) {
358 ImGui::TextColored(gui::GetErrorColor(),
359 ICON_MD_TRENDING_UP " GROWING (too fast!)");
360 } else if (avg_queue_delta_ < -50) {
361 ImGui::TextColored(gui::GetWarningColor(),
362 ICON_MD_TRENDING_DOWN " DRAINING");
363 } else {
364 ImGui::TextColored(gui::GetSuccessColor(),
365 ICON_MD_TRENDING_FLAT " STABLE");
366 }
367
368 // Cycle rate check (should be ~1,024,000/sec)
369 if (avg_cycle_rate_ > 0) {
370 float rate_ratio = avg_cycle_rate_ / 1024000.0f;
371 ImGui::Text(tr("APU Rate: %.2fx expected"), rate_ratio);
372 if (rate_ratio > 1.1f) {
373 ImGui::SameLine();
374 ImGui::TextColored(gui::GetErrorColor(), tr("(APU running too fast!)"));
375 }
376 }
377
378 ImGui::Separator();
379
380 // === DSP Buffer Status ===
381 if (ImGui::TreeNode("DSP Buffer")) {
382 auto& dsp = cached_dsp_;
383
384 ImGui::Text(tr("Sample Offset: %u / 2048"), dsp.sample_offset);
385 ImGui::Text(tr("Frame Boundary: %u"), dsp.frame_boundary);
386
387 // Buffer fill progress bar
388 float fill = dsp.sample_offset / 2048.0f;
389 char overlay[32];
390 snprintf(overlay, sizeof(overlay), "%.1f%%", fill * 100.0f);
391 ImGui::ProgressBar(fill, ImVec2(-1, 0), overlay);
392
393 // Drift indicator
394 int32_t drift = static_cast<int32_t>(dsp.sample_offset) -
395 static_cast<int32_t>(dsp.frame_boundary);
396 ImVec4 drift_color = (std::abs(drift) > 100) ? gui::GetErrorColor()
398 ImGui::TextColored(drift_color, tr("Drift: %+d samples"), drift);
399
400 ImGui::Text(tr("Master Vol: L=%d R=%d"), dsp.master_vol_l,
401 dsp.master_vol_r);
402
403 // Status flags
404 if (dsp.mute) {
405 ImGui::TextColored(gui::GetWarningColor(), ICON_MD_VOLUME_OFF " MUTED");
406 ImGui::SameLine();
407 }
408 if (dsp.reset) {
409 ImGui::TextColored(gui::GetErrorColor(), ICON_MD_RESTART_ALT " RESET");
410 ImGui::SameLine();
411 }
412 if (dsp.echo_enabled) {
413 ImGui::TextColored(gui::GetInfoColor(),
414 ICON_MD_SURROUND_SOUND " Echo (delay=%u)",
415 dsp.echo_delay);
416 }
417
418 ImGui::TreePop();
419 }
420
421 // === Audio Queue Status ===
422 if (ImGui::TreeNode("Audio Queue")) {
423 auto& audio = cached_audio_;
424
425 // Status indicator
426 if (audio.is_playing) {
427 ImGui::TextColored(gui::GetSuccessColor(),
428 ICON_MD_PLAY_CIRCLE " Playing");
429 } else {
430 ImGui::TextColored(gui::GetDisabledColor(),
431 ICON_MD_STOP_CIRCLE " Stopped");
432 }
433
434 ImGui::Text(tr("Queued: %u frames (%u bytes)"), audio.queued_frames,
435 audio.queued_bytes);
436 ImGui::Text(tr("Sample Rate: %d Hz"), audio.sample_rate);
437 ImGui::Text(tr("Backend: %s"), audio.backend_name.c_str());
438
439 // Underrun warning
440 if (audio.has_underrun) {
441 ImGui::TextColored(gui::GetErrorColor(),
442 ICON_MD_WARNING " UNDERRUN DETECTED");
443 }
444
445 // Queue level indicator
446 float queue_level = audio.queued_frames / 6000.0f; // ~100ms worth
447 queue_level = std::clamp(queue_level, 0.0f, 1.0f);
448 ImVec4 queue_color =
449 (queue_level < 0.2f) ? gui::GetErrorColor() : gui::GetSuccessColor();
450 {
451 gui::StyleColorGuard queue_guard(ImGuiCol_PlotHistogram, queue_color);
452 ImGui::ProgressBar(queue_level, ImVec2(-1, 0), "Queue Level");
453 }
454
455 ImGui::TreePop();
456 }
457
458 // === APU Timing ===
459 if (ImGui::TreeNode("APU Timing")) {
460 auto& apu = cached_apu_;
461
462 ImGui::Text(tr("Cycles: %llu"),
463 static_cast<unsigned long long>(apu.cycles));
464
465 // Timers in a table
466 if (ImGui::BeginTable("Timers", 4, ImGuiTableFlags_Borders)) {
467 ImGui::TableSetupColumn("Timer");
468 ImGui::TableSetupColumn("Enabled");
469 ImGui::TableSetupColumn("Counter");
470 ImGui::TableSetupColumn("Target");
471 ImGui::TableHeadersRow();
472
473 // Timer 0
474 ImGui::TableNextRow();
475 ImGui::TableNextColumn();
476 ImGui::Text(tr("T0"));
477 ImGui::TableNextColumn();
478 ImGui::TextColored(apu.timer0_enabled ? gui::GetSuccessColor()
480 apu.timer0_enabled ? "ON" : "off");
481 ImGui::TableNextColumn();
482 ImGui::Text("%u", apu.timer0_counter);
483 ImGui::TableNextColumn();
484 ImGui::Text("%u", apu.timer0_target);
485
486 // Timer 1
487 ImGui::TableNextRow();
488 ImGui::TableNextColumn();
489 ImGui::Text(tr("T1"));
490 ImGui::TableNextColumn();
491 ImGui::TextColored(apu.timer1_enabled ? gui::GetSuccessColor()
493 apu.timer1_enabled ? "ON" : "off");
494 ImGui::TableNextColumn();
495 ImGui::Text("%u", apu.timer1_counter);
496 ImGui::TableNextColumn();
497 ImGui::Text("%u", apu.timer1_target);
498
499 // Timer 2
500 ImGui::TableNextRow();
501 ImGui::TableNextColumn();
502 ImGui::Text(tr("T2"));
503 ImGui::TableNextColumn();
504 ImGui::TextColored(apu.timer2_enabled ? gui::GetSuccessColor()
506 apu.timer2_enabled ? "ON" : "off");
507 ImGui::TableNextColumn();
508 ImGui::Text("%u", apu.timer2_counter);
509 ImGui::TableNextColumn();
510 ImGui::Text("%u", apu.timer2_target);
511
512 ImGui::EndTable();
513 }
514
515 // Port state
516 ImGui::Text(tr("Ports IN: [0]=%02X [1]=%02X"), apu.port0_in,
517 apu.port1_in);
518 ImGui::Text(tr("Ports OUT: [0]=%02X [1]=%02X"), apu.port0_out,
519 apu.port1_out);
520
521 ImGui::TreePop();
522 }
523
524 // === Channel Overview ===
525 if (ImGui::TreeNode("Channels")) {
526 auto& channels = cached_channels_;
527
528 ImGui::Text(tr("Key Status:"));
529 ImGui::SameLine();
530 for (int i = 0; i < 8; i++) {
531 ImVec4 color = channels[i].key_on ? gui::GetSuccessColor()
533 ImGui::TextColored(color, "%d", i);
534 if (i < 7)
535 ImGui::SameLine();
536 }
537
538 // Detailed channel info
539 if (ImGui::BeginTable("ChannelDetails", 6,
540 ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) {
541 ImGui::TableSetupColumn("Ch", ImGuiTableColumnFlags_WidthFixed, 25);
542 ImGui::TableSetupColumn("Key");
543 ImGui::TableSetupColumn("Sample");
544 ImGui::TableSetupColumn("Pitch");
545 ImGui::TableSetupColumn("Vol L/R");
546 ImGui::TableSetupColumn("ADSR");
547 ImGui::TableHeadersRow();
548
549 const char* adsr_names[] = {"Atk", "Dec", "Sus", "Rel"};
550 for (int i = 0; i < 8; i++) {
551 ImGui::TableNextRow();
552 ImGui::TableNextColumn();
553 ImGui::Text("%d", i);
554 ImGui::TableNextColumn();
555 ImGui::TextColored(channels[i].key_on ? gui::GetSuccessColor()
557 channels[i].key_on ? "ON" : "--");
558 ImGui::TableNextColumn();
559 ImGui::Text("%02X", channels[i].sample_index);
560 ImGui::TableNextColumn();
561 ImGui::Text("%04X", channels[i].pitch);
562 ImGui::TableNextColumn();
563 ImGui::Text("%02X/%02X", channels[i].volume_l, channels[i].volume_r);
564 ImGui::TableNextColumn();
565 int state = channels[i].adsr_state & 0x03;
566 ImGui::Text("%s", adsr_names[state]);
567 }
568
569 ImGui::EndTable();
570 }
571
572 ImGui::TreePop();
573 }
574
575 // === Action Buttons ===
576 ImGui::Separator();
577 ImGui::Text(tr("Actions:"));
578
579 if (ImGui::Button(ICON_MD_CLEAR_ALL " Clear Queue")) {
581 }
582 if (ImGui::IsItemHovered())
583 ImGui::SetTooltip(tr("Clear SDL audio queue immediately"));
584
585 ImGui::SameLine();
586 if (ImGui::Button(ICON_MD_REFRESH " Reset DSP")) {
588 }
589 if (ImGui::IsItemHovered())
590 ImGui::SetTooltip(tr("Reset DSP sample ring buffer"));
591
592 ImGui::SameLine();
593 if (ImGui::Button(ICON_MD_SKIP_NEXT " NewFrame")) {
595 }
596 if (ImGui::IsItemHovered())
597 ImGui::SetTooltip(tr("Force DSP NewFrame() call"));
598
599 ImGui::SameLine();
600 if (ImGui::Button(ICON_MD_REPLAY " Reinit Audio")) {
602 }
603 if (ImGui::IsItemHovered())
604 ImGui::SetTooltip(tr("Full audio system reinitialization"));
605
606 ImGui::Unindent();
607 }
608
610 int* current_song_index_ = nullptr;
613
614 std::function<void(int)> on_open_song_;
615 std::function<void(int)> on_open_piano_roll_;
616
617 // Debug state
618 bool debug_paused_ = false;
622 std::array<music::ChannelState, 8> cached_channels_;
623 int32_t avg_queue_delta_ = 0;
624 uint64_t avg_cycle_rate_ = 0;
625
626 // Wall-clock timing for rate measurement
627 std::chrono::steady_clock::time_point last_stats_time_;
630};
631
632} // namespace editor
633} // namespace yaze
634
635#endif // YAZE_APP_EDITOR_MUSIC_PANELS_MUSIC_PLAYBACK_CONTROL_PANEL_H_
WindowContent for music playback controls and status display.
void SetOnOpenPianoRoll(std::function< void(int)> callback)
int GetPriority() const override
Get display priority for menu ordering.
std::string GetIcon() const override
Material Design icon for this panel.
std::string GetEditorCategory() const override
Editor category this panel belongs to.
void SetOnOpenSong(std::function< void(int)> callback)
void Draw(bool *p_open) override
Draw the panel content.
std::chrono::steady_clock::time_point last_stats_time_
std::string GetId() const override
Unique identifier for this panel.
std::string GetDisplayName() const override
Human-readable name shown in menus and title bars.
WindowPresentationPolicy GetPresentationPolicy() const override
How this content is hosted and advertised by workspace chrome.
MusicPlaybackControlPanel(zelda3::music::MusicBank *music_bank, int *current_song_index, music::MusicPlayer *music_player)
std::array< music::ChannelState, 8 > cached_channels_
Base interface for all logical window content components.
Handles audio playback for the music editor using the SNES APU emulator.
ApuDebugStatus GetApuStatus() const
Get APU timing diagnostic status.
void Stop()
Stop playback completely.
void ReinitAudio()
Reinitialize the audio system.
void SetPlaybackSpeed(float speed)
Set the playback speed (0.25x to 2.0x).
void ForceNewFrame()
Force a DSP NewFrame() call.
void SetVolume(float volume)
Set the master volume (0.0 to 1.0).
void Pause()
Pause the current playback.
AudioQueueStatus GetAudioQueueStatus() const
Get audio queue diagnostic status.
std::array< ChannelState, 8 > GetChannelStates() const
void PlaySong(int song_index)
Start playing a song by index.
DspDebugStatus GetDspStatus() const
Get DSP buffer diagnostic status.
void Resume()
Resume paused playback.
bool IsAudioReady() const
Check if the audio system is ready for playback.
PlaybackState GetState() const
void ResetDspBuffer()
Reset the DSP sample buffer.
void ClearAudioQueue()
Clear the audio queue (stops sound immediately).
RAII guard for ImGui style colors.
Definition style_guard.h:27
Manages the collection of songs, instruments, and samples from a ROM.
Definition music_bank.h:27
MusicSong * GetSong(int index)
Get a song by index.
#define ICON_MD_PAUSE_CIRCLE
Definition icons.h:1390
#define ICON_MD_PAUSE
Definition icons.h:1389
#define ICON_MD_PIANO
Definition icons.h:1462
#define ICON_MD_WARNING
Definition icons.h:2123
#define ICON_MD_VOLUME_UP
Definition icons.h:2111
#define ICON_MD_TRENDING_DOWN
Definition icons.h:2013
#define ICON_MD_TRENDING_UP
Definition icons.h:2016
#define ICON_MD_PLAY_ARROW
Definition icons.h:1479
#define ICON_MD_REFRESH
Definition icons.h:1572
#define ICON_MD_STOP
Definition icons.h:1862
#define ICON_MD_BUG_REPORT
Definition icons.h:327
#define ICON_MD_GRAPHIC_EQ
Definition icons.h:890
#define ICON_MD_EDIT
Definition icons.h:645
#define ICON_MD_SPEED
Definition icons.h:1817
#define ICON_MD_REPLAY
Definition icons.h:1588
#define ICON_MD_STOP_CIRCLE
Definition icons.h:1863
#define ICON_MD_CLEAR_ALL
Definition icons.h:417
#define ICON_MD_KEYBOARD
Definition icons.h:1028
#define ICON_MD_PLAY_CIRCLE
Definition icons.h:1480
#define ICON_MD_SKIP_NEXT
Definition icons.h:1773
#define ICON_MD_SURROUND_SOUND
Definition icons.h:1894
#define ICON_MD_OPEN_IN_NEW
Definition icons.h:1354
#define ICON_MD_VOLUME_OFF
Definition icons.h:2110
#define ICON_MD_RESTART_ALT
Definition icons.h:1602
#define ICON_MD_TRENDING_FLAT
Definition icons.h:2014
bool SliderIntWheel(const char *label, int *v, int v_min, int v_max, const char *format, int wheel_step, ImGuiSliderFlags flags)
Definition input.cc:903
ImVec4 GetSuccessColor()
Definition ui_helpers.cc:49
bool SliderFloatWheel(const char *label, float *v, float v_min, float v_max, const char *format, float wheel_step, ImGuiSliderFlags flags)
Definition input.cc:886
ButtonColorSet GetSuccessButtonColors()
ImVec4 GetDisabledColor()
Definition ui_helpers.cc:74
ImVec4 GetErrorColor()
Definition ui_helpers.cc:59
ImVec4 GetWarningColor()
Definition ui_helpers.cc:54
ImVec4 GetInfoColor()
Definition ui_helpers.cc:64
static WindowPresentationPolicy OptionalPopOut()
APU timing diagnostic status for debug UI.
Audio queue diagnostic status for debug UI.
DSP buffer diagnostic status for debug UI.
Represents the current playback state of the music player.