Overhaul: 5-task implementation

- Remove TURN decks (3/4), clean up MIDI, layout
- Single cart player with 3-item autoload queue + continue toggle
- Event logging (SessionLogger), mic tracking, large mic timer widget
- LUFS metering moved from external ports to internal master mix
- Master output WAV recording with top-bar REC toggle
- Music mix output (ch 3-8 only, no mics)
- Preview bar for playlist auditioning
- Merged show log with [SONG][CART][TALK] prefixes
- Live CSV writer for OBS song display (~/live_songs.csv)
- Misc fixes: preview race condition, datetime import for recording
This commit is contained in:
2026-07-17 20:44:15 +10:00
parent da8240a9e2
commit 0277089b2d
13 changed files with 1015 additions and 326 deletions
+31 -6
View File
@@ -47,6 +47,7 @@ class TopBarWidget(QFrame):
ratio_changed = Signal(int, int)
save_session = Signal()
load_session = Signal()
recording_toggled = Signal(bool)
def __init__(self, parent=None):
super().__init__(parent)
@@ -98,6 +99,32 @@ class TopBarWidget(QFrame):
self.station_label.setStyleSheet("color: #555555; background: transparent; border: none;")
layout.addWidget(self.station_label)
layout.addStretch()
self.record_btn = QPushButton("● REC")
self.record_btn.setCheckable(True)
self.record_btn.setFixedSize(70, 30)
self.record_btn.setFont(QFont("Arial", 8, QFont.Bold))
self.record_btn.setToolTip("Record master output to WAV")
self.record_btn.setStyleSheet("""
QPushButton {
background-color: #2a1a1a;
color: #664444;
border: 1px solid #442222;
border-radius: 3px;
padding: 0 6px;
}
QPushButton:checked {
background-color: #4a1a1a;
color: #ff4444;
border: 1px solid #ff4444;
}
QPushButton:hover { color: #ff8888; }
QPushButton:checked:hover { background-color: #5a2020; }
""")
self.record_btn.toggled.connect(self._on_record_toggled)
layout.addWidget(self.record_btn)
self.settings_btn = QPushButton()
self.settings_btn.setFixedSize(24, 24)
self.settings_btn.setIconSize(QSize(14, 14))
@@ -132,6 +159,9 @@ class TopBarWidget(QFrame):
# ── Settings popup ─────────────────────────────────────────────
def _on_record_toggled(self, checked):
self.recording_toggled.emit(checked)
def _toggle_settings_popup(self):
self._popup = SettingsPopup(self._midi_engine, self)
self._popup.save_session.connect(self.save_session.emit)
@@ -346,12 +376,7 @@ class SettingsPopup(QFrame):
("Deck 1 Cue", "deck_cue", "deck1"),
("Deck 2 Play/Pause", "deck_play_pause", "deck2"),
("Deck 2 Cue", "deck_cue", "deck2"),
("Deck 3 Play/Pause", "deck_play_pause", "deck3"),
("Deck 4 Play/Pause", "deck_play_pause", "deck4"),
("Cart 1", "cart_trigger", 0),
("Cart 2", "cart_trigger", 1),
("Cart 3", "cart_trigger", 2),
("Cart 4", "cart_trigger", 3),
("Cart Trigger", "cart_trigger", 0),
("Ch 1 Volume", "mixer_volume", 0),
("Ch 2 Volume", "mixer_volume", 1),
("Ch 3 Volume", "mixer_volume", 2),