diff --git a/bin/ascoltami b/bin/ascoltami --- a/bin/ascoltami +++ b/bin/ascoltami @@ -12,6 +12,21 @@ features and limitations: requesting what song is playing saying what song should play + +setup: + +get mpd root path correct + +run mpd that's been modified to give precise times: + dash(pts/21):/my/dl/modified/mpd% src/mpd --no-daemon + +tell it to scan + mpc update + (mpc listall to check) + +run ascoltami + + todo: diff --git a/bin/curvecalc b/bin/curvecalc --- a/bin/curvecalc +++ b/bin/curvecalc @@ -20,14 +20,15 @@ except ImportError: from twisted.internet import reactor,tksupport import twisted from twisted.web.xmlrpc import Proxy -from rdflib import Literal, URIRef +from rdflib import Literal, URIRef, RDF +from rdflib.Graph import Graph import logging log = logging.getLogger() logging.basicConfig(format="%(asctime)s %(levelname)-5s %(name)s %(filename)s:%(lineno)d: %(message)s") log.setLevel(logging.DEBUG) import run_local -from light9 import Submaster, dmxclient, networking, showconfig +from light9 import Submaster, dmxclient, networking, showconfig, prof from light9.TLUtility import make_attributes_from_args, dict_subset from light9.zoomcontrol import Zoomcontrol from light9.curve import Curve, Curveview, Curveset, Curvesetview @@ -257,13 +258,6 @@ def create_status_lines(master): l.config(text=sn+": "+tf(val)), signame,weak=0) -def savesubterms(filename,subterms): - s="" - for st in subterms: - s=s+"%s %s\n" % (st.submaster.name, st.subexpr.expr) - - file(filename,'w').write(s) - class SubtermSetView(tk.Frame): def __init__(self, master, *args, **kw): tk.Frame.__init__(self, master, *args, **kw) @@ -284,7 +278,7 @@ def add_one_subterm(graph, sub, curveset if expr is None: expr = '%s(t)' % subname - term = Subterm(Submaster.Submaster(sub), Subexpr(curveset,expr)) + term = Subterm(Submaster.Submaster(graph=graph, sub=sub), Subexpr(curveset,expr)) subterms.append(term) stv=Subtermview(ssv,term) @@ -314,13 +308,32 @@ def sub_commands_tk(master, curveset, su return f +def savesubterms(filename,subterms): + raise NotImplementedError + s="" + for st in subterms: + s=s+"%s %s\n" % (st.submaster.name, st.subexpr.expr) + + file(filename,'w').write(s) + +def createSubtermGraph(song, subterms): + """rdf graph describing the subterms, readable by add_subterms_for_song""" + graph = Graph() + for subterm in subterms: + uri = URIRef(song + "/subterm/" + subterm.submaster.name) + graph.add((song, L9['subterm'], uri)) + graph.add((uri, RDF.type, L9['Subterm'])) + graph.add((uri, L9['sub'], L9['sub/%s' % subterm.submaster.name])) + graph.add((uri, L9['expression'], Literal(subterm.subexpr.expr))) + return graph + def add_subterms_for_song(graph, song, curveset, subterms, root, ssv): for st in graph.objects(song, L9['subterm']): add_one_subterm(graph, graph.value(st, L9['sub']), curveset, subterms, root, ssv, graph.value(st, L9['expression'])) -def songFilename(uri): - return uri.split('/')[-1] +def graphPathForSubterms(song): + return showconfig.subtermsForSong(showconfig.songFilenameFromURI(song)) + ".n3" ####################################################################### root=tk.Tk() @@ -356,20 +369,27 @@ musicfilename = showconfig.songOnDisk(so maxtime = wavelength(musicfilename) dispatcher.send("max time",maxtime=maxtime) dispatcher.connect(lambda: maxtime, "get max time",weak=0) -curveset.load(basename=os.path.join(showconfig.curvesDir(), songFilename(song))) +curveset.load(basename=os.path.join(showconfig.curvesDir(), showconfig.songFilenameFromURI(song))) subterms = [] sub_commands_tk(root, curveset, subterms, root, ssv, graph).pack(side='top',fill='x') -add_subterms_for_song(graph, song, curveset, subterms, root, ssv) +try: + g = Graph() + g.parse(graphPathForSubterms(song), format='n3') + add_subterms_for_song(g, song, curveset, subterms, root, ssv) +except OSError, e: + print e log.debug("output") out = Output(subterms, music) def savekey(*args): print "saving",song - savesubterms(showconfig.subtermsForSong(songFilename(song)), subterms) - curveset.save(basename=os.path.join(showconfig.curvesDir(), songFilename(song))) + g = createSubtermGraph(song, subterms) + g.serialize(graphPathForSubterms(song), format="nt") + + curveset.save(basename=os.path.join(showconfig.curvesDir(), showconfig.songFilenameFromURI(song))) print "saved" root.bind("",savekey) @@ -391,9 +411,5 @@ root.bind("",lambda ev: reactor root.protocol('WM_DELETE_WINDOW', reactor.stop) tksupport.install(root,ms=20) log.debug("run") -if 0: - sys.path.append("/home/drewp/projects/cuisine/pour") - from utils import runstats - runstats("reactor.run()") -else: - reactor.run() +prof.run(reactor.run, profile=False) + diff --git a/bin/wavecurve b/bin/wavecurve --- a/bin/wavecurve +++ b/bin/wavecurve @@ -3,15 +3,41 @@ import os, sys, optparse import run_local from light9.wavepoints import simp -parser = optparse.OptionParser(usage="%prog inputSong.wav outputCurve") + +def createCurve(inpath, outpath, t): + print "reading %s, writing %s" % (inpath, outpath) + points = simp(inpath, seconds_per_average=t) + + f = file(outpath, 'w') + for time_val in points: + print >>f, "%s %s" % time_val + + + +parser = optparse.OptionParser(usage="""%prog inputSong.wav outputCurve + +You probably just want -a + +""") parser.add_option("-t",type="float",default=.01, help="seconds per sample (default .01, .07 is smooth)") +parser.add_option("-a", action="store_true", + help="make standard curves for all songs") options,args = parser.parse_args() -inpath,outpath = args -points = simp(inpath, seconds_per_average=options.t) - -f = file(outpath, 'w') -for time_val in points: - print >>f, "%s %s" % time_val +if options.a: + from light9 import showconfig + from light9.namespaces import L9 + from rdflib import RDF + graph = showconfig.getGraph() + for song in graph.subjects(RDF.type, L9['Song']): + inpath = showconfig.songOnDisk(song) + for curveName, t in [('music', .01), + ('smooth_music', .07)]: + outpath = showconfig.curvesDir() + "/%s-%s" % ( + showconfig.songFilenameFromURI(song), curveName) + createCurve(inpath, outpath, t) +else: + inpath,outpath = args + createCurve(inpath, outpath, options.t) diff --git a/light9/prof.py b/light9/prof.py new file mode 100644 --- /dev/null +++ b/light9/prof.py @@ -0,0 +1,36 @@ +import hotshot, hotshot.stats +import sys, traceback + +def run(main, profile=False): + if not profile: + main() + return + + p = hotshot.Profile("/tmp/pro") + p.runcall(main) + p.close() + hotshot.stats.load("/tmp/pro").sort_stats('time').print_stats() + +def watchPoint(filename, lineno, event="call"): + """whenever we hit this line, print a stack trace. event='call' + for lines that are function definitions, like what a profiler + gives you. + + Switch to 'line' to match lines inside functions. Execution speed + will be much slower.""" + seenTraces = {} # trace contents : count + def trace(frame, ev, arg): + if ev == event: + if (frame.f_code.co_filename, frame.f_lineno) == (filename, lineno): + stack = ''.join(traceback.format_stack(frame)) + if stack not in seenTraces: + print "watchPoint hit" + print stack + seenTraces[stack] = 1 + else: + seenTraces[stack] += 1 + + return trace + sys.settrace(trace) + + # atexit, print the frequencies? diff --git a/light9/showconfig.py b/light9/showconfig.py --- a/light9/showconfig.py +++ b/light9/showconfig.py @@ -66,11 +66,20 @@ def songOnDisk(song): songFullPath = path.join(root(), graph.value(song, L9['showPath'])) return songFullPath +def songFilenameFromURI(uri): + """ + 'http://light9.bigasterisk.com/show/dance2007/song8' -> 'song8' + + everything that uses this should be deprecated for real URIs + everywhere""" + assert isinstance(uri, URIRef) + return uri.split('/')[-1] + def curvesDir(): return path.join(root(),"curves") def songFilename(song): - return path.join(musicDir(),"%s.wav" % song) + return path.join(root(), "music", "%s.wav" % song) def subtermsForSong(song): return path.join(root(),"subterms",song)