Compare commits
No commits in common. "4ec1c0e09c21260d366d29c5b048dc17910edf65" and "c5ca1469dc2b042f0724f9e8c2460b4c47e91fa1" have entirely different histories.
4ec1c0e09c
...
c5ca1469dc
@ -2,19 +2,23 @@
|
|||||||
|
|
||||||
# Standard library imports
|
# Standard library imports
|
||||||
from os.path import basename
|
from os.path import basename
|
||||||
from typing import List, Optional
|
from time import sleep
|
||||||
|
from typing import cast, List, Optional
|
||||||
import argparse
|
import argparse
|
||||||
import datetime as dt
|
import datetime as dt
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
import threading
|
||||||
|
|
||||||
# PyQt imports
|
# PyQt imports
|
||||||
from PyQt6.QtCore import (
|
from PyQt6.QtCore import (
|
||||||
pyqtSignal,
|
pyqtSignal,
|
||||||
QDate,
|
QDate,
|
||||||
|
QEvent,
|
||||||
QObject,
|
QObject,
|
||||||
|
QSize,
|
||||||
Qt,
|
Qt,
|
||||||
QThread,
|
QThread,
|
||||||
QTime,
|
QTime,
|
||||||
@ -23,7 +27,10 @@ from PyQt6.QtCore import (
|
|||||||
from PyQt6.QtGui import (
|
from PyQt6.QtGui import (
|
||||||
QCloseEvent,
|
QCloseEvent,
|
||||||
QColor,
|
QColor,
|
||||||
|
QFont,
|
||||||
|
QMouseEvent,
|
||||||
QPalette,
|
QPalette,
|
||||||
|
QResizeEvent,
|
||||||
)
|
)
|
||||||
from PyQt6.QtWidgets import (
|
from PyQt6.QtWidgets import (
|
||||||
QApplication,
|
QApplication,
|
||||||
@ -35,6 +42,8 @@ from PyQt6.QtWidgets import (
|
|||||||
QListWidgetItem,
|
QListWidgetItem,
|
||||||
QMainWindow,
|
QMainWindow,
|
||||||
QMessageBox,
|
QMessageBox,
|
||||||
|
QProgressBar,
|
||||||
|
QPushButton,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Third party imports
|
# Third party imports
|
||||||
@ -167,6 +176,7 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
self.widgetFadeVolume.hideAxis("left")
|
self.widgetFadeVolume.hideAxis("left")
|
||||||
self.widgetFadeVolume.setDefaultPadding(0)
|
self.widgetFadeVolume.setDefaultPadding(0)
|
||||||
self.widgetFadeVolume.setBackground(Config.FADE_CURVE_BACKGROUND)
|
self.widgetFadeVolume.setBackground(Config.FADE_CURVE_BACKGROUND)
|
||||||
|
FadeCurve.GraphWidget = self.widgetFadeVolume
|
||||||
|
|
||||||
self.active_tab = lambda: self.tabPlaylist.currentWidget()
|
self.active_tab = lambda: self.tabPlaylist.currentWidget()
|
||||||
self.active_proxy_model = lambda: self.tabPlaylist.currentWidget().model()
|
self.active_proxy_model = lambda: self.tabPlaylist.currentWidget().model()
|
||||||
@ -989,7 +999,7 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
):
|
):
|
||||||
return
|
return
|
||||||
|
|
||||||
log.debug(f"play_next({position=})")
|
log.info(f"play_next({position=})")
|
||||||
|
|
||||||
# If there is no next track set, return.
|
# If there is no next track set, return.
|
||||||
if track_sequence.next is None:
|
if track_sequence.next is None:
|
||||||
@ -1025,13 +1035,6 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
# Play (new) current track
|
# Play (new) current track
|
||||||
track_sequence.current.play(position)
|
track_sequence.current.play(position)
|
||||||
|
|
||||||
# Show closing volume graph
|
|
||||||
if track_sequence.current.fade_graph:
|
|
||||||
track_sequence.current.fade_graph.GraphWidget = self.widgetFadeVolume
|
|
||||||
track_sequence.current.fade_graph.plot()
|
|
||||||
else:
|
|
||||||
log.error("No fade_graph")
|
|
||||||
|
|
||||||
# Disable play next controls
|
# Disable play next controls
|
||||||
self.catch_return_key = True
|
self.catch_return_key = True
|
||||||
self.show_status_message("Play controls: Disabled", 0)
|
self.show_status_message("Play controls: Disabled", 0)
|
||||||
@ -1472,8 +1475,23 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
Called every 10ms
|
Called every 10ms
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if track_sequence.current:
|
return
|
||||||
track_sequence.current.update_fade_graph()
|
# Update volume fade curve
|
||||||
|
if (
|
||||||
|
track_sequence.current.fade_graph_start_updates is None
|
||||||
|
or track_sequence.current.fade_graph_start_updates > dt.datetime.now()
|
||||||
|
):
|
||||||
|
return
|
||||||
|
|
||||||
|
if (
|
||||||
|
track_sequence.current.track_id
|
||||||
|
and track_sequence.current.fade_graph
|
||||||
|
and track_sequence.current.start_time
|
||||||
|
):
|
||||||
|
play_time = (
|
||||||
|
dt.datetime.now() - track_sequence.current.start_time
|
||||||
|
).total_seconds() * 1000
|
||||||
|
track_sequence.current.fade_graph.tick(play_time)
|
||||||
|
|
||||||
def tick_500ms(self) -> None:
|
def tick_500ms(self) -> None:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -43,13 +43,13 @@ class _AddFadeCurve(QObject):
|
|||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
track_manager: _TrackManager,
|
track_player: _TrackManager,
|
||||||
track_path: str,
|
track_path: str,
|
||||||
track_fade_at: int,
|
track_fade_at: int,
|
||||||
track_silence_at: int,
|
track_silence_at: int,
|
||||||
):
|
):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.track_manager = track_manager
|
self.track_player = track_player
|
||||||
self.track_path = track_path
|
self.track_path = track_path
|
||||||
self.track_fade_at = track_fade_at
|
self.track_fade_at = track_fade_at
|
||||||
self.track_silence_at = track_silence_at
|
self.track_silence_at = track_silence_at
|
||||||
@ -63,7 +63,7 @@ class _AddFadeCurve(QObject):
|
|||||||
if not fc:
|
if not fc:
|
||||||
log.error(f"Failed to create FadeCurve for {self.track_path=}")
|
log.error(f"Failed to create FadeCurve for {self.track_path=}")
|
||||||
else:
|
else:
|
||||||
self.track_manager.fade_graph = fc
|
self.track_player.fade_graph = fc
|
||||||
self.finished.emit()
|
self.finished.emit()
|
||||||
|
|
||||||
|
|
||||||
@ -84,10 +84,8 @@ class _FadeCurve:
|
|||||||
|
|
||||||
# Start point of curve is Config.FADE_CURVE_MS_BEFORE_FADE
|
# Start point of curve is Config.FADE_CURVE_MS_BEFORE_FADE
|
||||||
# milliseconds before fade starts to silence
|
# milliseconds before fade starts to silence
|
||||||
self.start_ms: int = max(
|
self.start_ms = max(0, track_fade_at - Config.FADE_CURVE_MS_BEFORE_FADE - 1)
|
||||||
0, track_fade_at - Config.FADE_CURVE_MS_BEFORE_FADE - 1
|
self.end_ms = track_silence_at
|
||||||
)
|
|
||||||
self.end_ms: int = track_silence_at
|
|
||||||
self.audio_segment = audio[self.start_ms : self.end_ms]
|
self.audio_segment = audio[self.start_ms : self.end_ms]
|
||||||
self.graph_array = np.array(self.audio_segment.get_array_of_samples())
|
self.graph_array = np.array(self.audio_segment.get_array_of_samples())
|
||||||
|
|
||||||
@ -289,19 +287,11 @@ class _Music:
|
|||||||
|
|
||||||
self._adjust_by_ms(ms)
|
self._adjust_by_ms(ms)
|
||||||
|
|
||||||
def play(
|
def play(self, path: str, position: Optional[float]) -> None:
|
||||||
self,
|
|
||||||
path: str,
|
|
||||||
start_time: dt.datetime,
|
|
||||||
position: Optional[float] = None,
|
|
||||||
) -> None:
|
|
||||||
"""
|
"""
|
||||||
Start playing the track at path.
|
Start playing the track at path.
|
||||||
|
|
||||||
Log and return if path not found.
|
Log and return if path not found.
|
||||||
|
|
||||||
start_time ensures our version and our caller's version of
|
|
||||||
the start time is the same
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
log.info(f"Music[{self.name}].play({path=}, {position=}")
|
log.info(f"Music[{self.name}].play({path=}, {position=}")
|
||||||
@ -318,7 +308,7 @@ class _Music:
|
|||||||
|
|
||||||
if position:
|
if position:
|
||||||
self.player.set_position(position)
|
self.player.set_position(position)
|
||||||
self.start_dt = start_time
|
self.start_dt = dt.datetime.now()
|
||||||
|
|
||||||
# For as-yet unknown reasons. sometimes the volume gets
|
# For as-yet unknown reasons. sometimes the volume gets
|
||||||
# reset to zero within 200mS or so of starting play. This
|
# reset to zero within 200mS or so of starting play. This
|
||||||
@ -433,8 +423,6 @@ class _TrackManager:
|
|||||||
|
|
||||||
if not self.player.is_playing():
|
if not self.player.is_playing():
|
||||||
self.start_time = None
|
self.start_time = None
|
||||||
if self.fade_graph:
|
|
||||||
self.fade_graph.clear()
|
|
||||||
self.signals.track_ended_signal.emit()
|
self.signals.track_ended_signal.emit()
|
||||||
|
|
||||||
def drop3db(self, enable: bool) -> None:
|
def drop3db(self, enable: bool) -> None:
|
||||||
@ -465,11 +453,10 @@ class _TrackManager:
|
|||||||
def play(self, position: Optional[float] = None) -> None:
|
def play(self, position: Optional[float] = None) -> None:
|
||||||
"""Play track"""
|
"""Play track"""
|
||||||
|
|
||||||
|
self.player.play(self.path, position)
|
||||||
|
|
||||||
now = dt.datetime.now()
|
now = dt.datetime.now()
|
||||||
self.start_time = now
|
self.start_time = now
|
||||||
|
|
||||||
self.player.play(self.path, start_time=now, position=position)
|
|
||||||
|
|
||||||
self.end_time = self.start_time + dt.timedelta(milliseconds=self.duration)
|
self.end_time = self.start_time + dt.timedelta(milliseconds=self.duration)
|
||||||
|
|
||||||
# Calculate time fade_graph should start updating
|
# Calculate time fade_graph should start updating
|
||||||
@ -523,25 +510,6 @@ class _TrackManager:
|
|||||||
|
|
||||||
return self.silence_at - self.time_playing()
|
return self.silence_at - self.time_playing()
|
||||||
|
|
||||||
def update_fade_graph(self) -> None:
|
|
||||||
"""
|
|
||||||
Update fade graph
|
|
||||||
"""
|
|
||||||
|
|
||||||
if (
|
|
||||||
not self.is_playing()
|
|
||||||
or not self.fade_graph_start_updates
|
|
||||||
or not self.fade_graph
|
|
||||||
):
|
|
||||||
return
|
|
||||||
|
|
||||||
now = dt.datetime.now()
|
|
||||||
|
|
||||||
if self.fade_graph_start_updates > now:
|
|
||||||
return
|
|
||||||
|
|
||||||
self.fade_graph.tick(self.time_playing())
|
|
||||||
|
|
||||||
|
|
||||||
class MainTrackManager(_TrackManager):
|
class MainTrackManager(_TrackManager):
|
||||||
"""
|
"""
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user