|
@@ -39,11 +39,20 @@ def fit_to_reference( pkL, refTakeId ):
|
39
|
39
|
return zip(db_outL,us_outL,dur_outL,tid_outL)
|
40
|
40
|
|
41
|
41
|
|
42
|
|
-def get_merged_pulse_db_measurements( inDir, midi_pitch, analysisArgsD ):
|
|
42
|
+def get_merged_pulse_db_measurements( inDir, midi_pitch, analysisArgsD, takeId=None ):
|
43
|
43
|
|
44
|
44
|
inDir = os.path.join(inDir,"%i" % (midi_pitch))
|
45
|
45
|
|
46
|
|
- takeDirL = os.listdir(inDir)
|
|
46
|
+ takeIdL = []
|
|
47
|
+ if takeId is not None:
|
|
48
|
+ takeIdL.append(takeId)
|
|
49
|
+ else:
|
|
50
|
+ takeDirL = os.listdir(inDir)
|
|
51
|
+
|
|
52
|
+ # for each take in this directory
|
|
53
|
+ for take_folder in takeDirL:
|
|
54
|
+ takeIdL.append(int(take_folder))
|
|
55
|
+
|
47
|
56
|
|
48
|
57
|
pkL = []
|
49
|
58
|
|
|
@@ -52,9 +61,7 @@ def get_merged_pulse_db_measurements( inDir, midi_pitch, analysisArgsD ):
|
52
|
61
|
dbRefL = None
|
53
|
62
|
|
54
|
63
|
# for each take in this directory
|
55
|
|
- for take_folder in takeDirL:
|
56
|
|
-
|
57
|
|
- take_number = int(take_folder)
|
|
64
|
+ for take_number in takeIdL:
|
58
|
65
|
|
59
|
66
|
if refTakeId is None:
|
60
|
67
|
refTakeId = take_number
|
|
@@ -66,7 +73,7 @@ def get_merged_pulse_db_measurements( inDir, midi_pitch, analysisArgsD ):
|
66
|
73
|
for db,us,stats in zip(r.pkDbL,r.pkUsL,r.statsL):
|
67
|
74
|
pkL.append( (db,us,stats.durMs,take_number) )
|
68
|
75
|
|
69
|
|
-
|
|
76
|
+
|
70
|
77
|
pkUsL = []
|
71
|
78
|
pkDbL = []
|
72
|
79
|
durMsL = []
|
|
@@ -323,9 +330,99 @@ def plot_us_db_curves( ax, inDir, keyMapD, midi_pitch, analysisArgsD, plotResamp
|
323
|
330
|
ax.axhline( r['maxDbL'][ r['pitchL'].index(midi_pitch) ], color='blue' )
|
324
|
331
|
|
325
|
332
|
ax.set_ylabel( "%i %s %s" % (midi_pitch, keyMapD[midi_pitch]['type'],keyMapD[midi_pitch]['class']))
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+def plot_us_db_take_curve( ax, inDir, keyMapD, midi_pitch, takeId, analysisArgsD ):
|
|
336
|
+
|
|
337
|
+ usL, dbL, durMsL, takeIdL, holdDutyPctL = get_merged_pulse_db_measurements( inDir, midi_pitch, analysisArgsD['rmsAnalysisArgs'] )
|
|
338
|
+
|
|
339
|
+ reUsL, reDbL, noiseL, resampleL, skipL, firstAudibleIdx, firstNonSkipIdx = get_resample_points( usL, dbL, durMsL, takeIdL, analysisArgsD['resampleMinDurMs'], analysisArgsD['resampleMinDb'], analysisArgsD['resampleNoiseLimitPct'] )
|
|
340
|
+
|
|
341
|
+ # plot first audible and non-skip position
|
|
342
|
+ if False:
|
|
343
|
+
|
|
344
|
+ if firstNonSkipIdx is not None:
|
|
345
|
+ ax.plot( usL[firstNonSkipIdx], dbL[firstNonSkipIdx], markersize=15, marker='+', linestyle='None', color='red')
|
|
346
|
+
|
|
347
|
+ if firstAudibleIdx is not None:
|
|
348
|
+ ax.plot( usL[firstAudibleIdx], dbL[firstAudibleIdx], markersize=15, marker='*', linestyle='None', color='red')
|
|
349
|
+
|
|
350
|
+ # plot the resample points
|
|
351
|
+ if plotResamplePointsFl:
|
|
352
|
+ ax.plot( reUsL, reDbL, markersize=13, marker='x', linestyle='None', color='green')
|
|
353
|
+
|
|
354
|
+ # plot the noisy sample positions
|
|
355
|
+ if noiseL:
|
|
356
|
+ nUsL,nDbL = zip(*noiseL)
|
|
357
|
+ ax.plot( nUsL, nDbL, marker='o', markersize=9, linestyle='None', color='black')
|
|
358
|
+
|
|
359
|
+ # plot the noisy sample positions and the neighbors included in the noisy region
|
|
360
|
+ if resampleL:
|
|
361
|
+ nUsL,nDbL = zip(*resampleL)
|
|
362
|
+ ax.plot( nUsL, nDbL, marker='+', markersize=8, linestyle='None', color='red')
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+ # plot actual sample points
|
|
367
|
+
|
|
368
|
+ elbow_us = None
|
|
369
|
+ elbow_db = None
|
|
370
|
+ elbow_len = None
|
|
371
|
+
|
|
372
|
+ usL,dbL,takeIdL = zip(*[(us,dbL[i],takeIdL[i]) for i,us in enumerate(usL) if usMax is None or us <= usMax])
|
|
373
|
+
|
|
374
|
+ if plotTakesFl:
|
|
375
|
+ for takeId in list(set(takeIdL)):
|
|
376
|
+
|
|
377
|
+ # get the us,db points included in this take
|
|
378
|
+ xL,yL = zip(*[(usL[i],dbL[i]) for i in range(len(usL)) if takeIdL[i]==takeId ])
|
|
379
|
+
|
|
380
|
+ ax.plot(xL,yL, marker='.',label=takeId)
|
|
381
|
+
|
|
382
|
+ for i,(x,y) in enumerate(zip(xL,yL)):
|
|
383
|
+ ax.text(x,y,str(i))
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+ #if elbow_len is None or len(xL) > elbow_len:
|
|
387
|
+ if takeId+1 == len(set(takeIdL)):
|
|
388
|
+ elbow_us,elbow_db = elbow.find_elbow(xL,yL)
|
|
389
|
+ elbow_len = len(xL)
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+ else:
|
|
394
|
+ ax.plot(usL, dbL, marker='.')
|
|
395
|
+
|
|
396
|
+ ax.plot([elbow_us],[elbow_db],marker='*',markersize=12,color='red',linestyle='None')
|
|
397
|
+
|
|
398
|
+ # plot the skip points in yellow
|
|
399
|
+ if False:
|
|
400
|
+ if skipL:
|
|
401
|
+ nUsL,nDbL = zip(*skipL)
|
|
402
|
+ ax.plot( nUsL, nDbL, marker='.', linestyle='None', color='yellow')
|
|
403
|
+
|
|
404
|
+ # plot the locations where the hold duty cycle changes with vertical black lines
|
|
405
|
+ for us_duty in holdDutyPctL:
|
|
406
|
+ us,duty = tuple(us_duty)
|
|
407
|
+ if us > 0:
|
|
408
|
+ ax.axvline(us,color='black')
|
|
409
|
+
|
|
410
|
+ # plot the 'minDb' reference line
|
|
411
|
+ ax.axhline(analysisArgsD['resampleMinDb'] ,color='black')
|
|
412
|
+
|
|
413
|
+ if os.path.isfile("minInterpDb.json"):
|
|
414
|
+ with open("minInterpDb.json","r") as f:
|
|
415
|
+ r = json.load(f)
|
|
416
|
+ if midi_pitch in r['pitchL']:
|
|
417
|
+ ax.axhline( r['minDbL'][ r['pitchL'].index(midi_pitch) ], color='blue' )
|
|
418
|
+ ax.axhline( r['maxDbL'][ r['pitchL'].index(midi_pitch) ], color='blue' )
|
|
419
|
+
|
|
420
|
+ ax.set_ylabel( "%i %s %s" % (midi_pitch, keyMapD[midi_pitch]['type'],keyMapD[midi_pitch]['class']))
|
|
421
|
+
|
326
|
422
|
|
327
|
423
|
def plot_us_db_curves_main( inDir, cfg, pitchL, plotTakesFl=True, usMax=None, printDir="" ):
|
328
|
424
|
|
|
425
|
+
|
329
|
426
|
analysisArgsD = cfg.analysisArgs
|
330
|
427
|
keyMapD = { d['midi']:d for d in cfg.key_mapL }
|
331
|
428
|
axN = len(pitchL)
|
|
@@ -336,6 +433,7 @@ def plot_us_db_curves_main( inDir, cfg, pitchL, plotTakesFl=True, usMax=None, pr
|
336
|
433
|
fig.set_size_inches(18.5, 10.5*axN)
|
337
|
434
|
|
338
|
435
|
for ax,midi_pitch in zip(axL,pitchL):
|
|
436
|
+
|
339
|
437
|
plot_us_db_curves( ax,inDir, keyMapD, midi_pitch, analysisArgsD, plotTakesFl=plotTakesFl, usMax=usMax )
|
340
|
438
|
|
341
|
439
|
if plotTakesFl:
|
|
@@ -346,6 +444,54 @@ def plot_us_db_curves_main( inDir, cfg, pitchL, plotTakesFl=True, usMax=None, pr
|
346
|
444
|
|
347
|
445
|
plt.show()
|
348
|
446
|
|
|
447
|
+def _plot_us_db_takes( inDir, cfg, pitchL, takeIdL, printDir="", printFn="" ):
|
|
448
|
+
|
|
449
|
+ assert( len(pitchL) == len(takeIdL) )
|
|
450
|
+
|
|
451
|
+ analysisArgsD = cfg.analysisArgs
|
|
452
|
+ keyMapD = { d['midi']:d for d in cfg.key_mapL }
|
|
453
|
+ fig,ax = plt.subplots(1,1)
|
|
454
|
+
|
|
455
|
+ fig.set_size_inches(18.5, 10.5)
|
|
456
|
+
|
|
457
|
+ for midi_pitch,takeId in zip(pitchL,takeIdL):
|
|
458
|
+
|
|
459
|
+ usL, dbL, durMsL, _, holdDutyPctL = get_merged_pulse_db_measurements( inDir, midi_pitch, analysisArgsD['rmsAnalysisArgs'], takeId=takeId )
|
|
460
|
+
|
|
461
|
+ ax.plot(usL,dbL, marker='.',label="%i:%i %s %s" % (midi_pitch,takeId,keyMapD[midi_pitch]['class'],keyMapD[midi_pitch]['type']))
|
|
462
|
+
|
|
463
|
+ # for i,(x,y) in enumerate(zip(usL,dbL)):
|
|
464
|
+ # ax.text(x,y,str(i))
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+ if printDir:
|
|
468
|
+ plt.savefig(os.path.join(printDir,printFn),format="png")
|
|
469
|
+
|
|
470
|
+ plt.legend()
|
|
471
|
+ plt.show()
|
|
472
|
+
|
|
473
|
+def plot_us_db_takes( inDir, cfg, pitchL, printDir=""):
|
|
474
|
+
|
|
475
|
+ takeIdL = None
|
|
476
|
+ takeIdL = [ pitchL[i] for i in range(1,len(pitchL),2) ]
|
|
477
|
+ pitchL = [ pitchL[i] for i in range(0,len(pitchL),2) ]
|
|
478
|
+
|
|
479
|
+ return _plot_us_db_takes( inDir, cfg, pitchL, takeIdL, printDir, "us_db_takes.png")
|
|
480
|
+
|
|
481
|
+def plot_us_db_takes_last( inDir, cfg, pitchL, printDir ):
|
|
482
|
+
|
|
483
|
+ takeIdL = []
|
|
484
|
+ for pitch in pitchL:
|
|
485
|
+
|
|
486
|
+ inDirL = os.listdir( os.path.join(inDir,str(pitch)))
|
|
487
|
+
|
|
488
|
+ inDirL = sorted(inDirL)
|
|
489
|
+
|
|
490
|
+ takeIdL.append( int(inDirL[-1]) )
|
|
491
|
+
|
|
492
|
+ return _plot_us_db_takes( inDir, cfg, pitchL, takeIdL, printDir, "us_db_takes_last.png")
|
|
493
|
+
|
|
494
|
+
|
349
|
495
|
def plot_all_noise_curves( inDir, cfg, pitchL=None ):
|
350
|
496
|
|
351
|
497
|
pitchFolderL = os.listdir(inDir)
|
|
@@ -800,7 +946,7 @@ def gen_vel_map( inDir, cfg, minMaxDbFn, dynLevelN, cacheFn ):
|
800
|
946
|
|
801
|
947
|
if __name__ == "__main__":
|
802
|
948
|
|
803
|
|
- printDir =os.path.expanduser( "~/src/picadae_ac_3/doc")
|
|
949
|
+ printDir = None #os.path.expanduser( "~/src/picadae_ac_3/doc")
|
804
|
950
|
cfgFn = sys.argv[1]
|
805
|
951
|
inDir = sys.argv[2]
|
806
|
952
|
mode = sys.argv[3]
|
|
@@ -814,6 +960,10 @@ if __name__ == "__main__":
|
814
|
960
|
|
815
|
961
|
if mode == 'us_db':
|
816
|
962
|
plot_us_db_curves_main( inDir, cfg, pitchL, plotTakesFl=True,usMax=None, printDir=printDir )
|
|
963
|
+ elif mode == 'us_db_pitch_take':
|
|
964
|
+ plot_us_db_takes( inDir, cfg, pitchL, printDir=printDir)
|
|
965
|
+ elif mode == 'us_db_pitch_last':
|
|
966
|
+ plot_us_db_takes_last( inDir, cfg, pitchL, printDir=printDir)
|
817
|
967
|
elif mode == 'noise':
|
818
|
968
|
plot_all_noise_curves( inDir, cfg, pitchL )
|
819
|
969
|
elif mode == 'min_max':
|