feat: audio format + fade/normalize/gain widgets; free them from the transport row
This commit is contained in:
@@ -4460,8 +4460,41 @@ class MainWindow(QMainWindow):
|
|||||||
"Extract this exact length of audio from the playhead and save it")
|
"Extract this exact length of audio from the playhead and save it")
|
||||||
self._btn_extract_audio.setEnabled(False)
|
self._btn_extract_audio.setEnabled(False)
|
||||||
self._btn_extract_audio.clicked.connect(self._on_extract_audio)
|
self._btn_extract_audio.clicked.connect(self._on_extract_audio)
|
||||||
transport_row.addWidget(self._spn_audio_len)
|
|
||||||
transport_row.addWidget(self._btn_extract_audio)
|
# Output format (persisted) — drives the extract extension + save filter.
|
||||||
|
self._cmb_audio_fmt = QComboBox()
|
||||||
|
for label, ext in (("WAV", ".wav"), ("MP3", ".mp3"), ("FLAC", ".flac"),
|
||||||
|
("M4A", ".m4a"), ("OGG", ".ogg"), ("OPUS", ".opus")):
|
||||||
|
self._cmb_audio_fmt.addItem(label, ext)
|
||||||
|
saved_fmt = self._settings.value("audio_extract_fmt", ".wav")
|
||||||
|
idx = self._cmb_audio_fmt.findData(saved_fmt)
|
||||||
|
self._cmb_audio_fmt.setCurrentIndex(idx if idx >= 0 else 0)
|
||||||
|
self._cmb_audio_fmt.currentIndexChanged.connect(
|
||||||
|
lambda _i: self._settings.setValue(
|
||||||
|
"audio_extract_fmt", self._cmb_audio_fmt.currentData()))
|
||||||
|
|
||||||
|
# Non-destructive edit controls (applied via ffmpeg -af at extract time).
|
||||||
|
# Edit params are per-extract (intentionally not persisted); only the format is sticky.
|
||||||
|
self._spn_fade_in = QDoubleSpinBox()
|
||||||
|
self._spn_fade_in.setRange(0.0, 30.0)
|
||||||
|
self._spn_fade_in.setDecimals(2)
|
||||||
|
self._spn_fade_in.setSingleStep(0.1)
|
||||||
|
self._spn_fade_in.setSuffix(" s")
|
||||||
|
self._spn_fade_in.setToolTip("Fade-in duration (0 = none)")
|
||||||
|
self._spn_fade_out = QDoubleSpinBox()
|
||||||
|
self._spn_fade_out.setRange(0.0, 30.0)
|
||||||
|
self._spn_fade_out.setDecimals(2)
|
||||||
|
self._spn_fade_out.setSingleStep(0.1)
|
||||||
|
self._spn_fade_out.setSuffix(" s")
|
||||||
|
self._spn_fade_out.setToolTip("Fade-out duration (0 = none)")
|
||||||
|
self._chk_normalize = QCheckBox("Normalize")
|
||||||
|
self._chk_normalize.setToolTip("Apply EBU R128 loudness normalization (loudnorm)")
|
||||||
|
self._spn_gain = QDoubleSpinBox()
|
||||||
|
self._spn_gain.setRange(-30.0, 30.0)
|
||||||
|
self._spn_gain.setDecimals(1)
|
||||||
|
self._spn_gain.setSingleStep(0.5)
|
||||||
|
self._spn_gain.setSuffix(" dB")
|
||||||
|
self._spn_gain.setToolTip("Gain applied to the extracted audio (0 = unchanged)")
|
||||||
self._transport_row = transport_row
|
self._transport_row = transport_row
|
||||||
|
|
||||||
# Row 1b — subcategory (subprofile) export buttons live on their own
|
# Row 1b — subcategory (subprofile) export buttons live on their own
|
||||||
|
|||||||
@@ -282,3 +282,16 @@ def test_audio_deck_tab_exists(win):
|
|||||||
labels = [win._control_deck.tabText(i)
|
labels = [win._control_deck.tabText(i)
|
||||||
for i in range(win._control_deck.count())]
|
for i in range(win._control_deck.count())]
|
||||||
assert "Audio" in labels and "Scan" not in labels
|
assert "Audio" in labels and "Scan" not in labels
|
||||||
|
|
||||||
|
|
||||||
|
def test_audio_edit_widgets_exist(win):
|
||||||
|
from PyQt6.QtWidgets import QComboBox, QCheckBox, QDoubleSpinBox
|
||||||
|
assert isinstance(win._cmb_audio_fmt, QComboBox)
|
||||||
|
assert win._cmb_audio_fmt.count() >= 3 # wav/mp3/flac at least
|
||||||
|
assert isinstance(win._spn_fade_in, QDoubleSpinBox)
|
||||||
|
assert isinstance(win._spn_fade_out, QDoubleSpinBox)
|
||||||
|
assert isinstance(win._chk_normalize, QCheckBox)
|
||||||
|
assert isinstance(win._spn_gain, QDoubleSpinBox)
|
||||||
|
assert win._cmb_audio_fmt.findData(".wav") >= 0
|
||||||
|
assert win._cmb_audio_fmt.findData(".mp3") >= 0
|
||||||
|
assert win._cmb_audio_fmt.findData(".flac") >= 0
|
||||||
|
|||||||
Reference in New Issue
Block a user