diff options
| author | Eddy Pedroni <epedroni@pm.me> | 2025-02-22 22:59:52 +0100 | 
|---|---|---|
| committer | Eddy Pedroni <epedroni@pm.me> | 2025-02-22 22:59:52 +0100 | 
| commit | bef8eee0f63cc5ccb963be9467381e4e605e7f53 (patch) | |
| tree | a7d07ef9689a608c572216b3e54569014752f0e6 /solo-tool-project/src/solo_tool | |
| parent | 2bcd98fd69b3b4c36b0f6c985a2ea214b1d0ad60 (diff) | |
Remove AB concept, introduce key points, refactor SoloTool to use properties
Diffstat (limited to 'solo-tool-project/src/solo_tool')
| -rw-r--r-- | solo-tool-project/src/solo_tool/abcontroller.py | 82 | ||||
| -rw-r--r-- | solo-tool-project/src/solo_tool/notifier.py | 3 | ||||
| -rw-r--r-- | solo-tool-project/src/solo_tool/solo_tool.py | 167 | 
3 files changed, 77 insertions, 175 deletions
| diff --git a/solo-tool-project/src/solo_tool/abcontroller.py b/solo-tool-project/src/solo_tool/abcontroller.py deleted file mode 100644 index cec9fb2..0000000 --- a/solo-tool-project/src/solo_tool/abcontroller.py +++ /dev/null @@ -1,82 +0,0 @@ -from collections import namedtuple - -_AB = namedtuple("_AB", ["a", "b"]) - -class ABController: -    def __init__(self, enabled=True, callback=None): -        self._setPositionCallback = callback -        self._limits = {} # dictionary of all songs -        self._songLimits = None # list of limits for selected song -        self._currentLimits = _AB(0.0, 0.0) # a/b positions of active limit -        self._loadedIndex = None -        self._enabled = enabled - -    def _ensureSongExists(self, path): -        if path not in self._limits: -            self._limits[path] = [] - -    def setCurrentSong(self, path): -        self._ensureSongExists(path) -        self._songLimits = self._limits[path] -        self._loadedIndex = None - -    def storeLimits(self, aLimit, bLimit, song=None): -        if song is not None: -            self._ensureSongExists(song) -            songLimits = self._limits[song] -        else: -            songLimits = self._songLimits - -        if songLimits is None: -            return - -        ab = _AB(aLimit, bLimit) -        songLimits.append(ab) - -    def loadLimits(self, index): -        if not self._songLimits: -            return - -        if index >= 0 and index < len(self._songLimits): -            self._currentLimits = self._songLimits[index] -            self._loadedIndex = index - -    def nextStoredAbLimits(self): -        if self._loadedIndex is None: -            nextIndex = 0 -        else: -            nextIndex = self._loadedIndex + 1 -        self.loadLimits(nextIndex) - -    def previousStoredAbLimits(self): -        if self._loadedIndex is None: -            previousIndex = 0 -        else: -            previousIndex = self._loadedIndex - 1 -        self.loadLimits(previousIndex) - -    def setLimits(self, aLimit, bLimit): -        self._currentLimits = _AB(aLimit, bLimit) -        self._loadedIndex = None - -    def positionChanged(self, position): -        if position > self._currentLimits.b and self._setPositionCallback and self._enabled: -            self._setPositionCallback(self._currentLimits.a) - -    def setEnable(self, enable): -        self._enabled = enable - -    def isEnabled(self): -        return self._enabled - -    def getStoredLimits(self, song): -        return self._limits.get(song) - -    def getCurrentLimits(self): -        return self._currentLimits - -    def getLoadedIndex(self): -        return self._loadedIndex - -    def clear(self): -        self.__init__(enabled=self._enabled, callback=self._setPositionCallback) diff --git a/solo-tool-project/src/solo_tool/notifier.py b/solo-tool-project/src/solo_tool/notifier.py index 9f445b6..73b84b7 100644 --- a/solo-tool-project/src/solo_tool/notifier.py +++ b/solo-tool-project/src/solo_tool/notifier.py @@ -3,8 +3,7 @@ class Notifier:      PLAYBACK_VOLUME_EVENT = 1      PLAYBACK_RATE_EVENT = 2      CURRENT_SONG_EVENT = 3 -    CURRENT_AB_EVENT = 4 -    AB_LIMIT_ENABLED_EVENT = 5 +    CURRENT_KEY_POINT_EVENT = 3      def __init__(self, player):          self._callbacks = dict() diff --git a/solo-tool-project/src/solo_tool/solo_tool.py b/solo-tool-project/src/solo_tool/solo_tool.py index a4c7af8..884721b 100644 --- a/solo-tool-project/src/solo_tool/solo_tool.py +++ b/solo-tool-project/src/solo_tool/solo_tool.py @@ -1,6 +1,5 @@  import os -from .abcontroller import ABController  from .session_manager import loadSession, saveSession  from .notifier import Notifier  from .player_vlc import Player @@ -8,32 +7,32 @@ from .player_vlc import Player  class SoloTool:      def __init__(self, playerOverride=None):          self._player = Player() if playerOverride is None else playerOverride -        self._abController = ABController(enabled=False, callback=self._abControllerCallback)          self._notifier = Notifier(self._player) -        self._songList = [] +        self._songs = []          self._song = None +        self._keyPoints = [] +        self._keyPoint = None      def _updateSong(self, index):          self._song = index -        path = self._songList[index] +        path = self._songs[index]          self._player.setCurrentSong(path) -        self._abController.setCurrentSong(path)          self._notifier.notify(Notifier.CURRENT_SONG_EVENT, index) +        self._keyPoint = 0.0 -    def _abControllerCallback(self, position): -        self._player.setPlaybackPosition(position) - -    def tick(self): -        position = self._player.getPlaybackPosition() -        self._abController.positionChanged(position) +    @staticmethod +    def _keyPointValid(kp: float) -> bool: +        return kp is not None and kp >= 0.0 and kp < 1.0      @property -    def songList(self) -> list[str]: -        return self._songList +    def songs(self) -> list[str]: +        return self._songs.copy()      def addSong(self, path: str) -> None: -        if os.path.isfile(path): -            self._songList.append(path) +        if not os.path.isfile(path): +            raise FileNotFoundError() +        self._songs.append(path) +        self._keyPoints.append([])      @property      def song(self) -> int: @@ -41,64 +40,36 @@ class SoloTool:      @song.setter      def song(self, new: int) -> None: -        if new >= 0 and new < len(self._songList) and new != self._song: +        if new is None or new < 0 or new >= len(self._songs): +            raise ValueError() +        if new != self._song:              self._updateSong(new) -    def storeAbLimits(self, aLimit, bLimit): -        self._abController.storeLimits(aLimit, bLimit) +    @property +    def keyPoints(self) -> list[float]: +        if self._song is None: +            return None +        return self._keyPoints[self._song] + +    @keyPoints.setter +    def keyPoints(self, new: list[float]) -> None: +        if new is None: +            raise ValueError() +        if self._song is not None: +            sanitized = sorted(list(set([p for p in new if SoloTool._keyPointValid(p)]))) +            self._keyPoints[self._song] = sanitized -    def loadAbLimits(self, index): -        previous = self._abController.getLoadedIndex() -        self._abController.loadLimits(index) -        new = self._abController.getLoadedIndex() -        if previous != new: -            self._notifier.notify(Notifier.CURRENT_AB_EVENT, new) -     -    def setAbLimits(self, aLimit, bLimit): -        self._abController.setLimits(aLimit, bLimit) +    @property +    def keyPoint(self) -> float: +        return self._keyPoint -    def getStoredAbLimits(self): -        if self._song is not None: -            return self._abController.getStoredLimits(self.songList[self._song]) -        else: -            return list() - -    def setAbLimitEnable(self, enable): -        previous = self._abController.isEnabled() -        self._abController.setEnable(enable) -        new = self._abController.isEnabled() -        if previous != new: -            self._notifier.notify(Notifier.AB_LIMIT_ENABLED_EVENT, new) - -    def isAbLimitEnabled(self): -        return self._abController.isEnabled() - -    def nextStoredAbLimits(self): -        previous = self._abController.getLoadedIndex() -        self._abController.nextStoredAbLimits() -        new = self._abController.getLoadedIndex() -        if previous != new: -            self._notifier.notify(Notifier.CURRENT_AB_EVENT, new) - -    def previousStoredAbLimits(self): -        previous = self._abController.getLoadedIndex() -        self._abController.previousStoredAbLimits() -        new = self._abController.getLoadedIndex() -        if previous != new: -            self._notifier.notify(Notifier.CURRENT_AB_EVENT, new) - -    def jumpToA(self): -        a = self._abController.getCurrentLimits()[0] -        # XXX assumes that player.setPlaybackPosition is thread-safe! -        self._player.setPlaybackPosition(a) - -    def loadSession(self, path): -        with open(path, "r") as f: -            loadSession(f, self._songList, self._abController) - -    def saveSession(self, path): -        with open(path, "w") as f: -            saveSession(f, self._songList, self._abController) +    @keyPoint.setter +    def keyPoint(self, new: float) -> None: +        if not SoloTool._keyPointValid(new): +            raise ValueError() +        if self._song is not None and new != self._keyPoint: +            self._keyPoint = new +            self._notifier.notify(Notifier.CURRENT_KEY_POINT_EVENT, new)      def play(self):          self._player.play() @@ -112,43 +83,57 @@ class SoloTool:      def isPlaying(self):          return self._player.isPlaying() -    def setPlaybackRate(self, rate): -        previous = self._player.getPlaybackRate() -        self._player.setPlaybackRate(rate) -        new = self._player.getPlaybackRate() -        if previous != new: -            self._notifier.notify(Notifier.PLAYBACK_RATE_EVENT, new) +    def jump(self): +        self._player.setPlaybackPosition(self._keyPoint) -    def getPlaybackRate(self): +    @property +    def rate(self) -> float:          return self._player.getPlaybackRate() -    def setPlaybackPosition(self, position): -        self._player.setPlaybackPosition(position) +    @rate.setter +    def rate(self, new: float) -> None: +        if new is None or new <= 0.0: +            raise ValueError() +        if new != self._player.getPlaybackRate(): +            self._player.setPlaybackRate(new) +            self._notifier.notify(Notifier.PLAYBACK_RATE_EVENT, new) + +    @property +    def volume(self) -> float: +        return self._player.getPlaybackVolume() -    def getPlaybackPosition(self): -        return self._player.getPlaybackPosition() +    @volume.setter +    def volume(self, new: float) -> None: +        if new is None or new < 0.0: +            raise ValueError() +        if new != self._player.getPlaybackVolume(): +            self._player.setPlaybackVolume(new) +            self._notifier.notify(Notifier.PLAYBACK_VOLUME_EVENT, new) -    def setPlaybackVolume(self, volume): -        self._player.setPlaybackVolume(volume) +    @property +    def position(self) -> float: +        return self._player.getPlaybackPosition() -    def getPlaybackVolume(self): -        return self._player.getPlaybackVolume() +    @position.setter +    def position(self, new: float) -> None: +        if new is None or new < 0.0 or new >= 1.0: +            raise ValueError() +        # TODO stop playback before changing position? +        if new != self._player.getPlaybackPosition(): +            self._player.setPlaybackPosition(new)      def registerPlayingStateCallback(self, callback):          self._notifier.registerCallback(Notifier.PLAYING_STATE_EVENT, callback) -    def registerPlaybackVolumeCallback(self, callback): +    def registerVolumeCallback(self, callback):          self._notifier.registerCallback(Notifier.PLAYBACK_VOLUME_EVENT, callback) -    def registerPlaybackRateCallback(self, callback): +    def registerRateCallback(self, callback):          self._notifier.registerCallback(Notifier.PLAYBACK_RATE_EVENT, callback)      def registerCurrentSongCallback(self, callback):          self._notifier.registerCallback(Notifier.CURRENT_SONG_EVENT, callback) -    def registerCurrentAbLimitsCallback(self, callback): -        self._notifier.registerCallback(Notifier.CURRENT_AB_EVENT, callback) - -    def registerAbLimitEnabledCallback(self, callback): -        self._notifier.registerCallback(Notifier.AB_LIMIT_ENABLED_EVENT, callback) +    def registerCurrentKeyPointCallback(self, callback): +        self._notifier.registerCallback(Notifier.CURRENT_KEY_POINT_EVENT, callback) | 
