ayé, on joue du musicxml :-)
[minwii.git] / src / gui / SongPlayingScreen.py
index a06e831..5ddd67a 100644 (file)
@@ -10,6 +10,8 @@ import colorsys
 import constants\r
 from gradients import gradients\r
 from logging.PickleableEvent import PickleableEvent\r
+from songs.Song import Song\r
+from songs.musicxmltosong import Part\r
 \r
 \r
 class SongPlayingScreen:\r
@@ -44,160 +46,323 @@ class SongPlayingScreen:
     \r
     \r
     \r
-    def __init__(self, instrumentChoice, song, cascade=False, extendedScale=False, easyMode = False, alwaysDown = False, eventLog = None, replay = None, defaultInstrumentChannel = 16, defaultNote = 60):\r
+    def __init__(self, instrumentChoice, pguconf):# song, cascade=False, extendedScale=False, easyMode = False, alwaysDown = False, eventLog = None, replay = None, defaultInstrumentChannel = 16, defaultNote = 60):\r
         '''\r
         Constructor\r
-        '''        \r
-        self.songDurations = []\r
-        self.totalDuration = None\r
-        self.clicks = [0]\r
-        self.clicksIn = [0]\r
-        self.clicksPerMinute = [0]\r
-        self.clicksInPerMinute = [0]\r
-        self.meanTimeBetweenNotes = []\r
-        self.firstClick = None\r
-        self.firstClickIn = None\r
-        \r
-        self.blinkLength = 200\r
-        self.minimalVelocity = 90\r
-        self.shortScaleSize = 8\r
-        self.longScaleSize = 11\r
-        if not extendedScale:\r
-            self.offset = self.longScaleSize - self.shortScaleSize\r
-        else:\r
-            self.offset = 0\r
-        self.borderSize = 5\r
-        self.highlightedNote = 0\r
-        self.highlightedNoteNumber = 0\r
-        self.syllabus = None\r
-        self.savedHighlightedNote = 0\r
-        self.alwaysDown = alwaysDown\r
-        self.nextLevel = None\r
-        \r
-        self.wiimotes = instrumentChoice.wiimotes\r
-        self.activeWiimotes = instrumentChoice.activeWiimotes\r
-        self.window = instrumentChoice.window\r
-        self.screen = instrumentChoice.screen\r
-        self.blitOrigin = instrumentChoice.blitOrigin\r
-        self.clock = instrumentChoice.clock\r
-        self.width = instrumentChoice.width\r
-        self.height = instrumentChoice.height\r
-        self.cursorPositions = instrumentChoice.cursorPositions\r
-        self.savedScreen = instrumentChoice.savedScreen\r
-        self.playerScreen = instrumentChoice.playerScreen\r
-        self.extendedScale = extendedScale\r
-        self.cascade = cascade\r
-        self.joys = instrumentChoice.joys\r
-        self.portOffset = instrumentChoice.portOffset\r
-        if eventLog == None :\r
-            self.eventLog = instrumentChoice.eventLog\r
-        else :\r
-            self.eventLog = eventLog\r
-        self.cursorPositions = instrumentChoice.cursorPositions\r
-        self.song = song\r
-        self.songIterator = self.song.getSongIterator()\r
-        self.midiNoteNumbers = self.song.scale\r
-        if replay == None :\r
-            self.replay = instrumentChoice.replay\r
-        else :\r
-            self.replay = replay\r
-        self.quarterNoteLength = song.quarterNoteLength\r
-        self.cascadeLockLengthMultiplier = 1\r
-        self.nextCascadeLockLengthMultiplier = 1\r
-        self.cascadeLockLength = self.quarterNoteLength * self.cascadeLockLengthMultiplier\r
-        \r
-        self.defaultInstrumentChannel = defaultInstrumentChannel\r
-        self.defaultNote = defaultNote\r
-        \r
-        self.done = False\r
-        self.backToInstrumentChoice = False\r
-        self.easyMode = easyMode\r
-        \r
-        #Initializes the highlightedNote and highlightedNoteNumber etc...\r
-        self.moveToNextNote()\r
-        self.cascadeLockLengthMultiplier = self.nextCascadeLockLengthMultiplier\r
-        \r
-        self.blinkOn = False\r
-        self.savedBlinkOn = False\r
-        ##Will prevent the song to move on if two consecutive notes are identical and the buttons have not been released in between the two\r
-        ##i.e. it guarantees that there will be an attack between two identical consecutive notes\r
-        self.highlightIsFree = True\r
-        \r
-        self.noteRects = []\r
-        self.boundingRect = None\r
-        self.notes = []\r
-        \r
-        self.buttonDown = []\r
-        self.velocityLock = []\r
-        \r
-        self._blinkOffset = 0\r
-        self._cascadeLockTimer = 0\r
-        self.cascadeIsFree = True\r
-        \r
-        self.font = pygame.font.Font(None,80)\r
-        self.renderedNoteNames = [self.font.render(constants.noteNumberToName(note),False,(0,0,0)) for note in self.midiNoteNumbers]\r
-        \r
-        self.drawBackground()\r
-        self.initializeWiimotes()\r
-        \r
-        self.songStartTime = self.eventLog.getCurrentTime()\r
-        \r
-        #The main loop\r
-        while not self.done :\r
+        '''\r
+        song = pguconf.song\r
+        cascade = pguconf.cascade\r
+        extendedScale = song.requiresExtendedScale\r
+        easyMode = pguconf.easyMode\r
+        alwaysDown = pguconf.alwaysDown\r
+        eventLog = instrumentChoice.eventLog\r
+        replay = instrumentChoice.replay\r
+        defaultInstrumentChannel = 16\r
+        defaultNote = 60\r
+\r
+        if isinstance(song, Song) :\r
+            self.songDurations = []\r
+            self.totalDuration = None\r
+            self.clicks = [0]\r
+            self.clicksIn = [0]\r
+            self.clicksPerMinute = [0]\r
+            self.clicksInPerMinute = [0]\r
+            self.meanTimeBetweenNotes = []\r
+            self.firstClick = None\r
+            self.firstClickIn = None\r
             \r
-            #Clear the cursors from the screen\r
-            if self.hasChanged():\r
-                self.drawBackground()\r
-            self.playerScreen.blit(self.savedScreen, (0, 0))\r
+            self.blinkLength = 200\r
+            self.minimalVelocity = 90\r
+            self.shortScaleSize = 8\r
+            self.longScaleSize = 11\r
+            if not extendedScale:\r
+                self.offset = self.longScaleSize - self.shortScaleSize\r
+            else:\r
+                self.offset = 0\r
+            self.borderSize = 5\r
+            self.highlightedNote = 0\r
+            self.highlightedNoteNumber = 0\r
+            self.syllabus = None\r
+            self.savedHighlightedNote = 0\r
+            self.alwaysDown = alwaysDown\r
+            self.nextLevel = None\r
             \r
-            # Limit frame speed to 50 FPS\r
-            #\r
-            timePassed = self.clock.tick(10000)\r
+            self.wiimotes = instrumentChoice.wiimotes\r
+            self.activeWiimotes = instrumentChoice.activeWiimotes\r
+            self.window = instrumentChoice.window\r
+            self.screen = instrumentChoice.screen\r
+            self.blitOrigin = instrumentChoice.blitOrigin\r
+            self.clock = instrumentChoice.clock\r
+            self.width = instrumentChoice.width\r
+            self.height = instrumentChoice.height\r
+            self.cursorPositions = instrumentChoice.cursorPositions\r
+            self.savedScreen = instrumentChoice.savedScreen\r
+            self.playerScreen = instrumentChoice.playerScreen\r
+            self.extendedScale = extendedScale\r
+            self.cascade = cascade\r
+            self.joys = instrumentChoice.joys\r
+            self.portOffset = instrumentChoice.portOffset\r
+            if eventLog == None :\r
+                self.eventLog = instrumentChoice.eventLog\r
+            else :\r
+                self.eventLog = eventLog\r
+            self.cursorPositions = instrumentChoice.cursorPositions\r
+            self.song = song\r
+            self.songIterator = self.song.getSongIterator()\r
+            self.midiNoteNumbers = self.song.scale\r
+            if replay == None :\r
+                self.replay = instrumentChoice.replay\r
+            else :\r
+                self.replay = replay\r
+            self.quarterNoteLength = song.quarterNoteLength\r
+            self.cascadeLockLengthMultiplier = 1\r
+            self.nextCascadeLockLengthMultiplier = 1\r
+            self.cascadeLockLength = self.quarterNoteLength * self.cascadeLockLengthMultiplier\r
+            \r
+            self.defaultInstrumentChannel = defaultInstrumentChannel\r
+            self.defaultNote = defaultNote\r
+            \r
+            self.done = False\r
+            self.backToInstrumentChoice = False\r
+            self.easyMode = easyMode\r
+            \r
+            #Initializes the highlightedNote and highlightedNoteNumber etc...\r
+            self.moveToNextNote()\r
+            self.cascadeLockLengthMultiplier = self.nextCascadeLockLengthMultiplier\r
+            \r
+            self.blinkOn = False\r
+            self.savedBlinkOn = False\r
+            ##Will prevent the song to move on if two consecutive notes are identical and the buttons have not been released in between the two\r
+            ##i.e. it guarantees that there will be an attack between two identical consecutive notes\r
+            self.highlightIsFree = True\r
+            \r
+            self.noteRects = []\r
+            self.boundingRect = None\r
+            self.notes = []\r
+            \r
+            self.buttonDown = []\r
+            self.velocityLock = []\r
+            \r
+            self._blinkOffset = 0\r
+            self._cascadeLockTimer = 0\r
+            self.cascadeIsFree = True\r
+            \r
+            self.font = pygame.font.Font(None,80)\r
+            self.renderedNoteNames = [self.font.render(constants.noteNumberToName(note),False,(0,0,0)) for note in self.midiNoteNumbers]\r
             \r
-            self._blinkOffset += timePassed\r
-            if (self.buttonDown or self.alwaysDown) and not self.cascadeIsFree :\r
-                self._cascadeLockTimer += timePassed\r
-                if self._cascadeLockTimer > self.cascadeLockLengthMultiplier*self.quarterNoteLength :\r
-                    self.cascadeIsFree = True\r
-                    self.cascadeLockLengthMultiplier = self.nextCascadeLockLengthMultiplier\r
+            self.drawBackground()\r
+            self.initializeWiimotes()\r
             \r
+            self.songStartTime = self.eventLog.getCurrentTime()\r
             \r
-            if self._blinkOffset > self.blinkLength:\r
-                self._blinkOffset -= self.blinkLength\r
-                self.blinkOn = not self.blinkOn\r
+            #The main loop\r
+            while not self.done :\r
+                \r
+                #Clear the cursors from the screen\r
+                if self.hasChanged():\r
+                    self.drawBackground()\r
+                self.playerScreen.blit(self.savedScreen, (0, 0))\r
+                \r
+                # Limit frame speed to 50 FPS\r
+                #\r
+                timePassed = self.clock.tick(10000)\r
+                \r
+                self._blinkOffset += timePassed\r
+                if (self.buttonDown or self.alwaysDown) and not self.cascadeIsFree :\r
+                    self._cascadeLockTimer += timePassed\r
+                    if self._cascadeLockTimer > self.cascadeLockLengthMultiplier*self.quarterNoteLength :\r
+                        self.cascadeIsFree = True\r
+                        self.cascadeLockLengthMultiplier = self.nextCascadeLockLengthMultiplier\r
+                \r
+                \r
+                if self._blinkOffset > self.blinkLength:\r
+                    self._blinkOffset -= self.blinkLength\r
+                    self.blinkOn = not self.blinkOn\r
+                    \r
+                if self.replay:\r
+                    self.eventLog.update(timePassed)\r
+                    pickledEventsToPost = self.eventLog.getPickledEvents() \r
+                    for pickledEvent in pickledEventsToPost:\r
+                        pygame.event.post(pickledEvent.event)\r
+                \r
+                events = pygame.event.get()\r
                 \r
-            if self.replay:\r
-                self.eventLog.update(timePassed)\r
-                pickledEventsToPost = self.eventLog.getPickledEvents() \r
-                for pickledEvent in pickledEventsToPost:\r
-                    pygame.event.post(pickledEvent.event)\r
-            \r
-            events = pygame.event.get()\r
-            \r
-            if not self.replay:\r
-                pickledEvents = [PickleableEvent(event.type,event.dict) for event in events]\r
-                if pickledEvents != [] :\r
-                    self.eventLog.appendEventGroup(pickledEvents)\r
-            \r
-            for event in events:\r
-                self.input(event)\r
-                            \r
+                if not self.replay:\r
+                    pickledEvents = [PickleableEvent(event.type,event.dict) for event in events]\r
+                    if pickledEvents != [] :\r
+                        self.eventLog.appendEventGroup(pickledEvents)\r
+                \r
+                for event in events:\r
+                    self.input(event)\r
+                                \r
+                for i in range(len(self.wiimotes)):\r
+                    if self.activeWiimotes[i]:\r
+                        self.wiimotes[i].cursor.update(timePassed, self.cursorPositions[i])\r
+                        if self.buttonDown[i] or self.alwaysDown:\r
+                            self.wiimotes[i].cursor.flash()\r
+                        self.wiimotes[i].cursor.blit(self.playerScreen)\r
+                \r
+                self.screen.blit(self.playerScreen, (0,0))\r
+                \r
+                pygame.display.flip()\r
+            \r
             for i in range(len(self.wiimotes)):\r
                 if self.activeWiimotes[i]:\r
-                    self.wiimotes[i].cursor.update(timePassed, self.cursorPositions[i])\r
-                    if self.buttonDown[i] or self.alwaysDown:\r
-                        self.wiimotes[i].cursor.flash()\r
-                    self.wiimotes[i].cursor.blit(self.playerScreen)\r
+                    self.wiimotes[i].stopNoteByNoteNumber(self.midiNoteNumbers[self.notes[i]])\r
+            if self.replay :        \r
+                self.totalDuration = self.eventLog.getCurrentTime()\r
+        \r
+        elif isinstance(song, Part) :\r
+            self.songDurations = []\r
+            self.totalDuration = None\r
+            self.clicks = [0]\r
+            self.clicksIn = [0]\r
+            self.clicksPerMinute = [0]\r
+            self.clicksInPerMinute = [0]\r
+            self.meanTimeBetweenNotes = []\r
+            self.firstClick = None\r
+            self.firstClickIn = None\r
             \r
-            self.screen.blit(self.playerScreen, (0,0))\r
+            self.blinkLength = 200\r
+            self.minimalVelocity = 90\r
+            self.shortScaleSize = 8\r
+            self.longScaleSize = 11\r
+            if not extendedScale:\r
+                self.offset = self.longScaleSize - self.shortScaleSize\r
+            else:\r
+                self.offset = 0\r
+            self.borderSize = 5\r
+            self.highlightedNote = 0\r
+            self.highlightedNoteNumber = 0\r
+            self.syllabus = None\r
+            self.savedHighlightedNote = 0\r
+            self.alwaysDown = alwaysDown\r
+            self.nextLevel = None\r
             \r
-            pygame.display.flip()\r
-        \r
-        for i in range(len(self.wiimotes)):\r
-            if self.activeWiimotes[i]:\r
-                self.wiimotes[i].stopNoteByNoteNumber(self.midiNoteNumbers[self.notes[i]])\r
-        if self.replay :        \r
-            self.totalDuration = self.eventLog.getCurrentTime()            \r
+            self.wiimotes = instrumentChoice.wiimotes\r
+            self.activeWiimotes = instrumentChoice.activeWiimotes\r
+            self.window = instrumentChoice.window\r
+            self.screen = instrumentChoice.screen\r
+            self.blitOrigin = instrumentChoice.blitOrigin\r
+            self.clock = instrumentChoice.clock\r
+            self.width = instrumentChoice.width\r
+            self.height = instrumentChoice.height\r
+            self.cursorPositions = instrumentChoice.cursorPositions\r
+            self.savedScreen = instrumentChoice.savedScreen\r
+            self.playerScreen = instrumentChoice.playerScreen\r
+            self.extendedScale = extendedScale\r
+            self.cascade = cascade\r
+            self.joys = instrumentChoice.joys\r
+            self.portOffset = instrumentChoice.portOffset\r
+            if eventLog == None :\r
+                self.eventLog = instrumentChoice.eventLog\r
+            else :\r
+                self.eventLog = eventLog\r
+            self.cursorPositions = instrumentChoice.cursorPositions\r
+            self.song = song\r
+            self.songIterator = self.song.iterNotes()\r
+            self.midiNoteNumbers = self.song.scale\r
+            if replay == None :\r
+                self.replay = instrumentChoice.replay\r
+            else :\r
+                self.replay = replay\r
+            self.quarterNoteLength = song.quarterNoteLength\r
+            self.cascadeLockLengthMultiplier = 1\r
+            self.nextCascadeLockLengthMultiplier = 1\r
+            self.cascadeLockLength = self.quarterNoteLength * self.cascadeLockLengthMultiplier\r
+            \r
+            self.defaultInstrumentChannel = defaultInstrumentChannel\r
+            self.defaultNote = defaultNote\r
+            \r
+            self.done = False\r
+            self.backToInstrumentChoice = False\r
+            self.easyMode = easyMode\r
+            \r
+            #Initializes the highlightedNote and highlightedNoteNumber etc...\r
+            self.moveToNextNote()\r
+            self.cascadeLockLengthMultiplier = self.nextCascadeLockLengthMultiplier\r
+            \r
+            self.blinkOn = False\r
+            self.savedBlinkOn = False\r
+            ##Will prevent the song to move on if two consecutive notes are identical and the buttons have not been released in between the two\r
+            ##i.e. it guarantees that there will be an attack between two identical consecutive notes\r
+            self.highlightIsFree = True\r
+            \r
+            self.noteRects = []\r
+            self.boundingRect = None\r
+            self.notes = []\r
+            \r
+            self.buttonDown = []\r
+            self.velocityLock = []\r
+            \r
+            self._blinkOffset = 0\r
+            self._cascadeLockTimer = 0\r
+            self.cascadeIsFree = True\r
+            \r
+            self.font = pygame.font.Font(None,80)\r
+            self.renderedNoteNames = [self.font.render(constants.noteNumberToName(note),False,(0,0,0)) for note in self.midiNoteNumbers]\r
+            \r
+            self.drawBackground()\r
+            self.initializeWiimotes()\r
+            \r
+            self.songStartTime = self.eventLog.getCurrentTime()\r
+            \r
+            #The main loop\r
+            while not self.done :\r
+                \r
+                #Clear the cursors from the screen\r
+                if self.hasChanged():\r
+                    self.drawBackground()\r
+                self.playerScreen.blit(self.savedScreen, (0, 0))\r
+                \r
+                # Limit frame speed to 50 FPS\r
+                #\r
+                timePassed = self.clock.tick(10000)\r
+                \r
+                self._blinkOffset += timePassed\r
+                if (self.buttonDown or self.alwaysDown) and not self.cascadeIsFree :\r
+                    self._cascadeLockTimer += timePassed\r
+                    if self._cascadeLockTimer > self.cascadeLockLengthMultiplier*self.quarterNoteLength :\r
+                        self.cascadeIsFree = True\r
+                        self.cascadeLockLengthMultiplier = self.nextCascadeLockLengthMultiplier\r
+                \r
+                \r
+                if self._blinkOffset > self.blinkLength:\r
+                    self._blinkOffset -= self.blinkLength\r
+                    self.blinkOn = not self.blinkOn\r
+                    \r
+                if self.replay:\r
+                    self.eventLog.update(timePassed)\r
+                    pickledEventsToPost = self.eventLog.getPickledEvents() \r
+                    for pickledEvent in pickledEventsToPost:\r
+                        pygame.event.post(pickledEvent.event)\r
+                \r
+                events = pygame.event.get()\r
+                \r
+                if not self.replay:\r
+                    pickledEvents = [PickleableEvent(event.type,event.dict) for event in events]\r
+                    if pickledEvents != [] :\r
+                        self.eventLog.appendEventGroup(pickledEvents)\r
+                \r
+                for event in events:\r
+                    self.input(event)\r
+                                \r
+                for i in range(len(self.wiimotes)):\r
+                    if self.activeWiimotes[i]:\r
+                        self.wiimotes[i].cursor.update(timePassed, self.cursorPositions[i])\r
+                        if self.buttonDown[i] or self.alwaysDown:\r
+                            self.wiimotes[i].cursor.flash()\r
+                        self.wiimotes[i].cursor.blit(self.playerScreen)\r
+                \r
+                self.screen.blit(self.playerScreen, (0,0))\r
+                \r
+                pygame.display.flip()\r
+            \r
+            for i in range(len(self.wiimotes)):\r
+                if self.activeWiimotes[i]:\r
+                    self.wiimotes[i].stopNoteByNoteNumber(self.midiNoteNumbers[self.notes[i]])\r
+            if self.replay :        \r
+                self.totalDuration = self.eventLog.getCurrentTime()\r
         \r
     def drawBackground(self):\r
         self.savedScreen.fill((255,255,255))\r
@@ -560,5 +725,12 @@ class SongPlayingScreen:
         \r
     def moveToNextNote(self):\r
         self.savedMidiNoteNumbers = self.midiNoteNumbers[:]\r
-        self.highlightedNote, self.highlightedNoteNumber, self.syllabus, self.nextCascadeLockLengthMultiplier = self.songIterator.next()\r
+        note, lyricIndex = self.songIterator.next()\r
+        self.highlightedNote = note.column\r
+        self.highlightedNoteNumber = note.midi\r
+        self.syllabus = str(note.lyrics[lyricIndex])\r
+        self.nextCascadeLockLengthMultiplier = note.duration\r
         self.midiNoteNumbers[self.highlightedNote] = self.highlightedNoteNumber\r
+        \r
+        #self.highlightedNote, self.highlightedNoteNumber, self.syllabus, self.nextCascadeLockLengthMultiplier = self.songIterator.next()\r
+        #self.midiNoteNumbers[self.highlightedNote] = self.highlightedNoteNumber\r