aboutsummaryrefslogtreecommitdiffstats
path: root/solo-tool-project
diff options
context:
space:
mode:
Diffstat (limited to 'solo-tool-project')
-rw-r--r--solo-tool-project/src/solo_tool/session_manager.py9
-rw-r--r--solo-tool-project/src/solo_tool/solo_tool.py10
-rw-r--r--solo-tool-project/test/session_manager_unittest.py14
-rw-r--r--solo-tool-project/test/solo_tool_integrationtest.py37
-rw-r--r--solo-tool-project/test/solo_tool_volume_integrationtest.py54
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
+