diff options
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) |