aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--known-issues.md1
-rw-r--r--midi_controller_launchpad_mini.py11
-rw-r--r--midi_launchpad_mini_unittest.py41
-rw-r--r--playlist.py14
-rw-r--r--playlist_unittest.py35
-rw-r--r--solo_tool.py10
-rw-r--r--solo_tool_integrationtest.py24
7 files changed, 127 insertions, 9 deletions
diff --git a/known-issues.md b/known-issues.md
index 81f2181..0307e4c 100644
--- a/known-issues.md
+++ b/known-issues.md
@@ -8,6 +8,7 @@
* automatically play next song when current song ends
* playback doesn't stop when jumping to next/previous song
* should this be the default anyway?
+* Add buttons to write current playback position to A or B limit sliders
# Closed Issues
diff --git a/midi_controller_launchpad_mini.py b/midi_controller_launchpad_mini.py
index 16c819c..55c0ec0 100644
--- a/midi_controller_launchpad_mini.py
+++ b/midi_controller_launchpad_mini.py
@@ -12,8 +12,10 @@ class MidiController:
self._handlers = {
112 : self._playPause,
- 96 : self._stop,
- 101 : self._jumpToA
+ 96 : self._soloTool.stop,
+ 101 : self._soloTool.jumpToA,
+ 118 : self._soloTool.previousSong,
+ 119 : self._soloTool.nextSong
}
def connect(self):
@@ -33,8 +35,3 @@ class MidiController:
else:
self._soloTool.play()
- def _stop(self):
- self._soloTool.stop()
-
- def _jumpToA(self):
- self._soloTool.jumpToA()
diff --git a/midi_launchpad_mini_unittest.py b/midi_launchpad_mini_unittest.py
index 09f12df..55ca6c8 100644
--- a/midi_launchpad_mini_unittest.py
+++ b/midi_launchpad_mini_unittest.py
@@ -30,6 +30,8 @@ class SoloToolMock:
self.state = SoloToolMock.STOPPED
self.position = 0.0
self.currentAbLimit = (0.0, 0.0)
+ self.currentLoadedAbLimitIndex = None
+ self.currentSong = None
def play(self):
self.state = SoloToolMock.PLAYING
@@ -46,6 +48,24 @@ class SoloToolMock:
def jumpToA(self):
self.position = self.currentAbLimit[0]
+ def loadAbLimits(self, index):
+ self.currentLoadedAbLimitIndex = index
+
+ def setSong(self, index):
+ self.currentSong = index
+
+ def nextSong(self):
+ if self.currentSong is None:
+ self.currentSong = 0
+ else:
+ self.currentSong += 1
+
+ def previousSong(self):
+ if self.currentSong is None:
+ self.currentSong = 0
+ else:
+ self.currentSong = max(self.currentSong - 1, 0)
+
def test_connect():
expectedDevice = "Launchpad Mini MIDI 1"
@@ -97,6 +117,26 @@ def test_jumpToAButton():
midiWrapperMock.simulateInput(101)
assert soloToolMock.position == ab[0]
+def test_previousAndNextSongButtons():
+ soloToolMock = SoloToolMock()
+ midiWrapperMock = MidiWrapperMock()
+ uut = MidiController(soloToolMock, midiWrapperMock)
+ uut.connect()
+
+ assert soloToolMock.currentSong == None
+ midiWrapperMock.simulateInput(119)
+ assert soloToolMock.currentSong == 0
+
+ midiWrapperMock.simulateInput(119)
+ assert soloToolMock.currentSong == 1
+
+ midiWrapperMock.simulateInput(118)
+ assert soloToolMock.currentSong == 0
+
+ midiWrapperMock.simulateInput(118)
+ assert soloToolMock.currentSong == 0
+
+"""
def test_unprogrammedButton():
unusedButton = 48
midiWrapperMock = MidiWrapperMock()
@@ -105,3 +145,4 @@ def test_unprogrammedButton():
# expect no crash
midiWrapperMock.simulateInput(48)
+"""
diff --git a/playlist.py b/playlist.py
index d25395b..2880733 100644
--- a/playlist.py
+++ b/playlist.py
@@ -22,3 +22,17 @@ class Playlist:
def clear(self):
self.__init__(self._setSongCallback)
+
+ def nextSong(self):
+ if self._currentSong is None:
+ nextSong = 0
+ else:
+ nextSong = self._currentSong + 1
+ self.setCurrentSong(nextSong)
+
+ def previousSong(self):
+ if self._currentSong is None:
+ prevSong = 0
+ else:
+ prevSong = self._currentSong - 1
+ self.setCurrentSong(prevSong)
diff --git a/playlist_unittest.py b/playlist_unittest.py
index 9dd3700..24d3a59 100644
--- a/playlist_unittest.py
+++ b/playlist_unittest.py
@@ -93,3 +93,38 @@ def test_clearPlaylist():
assert uut.getSongs() == []
assert uut.getCurrentSong() == None
+def test_nextSong():
+ songAddedByUser = ["/path/to/song", "/path/to/second/song"]
+
+ uut = Playlist(lambda index: None)
+ for s in songAddedByUser:
+ uut.addSong(s)
+ assert uut.getCurrentSong() == None
+
+ uut.nextSong()
+ assert uut.getCurrentSong() == songAddedByUser[0]
+
+ uut.nextSong()
+ assert uut.getCurrentSong() == songAddedByUser[1]
+
+ uut.nextSong()
+ assert uut.getCurrentSong() == songAddedByUser[1]
+
+def test_previousSong():
+ songAddedByUser = ["/path/to/song", "/path/to/second/song"]
+
+ uut = Playlist(lambda index: None)
+ for s in songAddedByUser:
+ uut.addSong(s)
+ assert uut.getCurrentSong() == None
+
+ uut.previousSong()
+ assert uut.getCurrentSong() == songAddedByUser[0]
+
+ uut.previousSong()
+ assert uut.getCurrentSong() == songAddedByUser[0]
+
+ uut.setCurrentSong(1)
+ assert uut.getCurrentSong() == songAddedByUser[1]
+ uut.previousSong()
+ assert uut.getCurrentSong() == songAddedByUser[0]
diff --git a/solo_tool.py b/solo_tool.py
index c32d3e8..d2147bf 100644
--- a/solo_tool.py
+++ b/solo_tool.py
@@ -6,8 +6,8 @@ from session_manager import SessionManager
from player_vlc import Player
class SoloTool:
- def __init__(self, player=None):
- self._player = Player() if player is None else player
+ def __init__(self, playerOverride=None):
+ self._player = Player() if playerOverride is None else playerOverride
self._playlist = Playlist(self._playlistCallback)
self._abController = ABController(enabled=False, callback=self._abControllerCallback)
self._sessionManager = SessionManager(self._playlist, self._abController)
@@ -30,6 +30,12 @@ class SoloTool:
def setSong(self, index):
self._playlist.setCurrentSong(index)
+ def nextSong(self):
+ self._playlist.nextSong()
+
+ def previousSong(self):
+ self._playlist.previousSong()
+
def getSongs(self):
return self._playlist.getSongs()
diff --git a/solo_tool_integrationtest.py b/solo_tool_integrationtest.py
index af0a921..2fa923a 100644
--- a/solo_tool_integrationtest.py
+++ b/solo_tool_integrationtest.py
@@ -47,6 +47,30 @@ def test_addAndSetSongs():
uut.setSong(i)
assert mockPlayer.currentSong == songs[i]
+def test_nextAndPreviousSong():
+ songs = [
+ "test.flac",
+ "test.mp3"
+ ]
+ mockPlayer = MockPlayer()
+ uut = SoloTool(mockPlayer)
+
+ for s in songs:
+ uut.addSong(s)
+ assert mockPlayer.currentSong == None
+
+ uut.nextSong()
+ assert mockPlayer.currentSong == songs[0]
+
+ uut.previousSong()
+ assert mockPlayer.currentSong == songs[0]
+
+ uut.nextSong()
+ assert mockPlayer.currentSong == songs[1]
+
+ uut.nextSong()
+ assert mockPlayer.currentSong == songs[1]
+
def test_addAndSetAbLimits():
song = "test.flac"
abLimits = [