""" Main Window — Main application shell with tabbed interface. """ from PyQt6.QtWidgets import QMainWindow, QTabWidget, QVBoxLayout, QWidget, QLabel from PyQt6.QtCore import Qt from core.audio_device import DeviceManager from core.eq_engine import EQEngine from core.tape_processor import TapeProcessor from core.audio_player import AudioPlayer from core.audio_recorder import AudioRecorder from ui.device_panel import DevicePanel from ui.player_panel import PlayerPanel from ui.calibration_panel import CalibrationPanel from ui.eq_panel import EQPanel class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("Tape Recorder Pro - Auto-Calibrating EQ") self.resize(1000, 700) # --- Initialize Core Audio Engine --- self.device_manager = DeviceManager.instance() self.device_manager.auto_select_defaults() self.eq_engine = EQEngine() self.tape_processor = TapeProcessor(self.device_manager.sample_rate) self.player = AudioPlayer(self.eq_engine, self.tape_processor, self.device_manager) self.recorder = AudioRecorder(self.device_manager) self._init_ui() self._update_status() def _init_ui(self): # Central widget and layout central_widget = QWidget() self.setCentralWidget(central_widget) layout = QVBoxLayout(central_widget) layout.setContentsMargins(10, 10, 10, 10) # Tabs self.tabs = QTabWidget() # 1. Device Setup Tab self.device_panel = DevicePanel(self.device_manager) self.device_panel.devices_changed.connect(self._update_status) self.tabs.addTab(self.device_panel, "🔊 Devices") # 2. Calibration Tab self.calibration_panel = CalibrationPanel(self.device_manager, self.eq_engine, self.tape_processor) self.calibration_panel.calibration_complete.connect(self._on_calibration_complete) self.tabs.addTab(self.calibration_panel, "📐 Calibrate") # 3. EQ Tab self.eq_panel = EQPanel(self.eq_engine, self.tape_processor) self.tabs.addTab(self.eq_panel, "🎚️ EQ") # 4. Player Tab self.player_panel = PlayerPanel(self.player) self.tabs.addTab(self.player_panel, "▶️ Player") layout.addWidget(self.tabs) # Status Bar self.statusBar().showMessage("Ready") # Persistent device info labels in status bar self.in_status_lbl = QLabel("Input: None") self.out_status_lbl = QLabel("Output: None") self.statusBar().addPermanentWidget(self.in_status_lbl) self.statusBar().addPermanentWidget(self.out_status_lbl) def _update_status(self): """Update status bar with current device names.""" in_id = self.device_manager.input_device_id if in_id is not None: dev = self.device_manager.get_device_by_index(in_id) name = dev.name if dev else "Unknown" # truncate long names if len(name) > 30: name = name[:27] + "..." self.in_status_lbl.setText(f"In: {name}") else: self.in_status_lbl.setText("In: None") out_id = self.device_manager.output_device_id if out_id is not None: dev = self.device_manager.get_device_by_index(out_id) name = dev.name if dev else "Unknown" if len(name) > 30: name = name[:27] + "..." self.out_status_lbl.setText(f"Out: {name}") else: self.out_status_lbl.setText("Out: None") def _on_calibration_complete(self, bands): """Called when calibration finishes successfully.""" # Refresh the EQ UI to show the newly computed bands self.eq_panel.refresh_ui() # Switch to the EQ tab so the user can see the result self.tabs.setCurrentWidget(self.eq_panel)