[5140276] | 1 | from aubio.bench.node import * |
---|
| 2 | |
---|
| 3 | def parse_args(req): |
---|
| 4 | req.basehref = BASEHREF |
---|
| 5 | req.datadir = DATADIR |
---|
| 6 | if req.path_info: path_info = req.path_info |
---|
| 7 | else: path_info = '/' |
---|
| 8 | location = re.sub('^/show_[a-z0-9]*/','',path_info) |
---|
| 9 | location = re.sub('^/play_[a-z0-9]*/','',location) |
---|
| 10 | location = re.sub('^/index/','',location) |
---|
| 11 | location = re.sub('^/','',location) |
---|
| 12 | location = re.sub('/$','',location) |
---|
| 13 | datapath = "%s/%s" % (DATADIR,location) |
---|
| 14 | respath = "%s/%s" % (DATADIR,location) |
---|
| 15 | last = re.sub('/$','',location) |
---|
| 16 | last = last.split('/')[-1] |
---|
| 17 | first = path_info.split('/')[1] |
---|
| 18 | # store some of this in the mp_request |
---|
| 19 | req.location, req.datapath, req.respath = location, datapath, respath |
---|
| 20 | req.first, req.last = first, last |
---|
| 21 | |
---|
| 22 | if location: |
---|
| 23 | if not (os.path.isfile(datapath) or |
---|
| 24 | os.path.isdir(datapath) or |
---|
| 25 | location in ['feedback','email']): |
---|
| 26 | # the path was not understood |
---|
| 27 | from mod_python import apache |
---|
| 28 | req.write("<html> path not found %s</html>" % (datapath)) |
---|
| 29 | raise apache.SERVER_RETURN, apache.OK |
---|
| 30 | #from mod_python import apache |
---|
| 31 | #raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND |
---|
| 32 | |
---|
| 33 | def navigation(req): |
---|
| 34 | """ main html navigation header """ |
---|
| 35 | from mod_python import psp |
---|
| 36 | req.content_type = "text/html" |
---|
| 37 | parse_args(req) |
---|
| 38 | datapath = req.datapath |
---|
| 39 | location = req.location |
---|
| 40 | |
---|
| 41 | # deal with session |
---|
| 42 | if req.sess.is_new(): |
---|
| 43 | msg = "<b>Welcome %s</b><br>" % req.sess['login'] |
---|
| 44 | else: |
---|
| 45 | msg = "<b>Welcome back %s</b><br>" % req.sess['login'] |
---|
| 46 | |
---|
| 47 | # start writing |
---|
| 48 | tmpl = psp.PSP(req, filename='header.tmpl') |
---|
| 49 | tmpl.run(vars = { 'title': "aubioweb / %s / %s" % (req.first,location), |
---|
| 50 | 'basehref': '/~piem/', |
---|
| 51 | 'message': msg, |
---|
| 52 | 'action': req.first}) |
---|
| 53 | |
---|
| 54 | req.write("<h2>Content of ") |
---|
| 55 | print_link(req,"","/") |
---|
| 56 | y = location.split('/') |
---|
| 57 | for i in range(len(y)-1): |
---|
| 58 | print_link(req,"/".join(y[:i+1]),y[i]) |
---|
| 59 | req.write(" / ") |
---|
| 60 | req.write("%s</h2>\n" % y[-1]) |
---|
| 61 | |
---|
| 62 | a = {'show_info' : 'info', |
---|
| 63 | 'show_sound': 'waveform', |
---|
| 64 | 'show_onset': 'onset', |
---|
| 65 | 'index' : 'index', |
---|
| 66 | 'show_pitch': 'pitch', |
---|
| 67 | 'play_m3u': 'stream (m3u/ogg)', |
---|
| 68 | 'play_ogg': 'save (ogg)', |
---|
| 69 | 'play_wav': 'save (wav)', |
---|
| 70 | } |
---|
| 71 | |
---|
| 72 | # print task lists (only remaining tasks) |
---|
| 73 | print_link(req,re.sub('%s.*'%req.last,'',location),"go up") |
---|
| 74 | akeys = a.keys(); akeys.sort(); |
---|
| 75 | curkey = req.first |
---|
| 76 | for akey in akeys: |
---|
| 77 | if akey != curkey: |
---|
| 78 | req.write(":: ") |
---|
| 79 | print_link(req,"/".join((akey,location)),a[akey]) |
---|
| 80 | else: |
---|
| 81 | req.write(":: ") |
---|
| 82 | req.write("<b>%s</b>" % a[akey]) |
---|
| 83 | req.write("<br>") |
---|
| 84 | |
---|
| 85 | # list the content of the directories |
---|
| 86 | listdir,listfiles = [],[] |
---|
| 87 | if os.path.isdir(datapath): |
---|
| 88 | listfiles = list_snd_files(datapath) |
---|
| 89 | listdir = list_dirs(datapath) |
---|
| 90 | listdir.pop(0) # kick the current dir |
---|
| 91 | elif os.path.isfile(datapath): |
---|
| 92 | listfiles = [datapath] |
---|
| 93 | listdir = [re.sub(req.last,'',location)] |
---|
| 94 | |
---|
| 95 | link_list(req,listdir,title="Subdirectories") |
---|
| 96 | link_list(req,listfiles,title="Files") |
---|
| 97 | |
---|
| 98 | def footer(req): |
---|
| 99 | """ html navigation footer """ |
---|
| 100 | from mod_python import psp |
---|
| 101 | tmpl = psp.PSP(req, filename='footer.tmpl') |
---|
| 102 | tmpl.run(vars = { 'time': -req.mtime+req.request_time }) |
---|
| 103 | |
---|
| 104 | def apply_on_data(req, func,**keywords): |
---|
| 105 | # bug: hardcoded snd file filter |
---|
| 106 | act_on_data(func,req.datapath,req.respath, |
---|
| 107 | filter="f -maxdepth 1 -name '*.wav' -o -name '*.aif'",**keywords) |
---|
| 108 | |
---|
| 109 | def print_link(req,target,name,basehref=BASEHREF): |
---|
| 110 | req.write("<a href='%s/%s'>%s</a>\n" % (basehref,target,name)) |
---|
| 111 | |
---|
| 112 | def print_img(req,target,name='',basehref=BASEHREF): |
---|
| 113 | if name == '': name = target |
---|
| 114 | req.write("<img src='%s/%s' alt='%s' title='%s'>\n" % (basehref,target,name,name)) |
---|
| 115 | |
---|
| 116 | def link_list(req,targetlist,basehref=BASEHREF,title=None): |
---|
| 117 | if len(targetlist) > 1: |
---|
| 118 | if title: req.write("<h3>%s</h3>"%title) |
---|
| 119 | req.write('<ul>') |
---|
| 120 | for i in targetlist: |
---|
| 121 | s = re.split('%s/'%DATADIR,i,maxsplit=1)[1] |
---|
| 122 | if s: |
---|
| 123 | req.write('<li>') |
---|
| 124 | print_link(req,s,s) |
---|
| 125 | req.write('</li>') |
---|
| 126 | req.write('</ul>') |
---|
| 127 | |
---|
| 128 | def print_list(req,list): |
---|
| 129 | req.write("<pre>\n") |
---|
| 130 | for i in list: req.write("%s\n" % i) |
---|
| 131 | req.write("</pre>\n") |
---|
| 132 | |
---|
| 133 | def print_command(req,command): |
---|
| 134 | req.write("<h4>%s</h4>\n" % re.sub('%%','%',command)) |
---|
| 135 | def print_runcommand(input,output): |
---|
| 136 | cmd = re.sub('(%)?%i','%s' % input, command) |
---|
| 137 | cmd = re.sub('(%)?%o','%s' % output, cmd) |
---|
| 138 | print_list(req,runcommand(cmd)) |
---|
| 139 | apply_on_data(req,print_runcommand) |
---|
| 140 | |
---|
| 141 | def datapath_to_location(input): |
---|
| 142 | location = re.sub(DATADIR,'',input) |
---|
| 143 | return re.sub('^/*','',location) |
---|
| 144 | |
---|
| 145 | ## drawing hacks |
---|
| 146 | def draw_func(req,func): |
---|
| 147 | import re |
---|
| 148 | req.content_type = "image/png" |
---|
| 149 | # build location (strip the func_path, add DATADIR) |
---|
| 150 | location = re.sub('^/draw_[a-z]*/','%s/'%DATADIR,req.path_info) |
---|
| 151 | location = re.sub('.png$','',location) |
---|
| 152 | if not os.path.isfile(location): |
---|
| 153 | from mod_python import apache |
---|
| 154 | raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND |
---|
| 155 | # replace location in func |
---|
| 156 | cmd = re.sub('(%)?%i','%s' % location, func) |
---|
| 157 | # add PYTHONPATH at the beginning, |
---|
| 158 | cmd = "%s%s 2> /dev/null" % (PYTHONPATH,cmd) |
---|
| 159 | for each in runcommand(cmd): |
---|
| 160 | req.write("%s\n"%each) |
---|
| 161 | |
---|
| 162 | def show_task(req,task): |
---|
| 163 | def show_task_file(input,output,task): |
---|
| 164 | location = datapath_to_location(input) |
---|
| 165 | print_img(req,"draw_%s/%s" % (task,location)) |
---|
| 166 | navigation(req) |
---|
| 167 | req.write("<h3>%s</h3>\n" % task) |
---|
| 168 | apply_on_data(req,show_task_file,task=task) |
---|
| 169 | footer(req) |
---|
| 170 | |
---|
| 171 | ## waveform_foo |
---|
| 172 | def draw_sound(req): |
---|
[2d975cf] | 173 | draw_func(req,"aubioplot-audio %%i stdout 2> /dev/null") |
---|
[5140276] | 174 | |
---|
| 175 | def show_sound(req): |
---|
| 176 | show_task(req,"sound") |
---|
| 177 | |
---|
| 178 | ## pitch foo |
---|
| 179 | def draw_pitch(req,threshold='0.3'): |
---|
[2d975cf] | 180 | draw_func(req,"aubiopitch -i %%i -p -m yin -t %s -O stdout" % threshold) |
---|
[5140276] | 181 | |
---|
| 182 | def show_pitch(req): |
---|
| 183 | show_task(req,"pitch") |
---|
| 184 | |
---|
| 185 | ## onset foo |
---|
| 186 | def draw_onset(req,threshold='0.3'): |
---|
| 187 | draw_func(req,"aubiocut -i %%i -p -m complex -t %s -O stdout" % threshold) |
---|
| 188 | |
---|
| 189 | def show_onset(req,threshold='0.3',details=''): |
---|
| 190 | def onset_file(input,output): |
---|
| 191 | location = datapath_to_location(input) |
---|
| 192 | print_img(req,"draw_onset/%s?threshold=%s"%(location,threshold)) |
---|
| 193 | print_link(req,"?threshold=%s" % (float(threshold)-0.1),"-") |
---|
| 194 | req.write("%s\n" % threshold) |
---|
| 195 | print_link(req,"?threshold=%s" % (float(threshold)+0.1),"+") |
---|
| 196 | # bug: hardcoded sndfile extension |
---|
| 197 | anote = re.sub('\.wav$','.txt',input) |
---|
| 198 | if anote == input: anote = "" |
---|
| 199 | res = get_extract(input,threshold) |
---|
| 200 | if os.path.isfile(anote): |
---|
| 201 | tru = get_anote(anote) |
---|
| 202 | print_list(req,get_results(tru,res,0.05)) |
---|
| 203 | else: |
---|
| 204 | req.write("no ground truth found<br>\n") |
---|
| 205 | if details: |
---|
| 206 | req.write("<h4>Extraction</h4>\n") |
---|
| 207 | print_list(req,res) |
---|
| 208 | else: |
---|
| 209 | req.write("<a href='%s/show_onset/%s?details=yes&threshold=%s'>details</a><br>\n" % |
---|
| 210 | (req.basehref,location,threshold)) |
---|
| 211 | if details and os.path.isfile(anote): |
---|
| 212 | req.write("<h4>Computed differences</h4>\n") |
---|
| 213 | ldiffs = get_diffs(tru,res,0.05) |
---|
| 214 | print_list(req,ldiffs) |
---|
| 215 | req.write("<h4>Annotations</h4>\n") |
---|
| 216 | print_list(req,tru) |
---|
| 217 | navigation(req) |
---|
| 218 | req.write("<h3>Onset</h3>\n") |
---|
| 219 | apply_on_data(req,onset_file) |
---|
| 220 | footer(req) |
---|
| 221 | |
---|
| 222 | def get_anote(anote): |
---|
| 223 | import aubio.onsetcompare |
---|
| 224 | # FIXME: should import with txtfile.read_datafile |
---|
| 225 | return aubio.onsetcompare.load_onsets(anote) |
---|
| 226 | |
---|
| 227 | def get_diffs(anote,extract,tol): |
---|
| 228 | import aubio.onsetcompare |
---|
| 229 | return aubio.onsetcompare.onset_diffs(anote,extract,tol) |
---|
| 230 | |
---|
| 231 | def get_extract(datapath,threshold='0.3'): |
---|
| 232 | cmd = "%saubiocut -v -m complex -t %s -i %s" % (PYTHONPATH,threshold,datapath) |
---|
| 233 | lo = runcommand(cmd) |
---|
| 234 | for i in range(len(lo)): lo[i] = float(lo[i]) |
---|
| 235 | return lo |
---|
| 236 | |
---|
| 237 | def get_results(anote,extract,tol): |
---|
| 238 | import aubio.onsetcompare |
---|
| 239 | orig, missed, merged, expc, bad, doubled = aubio.onsetcompare.onset_roc(anote,extract,tol) |
---|
| 240 | s =("GD %2.8f\t" % (100*float(orig-missed-merged)/(orig)), |
---|
| 241 | "FP %2.8f\t" % (100*float(bad+doubled)/(orig)) , |
---|
| 242 | "GD-merged %2.8f\t" % (100*float(orig-missed)/(orig)) , |
---|
| 243 | "FP-pruned %2.8f\t" % (100*float(bad)/(orig)) ) |
---|
| 244 | return s |
---|
| 245 | |
---|
| 246 | # play m3u foo |
---|
| 247 | def play_m3u(req): |
---|
| 248 | def show_task_file(input,output,task): |
---|
| 249 | location = datapath_to_location(input) |
---|
| 250 | req.write("http://%s%s/play_ogg/%s\n" % (HOSTNAME,BASEHREF,re.sub("play_m3u",task,location))) |
---|
| 251 | req.content_type = "audio/mpegurl" |
---|
| 252 | parse_args(req) |
---|
| 253 | apply_on_data(req,show_task_file,task="play_ogg") |
---|
| 254 | |
---|
| 255 | # play wav foo |
---|
| 256 | def play_wav(req): |
---|
| 257 | req.content_type = "audio/x-wav" |
---|
| 258 | func = "cat %%i" |
---|
| 259 | # build location (strip the func_path, add DATADIR) |
---|
| 260 | location = re.sub('^/play_wav/','%s/'%DATADIR,req.path_info) |
---|
| 261 | if not os.path.isfile(location): |
---|
| 262 | from mod_python import apache |
---|
| 263 | raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND |
---|
| 264 | # replace location in func |
---|
| 265 | cmd = re.sub('(%)?%i','%s' % location, func) |
---|
| 266 | # add PYTHONPATH at the beginning, |
---|
| 267 | cmd = "%s 2> /dev/null" % cmd |
---|
| 268 | for each in runcommand(cmd): |
---|
| 269 | req.write("%s\n"%each) |
---|
| 270 | |
---|
| 271 | # play ogg foo |
---|
| 272 | def play_ogg(req): |
---|
| 273 | req.content_type = "application/ogg" |
---|
| 274 | func = "oggenc -o - %%i" |
---|
| 275 | # build location (strip the func_path, add DATADIR) |
---|
| 276 | location = re.sub('^/play_ogg/','%s/'%DATADIR,req.path_info) |
---|
| 277 | location = re.sub('.ogg$','',location) |
---|
| 278 | if not os.path.isfile(location): |
---|
| 279 | from mod_python import apache |
---|
| 280 | raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND |
---|
| 281 | # replace location in func |
---|
| 282 | cmd = re.sub('(%)?%i','%s' % location, func) |
---|
| 283 | # add PYTHONPATH at the beginning, |
---|
| 284 | cmd = "%s 2> /dev/null" % cmd |
---|
| 285 | for each in runcommand(cmd): |
---|
| 286 | req.write("%s\n"%each) |
---|