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