Initialise FadeCurve in a thread

Stops a UI delay of half a second or so when marking a track 'next'
This commit is contained in:
Keith Edmunds 2023-11-03 09:08:06 +00:00
parent 4d3dc1fd00
commit bd2fa1cab0

View File

@ -2,32 +2,34 @@ from dataclasses import dataclass
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import Optional from typing import Optional
from PyQt6.QtCore import pyqtSignal, QObject from PyQt6.QtCore import pyqtSignal, QObject, QThread
import numpy as np import numpy as np
import pyqtgraph as pg # type: ignore import pyqtgraph as pg # type: ignore
from config import Config from config import Config
from dbconfig import scoped_session from dbconfig import scoped_session, Session
from models import PlaylistRows from models import PlaylistRows, Tracks
import helpers import helpers
class FadeCurve: class FadeCurve:
GraphWidget = None GraphWidget = None
def __init__(self, track): def __init__(
self, track_path: str, track_fade_at: int, track_silence_at: int
) -> None:
""" """
Set up fade graph array Set up fade graph array
""" """
audio = helpers.get_audio_segment(track.path) audio = helpers.get_audio_segment(track_path)
if not audio: if not audio:
return None return None
# 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 = max(0, track.fade_at - Config.FADE_CURVE_MS_BEFORE_FADE - 1) self.start_ms = max(0, track_fade_at - Config.FADE_CURVE_MS_BEFORE_FADE - 1)
self.end_ms = track.silence_at self.end_ms = 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())
@ -106,7 +108,7 @@ class PlaylistTrack:
self.duration: Optional[int] = None self.duration: Optional[int] = None
self.end_time: Optional[datetime] = None self.end_time: Optional[datetime] = None
self.fade_at: Optional[int] = None self.fade_at: Optional[int] = None
self.fade_curve: Optional[FadeCurve] = None self.fade_graph: Optional[FadeCurve] = None
self.fade_length: Optional[int] = None self.fade_length: Optional[int] = None
self.path: Optional[str] = None self.path: Optional[str] = None
self.playlist_id: Optional[int] = None self.playlist_id: Optional[int] = None
@ -139,7 +141,6 @@ class PlaylistTrack:
self.duration = track.duration self.duration = track.duration
self.end_time = None self.end_time = None
self.fade_at = track.fade_at self.fade_at = track.fade_at
self.fade_graph = FadeCurve(track) # TODO: speed this line up
self.path = track.path self.path = track.path
self.playlist_id = plr.playlist_id self.playlist_id = plr.playlist_id
self.plr_id = plr.id self.plr_id = plr.id
@ -153,6 +154,22 @@ class PlaylistTrack:
if track.silence_at and track.fade_at: if track.silence_at and track.fade_at:
self.fade_length = track.silence_at - track.fade_at self.fade_length = track.silence_at - track.fade_at
# Initialise and add FadeCurve in a thread as it's slow
# Import in separate thread
self.fadecurve_thread = QThread()
self.worker = AddFadeCurve(
self,
track_path=track.path,
track_fade_at=track.fade_at,
track_silence_at=track.silence_at,
)
self.worker.moveToThread(self.fadecurve_thread)
self.fadecurve_thread.started.connect(self.worker.run)
self.worker.finished.connect(self.fadecurve_thread.quit)
self.worker.finished.connect(self.worker.deleteLater)
self.fadecurve_thread.finished.connect(self.fadecurve_thread.deleteLater)
self.fadecurve_thread.start()
def start(self) -> None: def start(self) -> None:
""" """
Called when track starts playing Called when track starts playing
@ -163,6 +180,38 @@ class PlaylistTrack:
self.end_time = self.start_time + timedelta(milliseconds=self.duration) self.end_time = self.start_time + timedelta(milliseconds=self.duration)
class AddFadeCurve(QObject):
"""
Initialising a fade curve introduces a noticeable delay so carry out in
a thread.
"""
finished = pyqtSignal()
def __init__(
self,
playlist_track: PlaylistTrack,
track_path: str,
track_fade_at: int,
track_silence_at: int,
):
super().__init__()
self.playlist_track = playlist_track
self.track_path = track_path
self.track_fade_at = track_fade_at
self.track_silence_at = track_silence_at
def run(self):
"""
Create fade curve and add to PlaylistTrack object
"""
self.playlist_track.fade_graph = FadeCurve(
self.track_path, self.track_fade_at, self.track_silence_at
)
self.finished.emit()
@helpers.singleton @helpers.singleton
class CurrentTrack(PlaylistTrack): class CurrentTrack(PlaylistTrack):
pass pass