From: pin Date: Mon, 8 Feb 2010 11:26:53 +0000 (+0000) Subject: ayé, on joue du musicxml :-) X-Git-Url: https://scm.cri.mines-paristech.fr/git/minwii.git/commitdiff_plain/f3c7ce6115ca54c1bc5db03ce03a873ee379edcf?ds=sidebyside ayé, on joue du musicxml :-) git-svn-id: https://svn.cri.ensmp.fr/svn/minwii/trunk@13 fe552daf-6dbe-4428-90eb-1537e0879342 --- diff --git a/src/dataTools/__init__.pyc b/src/dataTools/__init__.pyc index 759cc27..8d2ef12 100644 Binary files a/src/dataTools/__init__.pyc and b/src/dataTools/__init__.pyc differ diff --git a/src/dataTools/odict.pyc b/src/dataTools/odict.pyc index b9e213b..1d56861 100644 Binary files a/src/dataTools/odict.pyc and b/src/dataTools/odict.pyc differ diff --git a/src/gui/PGUConfiguration.py b/src/gui/PGUConfiguration.py index 214a347..5e9f7e7 100644 --- a/src/gui/PGUConfiguration.py +++ b/src/gui/PGUConfiguration.py @@ -246,7 +246,7 @@ class PGUConfiguration(pguGui.Desktop): self.easyMode = False choice = InstrumentChoice(instruments, wiimotes, self.window, screen, clock, joys, portOffset,self.activeWiimotes, scaleFactor = songScaleFactor) - play = SongPlayingScreen(choice, self.song,self.cascade, self.extendedScale,self.easyMode,self.alwaysDown) + play = SongPlayingScreen(choice, self)# self.song,self.cascade, self.extendedScale,self.easyMode,self.alwaysDown) else: @@ -264,7 +264,7 @@ class PGUConfiguration(pguGui.Desktop): self.cascade = True choice = InstrumentChoice(instruments, wiimotes, self.window, screen, clock, joys, portOffset,self.activeWiimotes) - play = PlayingScreen(choice, None,self.cascade, self.extendedScale) + play = PlayingScreen(choice, self)#None,self.cascade, self.extendedScale) while play.backToInstrumentChoice == True : diff --git a/src/gui/SongPlayingScreen.py b/src/gui/SongPlayingScreen.py index a06e831..5ddd67a 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 = str(note.lyrics[lyricIndex]) + 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 diff --git a/src/mxmMidi/DataTypeConverters.pyc b/src/mxmMidi/DataTypeConverters.pyc index f5ef8c8..208295a 100644 Binary files a/src/mxmMidi/DataTypeConverters.pyc and b/src/mxmMidi/DataTypeConverters.pyc differ diff --git a/src/mxmMidi/EventDispatcher.pyc b/src/mxmMidi/EventDispatcher.pyc index 2657b04..245af08 100644 Binary files a/src/mxmMidi/EventDispatcher.pyc and b/src/mxmMidi/EventDispatcher.pyc differ diff --git a/src/mxmMidi/MidiFileParser.pyc b/src/mxmMidi/MidiFileParser.pyc index f6a7165..6524752 100644 Binary files a/src/mxmMidi/MidiFileParser.pyc and b/src/mxmMidi/MidiFileParser.pyc differ diff --git a/src/mxmMidi/MidiInFile.pyc b/src/mxmMidi/MidiInFile.pyc index 182efaa..88b3cca 100644 Binary files a/src/mxmMidi/MidiInFile.pyc and b/src/mxmMidi/MidiInFile.pyc differ diff --git a/src/mxmMidi/MidiOutStream.pyc b/src/mxmMidi/MidiOutStream.pyc index 53ceb24..cc51d3a 100644 Binary files a/src/mxmMidi/MidiOutStream.pyc and b/src/mxmMidi/MidiOutStream.pyc differ diff --git a/src/mxmMidi/RawInstreamFile.pyc b/src/mxmMidi/RawInstreamFile.pyc index 9d05bf3..abad76a 100644 Binary files a/src/mxmMidi/RawInstreamFile.pyc and b/src/mxmMidi/RawInstreamFile.pyc differ diff --git a/src/mxmMidi/constants.pyc b/src/mxmMidi/constants.pyc index 0ce9fec..f392f8b 100644 Binary files a/src/mxmMidi/constants.pyc and b/src/mxmMidi/constants.pyc differ diff --git a/src/songs/musicxmltosong.py b/src/songs/musicxmltosong.py index 39df188..ed7dddf 100755 --- a/src/songs/musicxmltosong.py +++ b/src/songs/musicxmltosong.py @@ -33,6 +33,10 @@ _marker = [] class Part(object) : + requiresExtendedScale = False + scale = [55, 57, 59, 60, 62, 64, 65, 67, 69, 71, 72] + quarterNoteLength = 400 + def __init__(self, node, autoDetectChorus=True) : self.node = node self.notes = [] @@ -109,10 +113,24 @@ class Part(object) : def pprint(self) : for note, verseIndex in self.iterNotes() : print note.nom, note.name, note.midi, note.duration, note.lyrics[verseIndex] + + + def assignNotesFromMidiNoteNumbers(self): + # TODO faire le mapping bande hauteur midi + for i in range(len(self.midiNoteNumbers)): + noteInExtendedScale = 0 + while self.midiNoteNumbers[i] > self.scale[noteInExtendedScale] and noteInExtendedScale < len(self.scale)-1: + noteInExtendedScale += 1 + if self.midiNoteNumbers[i]