diff options
Diffstat (limited to 'solo-tool-project')
5 files changed, 113 insertions, 11 deletions
| diff --git a/solo-tool-project/src/solo_tool/session_manager.py b/solo-tool-project/src/solo_tool/session_manager.py index 1575060..8624207 100644 --- a/solo-tool-project/src/solo_tool/session_manager.py +++ b/solo-tool-project/src/solo_tool/session_manager.py @@ -30,10 +30,10 @@ class SessionManager():          st = SoloTool(player=player)          for i, entry in enumerate(session):              songPath = entry["path"] -            keyPoints = entry["key_points"] +            keyPoints = entry.get("key_points", []) +            volume = entry.get("vol", 1.0) -            st.addSong(songPath) -            st._keyPoints[i] = keyPoints +            st.addSong(songPath, keyPoints=keyPoints, volume=volume)          return st @@ -43,7 +43,8 @@ class SessionManager():          for i, song in enumerate(soloTool.songs):              entry = {                  "path": song, -                "key_points" : soloTool._keyPoints[i] +                "key_points" : soloTool._keyPoints[i], +                "vol" : soloTool._volumes[i]              }              session.append(entry) diff --git a/solo-tool-project/src/solo_tool/solo_tool.py b/solo-tool-project/src/solo_tool/solo_tool.py index 63fb7f9..e8474e6 100644 --- a/solo-tool-project/src/solo_tool/solo_tool.py +++ b/solo-tool-project/src/solo_tool/solo_tool.py @@ -11,6 +11,7 @@ class SoloTool:          self._song = None          self._keyPoints = []          self._keyPoint = None +        self._volumes = []      def __del__(self):          del self._player @@ -30,6 +31,8 @@ class SoloTool:          if previousSong is None or self._keyPoints[previousSong] != self._keyPoints[index]:              self._notifier.notify(Notifier.KEY_POINT_LIST_EVENT, self.keyPoints) +        self.volume = self._volumes[index] +      @staticmethod      def _keyPointValid(kp: float) -> bool:          return kp is not None and kp >= 0.0 and kp < 1.0 @@ -38,11 +41,12 @@ class SoloTool:      def songs(self) -> list[str]:          return self._songs.copy() -    def addSong(self, path: str) -> None: +    def addSong(self, path: str, keyPoints: list[float]=[], volume: float=1.0) -> None:          if path in self._songs:              return          self._songs.append(path) -        self._keyPoints.append([]) +        self._keyPoints.append(keyPoints) +        self._volumes.append(volume)          self._notifier.notify(Notifier.SONG_LIST_EVENT, self.songs)          if self.song is None:              self.song = 0 @@ -112,6 +116,8 @@ class SoloTool:      @volume.setter      def volume(self, new: float) -> None:          if new is not None and new >= 0.0 and new != self._player.getPlaybackVolume(): +            if self._song is not None: +                self._volumes[self._song] = new              self._player.setPlaybackVolume(new)              self._notifier.notify(Notifier.PLAYBACK_VOLUME_EVENT, new) diff --git a/solo-tool-project/test/session_manager_unittest.py b/solo-tool-project/test/session_manager_unittest.py index bf0d8d9..5786b23 100644 --- a/solo-tool-project/test/session_manager_unittest.py +++ b/solo-tool-project/test/session_manager_unittest.py @@ -10,7 +10,8 @@ def testSessionFile(sessionPath, testSongs):      contents = """[      {          "path" : "test.flac", -        "key_points" : [] +        "key_points" : [], +        "vol" : 0.5      },      {          "path" : "test.mp3", @@ -35,24 +36,29 @@ def test_loadSession(sessionManager, mockPlayer, testSessionFile):      soloTool.song = 0      assert soloTool.keyPoints == [] +    assert soloTool.volume == 0.5      soloTool.song = 1      assert soloTool.keyPoints == [0.1, 0.3] +    assert soloTool.volume == 1.0  def test_saveSession(sessionManager, soloTool, testSessionFile, sessionPath):      soloTool.addSong("test.flac") +    soloTool.volume = 0.5 +      soloTool.addSong("test.mp3")      soloTool.song = 1      soloTool.keyPoints = [0.1, 0.3] -    sessionKey = "test_session_saved" -    sessionManager.saveSession(soloTool, sessionKey) +    sessionId = "test_session_saved" +    sessionManager.saveSession(soloTool, sessionId) -    with open(sessionPath / f"{sessionKey}.json", "r") as f: +    with open(sessionPath / f"{sessionId}.json", "r") as f:          savedSession = loads(f.read())      with open(testSessionFile, "r") as f:          testSession = loads(f.read()) +        testSession[1]["vol"] = 1.0 # Needed to handle default behaviour when vol is missing      assert savedSession == testSession diff --git a/solo-tool-project/test/solo_tool_integrationtest.py b/solo-tool-project/test/solo_tool_integrationtest.py index b92cd85..e5745bb 100644 --- a/solo-tool-project/test/solo_tool_integrationtest.py +++ b/solo-tool-project/test/solo_tool_integrationtest.py @@ -1,6 +1,6 @@  from fixtures import soloTool as uut, mockPlayer, testSongs -def test_playerControls(uut, mockPlayer): +def test_playerControls(uut, mockPlayer, testSongs):      assert not mockPlayer.playing      assert not uut.playing      uut.play() @@ -130,6 +130,41 @@ def test_playbackVolumeNotification(uut, mockPlayer, testSongs):      uut.volume = 0.3      assert not called +    # Volume can also change when the song changes +    uut.addSong(testSongs[1]) +    uut.song = 1 +    assert called +    assert receivedValue == 1.0 +    called = False + +    uut.volume = 0.3 +    assert called +    assert receivedValue == 0.3 +    called = False + +    uut.song = 0 +    assert not called + +def test_playbackVolumeNotificationBeforeFirstSong(uut, mockPlayer, testSongs): +    called = False +    receivedValue = None +    def callback(value): +        nonlocal called, receivedValue +        called = True +        receivedValue = value + +    uut.registerVolumeCallback(callback) +    assert not called + +    uut.volume = 0.3 +    assert called +    assert receivedValue == 0.3 +    called = False + +    uut.addSong(testSongs[0]) +    assert called +    assert receivedValue == 1.0 +  def test_playbackRateNotification(uut, mockPlayer, testSongs):      uut.addSong(testSongs[0]) diff --git a/solo-tool-project/test/solo_tool_volume_integrationtest.py b/solo-tool-project/test/solo_tool_volume_integrationtest.py new file mode 100644 index 0000000..cc1aeef --- /dev/null +++ b/solo-tool-project/test/solo_tool_volume_integrationtest.py @@ -0,0 +1,54 @@ +import pytest + +from fixtures import soloTool as uut, mockPlayer, testSongs + +def test_perSongVolumeFlow(uut, mockPlayer, testSongs): +    # Before a song is added, the volume starts at 100% +    assert uut.song is None +    assert mockPlayer.currentSong == None +    assert uut.volume == 1.0 +    assert mockPlayer.volume == 1.0 + +    # When songs are added, their volume starts at 100% +    uut.addSong(testSongs[0]) +    assert uut.song == 0 +    assert uut.volume == 1.0 +    assert mockPlayer.volume == 1.0 + +    # It's possible to change the volume +    uut.volume = 0.5 +    assert uut.volume == 0.5 +    assert mockPlayer.volume == 0.5 + +    # New song song is added, volume stays because the new song is not selected +    uut.addSong(testSongs[1]) +    assert uut.song == 0 +    assert uut.volume == 0.5 +    assert mockPlayer.volume == 0.5 + +    # Select new song, volume is 100% +    uut.song = 1 +    assert uut.volume == 1.0 +    assert mockPlayer.volume == 1.0 + +    uut.volume = 0.75 + +    # Previous song retains its volume +    uut.song = 0 +    assert uut.volume == 0.5 +    assert mockPlayer.volume == 0.5 + +    # New song also +    uut.song = 1 +    assert uut.volume == 0.75 +    assert mockPlayer.volume == 0.75 + +def test_perSongVolumeEdgeCases(uut, mockPlayer, testSongs): +    # If the player volume is not 100% when the first song is added, it is set to 100% +    uut.volume = 0.5 +    assert mockPlayer.volume == 0.5 + +    uut.addSong(testSongs[0]) +    assert uut.volume == 1.0 +    assert mockPlayer.volume == 1.0 + | 
