1 # -*- coding: utf-8 -*-
3 Module de lecture des fichiers de log minwii
9 from widgets
.playingscreen
import PlayingScreenBase
10 from eventutils
import EventDispatcher
11 from events
import eventCodes
12 from synth
import Synth
13 from musicxml
import musicXml2Song
16 SUPPORTED_FILE_HEADER
= 'ENV winwii log format version : 1.0'
18 class LogFileReader(object) :
20 def __init__(self
, logfile
) :
21 if isinstance(logfile
, str) :
22 self
.logfile
= open(logfile
, 'r')
24 self
.logfile
= logfile
26 firstline
= self
.next()
27 assert firstline
== SUPPORTED_FILE_HEADER
30 def getSongFile(self
) :
36 if l
.startswith('APP chanson :') :
38 songfile
= l
.split(':', 1)[1].strip()
42 def getSoundFontFile(self
) :
47 if l
.startswith('ENV soundfont :') :
49 soundFontFile
= l
.split(':', 1)[1].strip()
58 if l
.startswith('APP bank :') :
61 bank
= l
.split(':', 1)[1].strip()
69 if l
.startswith('APP preset :') :
72 preset
= l
.split(':', 1)[1].strip()
75 def getScreenResolution(self
) :
80 if l
.startswith('ENV résolution écran :') :
82 screenResolution
= eval(l
.split(':', 1)[1].strip())
84 return screenResolution
86 def getFirstEventTicks(self
) :
91 if l
.startswith('EVT ') :
93 firstTicks
= int(l
.split(None, 2)[1])
104 line
= self
.logfile
.next().strip()
107 def getEventsIterator(self
) :
112 except StopIteration :
115 if not l
.startswith('EVT ') :
118 ticks
, eventName
, message
= l
.split(None, 3)[1:]
119 yield ticks
, eventName
, message
121 ticks
, eventName
= l
.split(None, 3)[1:]
122 yield ticks
, eventName
, ''
125 class LogFilePlayer(PlayingScreenBase
) :
127 ré-exécution d'une chanson sur la base de son fichier de log.
130 def __init__(self
, logfile
) :
131 lfr
= self
.lfr
= LogFileReader(logfile
)
132 songFile
= lfr
.getSongFile()
133 soundFontFile
= lfr
.getSoundFontFile()
134 sfPath
= lfr
.getSoundFontFile()
136 preset
= lfr
.getPreset()
137 synth
= Synth(sfPath
=sfPath
)
138 synth
.program_select(0, bank
, preset
)
139 self
.song
= musicXml2Song(songFile
)
140 screenResolution
= lfr
.getScreenResolution()
142 pygame
.display
.set_mode(screenResolution
)
144 super(LogFilePlayer
, self
).__init
__(synth
, self
.song
.distinctNotes
)
148 clock
= pygame
.time
.Clock()
149 pygame
.display
.flip()
150 pygame
.mouse
.set_visible(False)
152 previousTicks
= self
.lfr
.getFirstEventTicks()
153 eIter
= self
.lfr
.getEventsIterator()
155 for ticks
, eventName
, message
in eIter
:
156 t0
= pygame
.time
.get_ticks()
158 if eventName
== 'COLSTATECHANGE' :
159 parts
= message
.split(None, 4)
162 index
, state
, midi
, name
, syllabus
= parts
165 state
= state
== 'True'
166 col
= self
.columns
[midi
]
167 col
.update(state
, syllabus
=syllabus
.decode('utf-8'))
169 elif eventName
== 'NOTEON':
170 chan
, key
, vel
= [int(v
) for v
in message
.split(None, 2)]
171 self
.synth
.noteon(chan
, key
, vel
)
173 elif eventName
== 'NOTEOFF':
174 chan
, key
= [int(v
) for v
in message
.split(None, 1)]
175 self
.synth
.noteoff(chan
, key
)
177 elif eventName
.startswith('COL') :
178 pos
= [int(n
) for n
in message
.split(None, 4)[-1].strip('()').split(',')]
179 self
.cursor
.setPosition(pos
)
182 pygame
.event
.clear() # à virer
183 #EventDispatcher.dispatchEvents()
185 dirty
= self
.draw(pygame
.display
.get_surface())
186 pygame
.display
.update(dirty
)
187 execTime
= pygame
.time
.get_ticks() - t0
189 delay
= ticks
- previousTicks
- execTime
191 pygame
.time
.wait(delay
)
193 previousTicks
= ticks
194 #print ticks, eventName, message
196 #while self._running :
197 # EventDispatcher.dispatchEvents()
198 # dirty = self.draw(pygame.display.get_surface())
199 # pygame.display.update(dirty)