X-Git-Url: https://svn.cri.ensmp.fr/git/minwii.git/blobdiff_plain/eec2dd4ea183465c2c95546402447303ee6320e4..9dc58a99930c4951aa561d75e572416221c3aa33:/src/minwii/logfilereader.py diff --git a/src/minwii/logfilereader.py b/src/minwii/logfilereader.py index 29425f7..828b085 100755 --- a/src/minwii/logfilereader.py +++ b/src/minwii/logfilereader.py @@ -6,15 +6,26 @@ $Id$ $URL$ """ +from types import StringTypes from widgets.playingscreen import PlayingScreenBase from eventutils import EventDispatcher from events import eventCodes from synth import Synth from musicxml import musicXml2Song import pygame +from backwardsfilereader import BackwardsReader SUPPORTED_FILE_HEADER = 'ENV winwii log format version : 1.0' +def inplaceread(m) : + def readinplace(self, *args, **kw) : + pos = self.logfile.tell() + self.logfile.seek(0) + ret = m(self, *args, **kw) + self.logfile.seek(pos) + return ret + return readinplace + class LogFileReader(object) : """ classe utilitaire pour l'accès aux données d'un fichier de log MinWii. @@ -24,100 +35,91 @@ class LogFileReader(object) : """ logfile : chemin d'accès au fichier de log MinWii. le format supporté est actuellement la version 1.0 uniquement. """ - if isinstance(logfile, str) : + if isinstance(logfile, StringTypes) : self.logfile = open(logfile, 'r') else : self.logfile = logfile firstline = self.next() assert firstline == SUPPORTED_FILE_HEADER - + + @inplaceread def getSongFile(self) : "retourne le chemin d'accès au fichier musicxml de la chanson" - f = self.logfile - pos = f.tell() - - f.seek(0) for l in self : if l.startswith('APP chanson :') : break songfile = l.split(':', 1)[1].strip() - f.seek(pos) return songfile + @inplaceread def getSoundFontFile(self) : "retourne le chemin d'accès au fichier de la soundfont (*.sf2)" - f = self.logfile - pos = f.tell() - f.seek(0) for l in self : if l.startswith('ENV soundfont :') : break soundFontFile = l.split(':', 1)[1].strip() - f.seek(pos) return soundFontFile - + + @inplaceread def getBank(self) : "retourne le paramètre bank du synthétiseur (entier)" - f = self.logfile - pos = f.tell() - f.seek(0) for l in self : if l.startswith('APP bank :') : break - f.seek(pos) bank = l.split(':', 1)[1].strip() return int(bank) + @inplaceread def getPreset(self) : "retourne le paramètre preset du synthétiseur (entier)" - f = self.logfile - pos = f.tell() - f.seek(0) for l in self : if l.startswith('APP preset :') : break - f.seek(pos) preset = l.split(':', 1)[1].strip() return int(preset) + @inplaceread def getScreenResolution(self) : "retourne la résolution écran (tuple de deux entiers)" - f = self.logfile - pos = f.tell() - f.seek(0) for l in self : if l.startswith('ENV résolution écran :') : break screenResolution = eval(l.split(':', 1)[1].strip()) - f.seek(pos) return screenResolution + @inplaceread def getMode(self) : "retourne le niveau de difficulté" - f = self.logfile - pos = f.tell() for l in self : if l.startswith('APP mode :') : break mode = l.split(':', 1)[1].strip() - f.geek(pos) return mode + @inplaceread def getFirstEventTicks(self) : "retourne le timecode du premier événement (entier)" - f = self.logfile - pos = f.tell() - f.seek(0) for l in self : if l.startswith('EVT ') : break firstTicks = int(l.split(None, 2)[1]) - f.seek(pos) return firstTicks + @inplaceread + def getLastEventTicks(self) : + "retourne le timecode du dernier événement (entier)" + for l in self.getBackwardLineIterator() : + if l.startswith('EVT ') : + break + else : + return None + + lastTicks = int(l.split(None, 2)[1]) + return lastTicks + def __del__(self) : self.logfile.close() @@ -151,6 +153,14 @@ class LogFileReader(object) : ticks, eventName = l.split(None, 3)[1:] ticks = int(ticks) yield ticks, eventName, '' + + def getBackwardLineIterator(self) : + br = BackwardsReader(self.logfile, BLKSIZE=128) + line = br.readline() + while line : + yield line.strip() + line = br.readline() + class LogFilePlayer(PlayingScreenBase) :