Przeglądaj źródła

plot_seq_1.py : Many changes and updates.

master
kevin 3 lat temu
rodzic
commit
f36e7c8a64
1 zmienionych plików z 144 dodań i 46 usunięć
  1. 144
    46
      plot_seq_1.py

+ 144
- 46
plot_seq_1.py Wyświetl plik

1
 ##| Copyright: (C) 2019-2020 Kevin Larke <contact AT larke DOT org> 
1
 ##| Copyright: (C) 2019-2020 Kevin Larke <contact AT larke DOT org> 
2
 ##| License: GNU GPL version 3.0 or above. See the accompanying LICENSE file.
2
 ##| License: GNU GPL version 3.0 or above. See the accompanying LICENSE file.
3
-import os, sys,json
3
+import os, sys,json,math
4
 import matplotlib.pyplot as plt
4
 import matplotlib.pyplot as plt
5
 import numpy as np
5
 import numpy as np
6
 from common import parse_yaml_cfg
6
 from common import parse_yaml_cfg
458
 
458
 
459
         usL, dbL, durMsL, _, holdDutyPctL = get_merged_pulse_db_measurements( inDir, midi_pitch, analysisArgsD['rmsAnalysisArgs'], takeId=takeId )
459
         usL, dbL, durMsL, _, holdDutyPctL = get_merged_pulse_db_measurements( inDir, midi_pitch, analysisArgsD['rmsAnalysisArgs'], takeId=takeId )
460
 
460
 
461
+
461
         ax.plot(usL,dbL, marker='.',label="%i:%i %s %s" % (midi_pitch,takeId,keyMapD[midi_pitch]['class'],keyMapD[midi_pitch]['type']))
462
         ax.plot(usL,dbL, marker='.',label="%i:%i %s %s" % (midi_pitch,takeId,keyMapD[midi_pitch]['class'],keyMapD[midi_pitch]['type']))
462
 
463
 
463
-        # for i,(x,y) in enumerate(zip(usL,dbL)):
464
-        #    ax.text(x,y,str(i))
464
+        for i,(x,y) in enumerate(zip(usL,dbL)):
465
+            ax.text(x,y,str(i))
465
 
466
 
467
+        f_usL,f_dbL = filter_us_db(usL,dbL)
468
+            
469
+        ax.plot(f_usL,f_dbL, marker='.')
470
+            
471
+
472
+        elbow_us,elbow_db = elbow.find_elbow(usL,dbL)
473
+        ax.plot([elbow_us],[elbow_db],marker='*',markersize=12,color='red',linestyle='None')
474
+
475
+        elb_idx = nearest_sample_point( dbL, usL, elbow_db, elbow_us )
466
 
476
 
467
     if printDir:
477
     if printDir:
468
         plt.savefig(os.path.join(printDir,printFn),format="png")
478
         plt.savefig(os.path.join(printDir,printFn),format="png")
469
         
479
         
470
     plt.legend()
480
     plt.legend()
471
     plt.show()
481
     plt.show()
482
+
483
+def get_pitches_and_takes( inDir ):
484
+
485
+    pitchD = {}
486
+    inDirL = os.listdir( inDir )
487
+
488
+    for pitch in inDirL:
489
+        path    = os.path.join( inDir, pitch )
490
+        takeIdL = os.listdir( path )
491
+        
492
+        takeIdL = sorted([ int(takeId) for takeId in takeIdL ])
493
+        takeIdL = [ str(x) for x in takeIdL ] 
494
+        pitchD[int(pitch)] = takeIdL
495
+
496
+
497
+    return pitchD
472
     
498
     
473
 def plot_us_db_takes( inDir, cfg, pitchL, printDir=""):
499
 def plot_us_db_takes( inDir, cfg, pitchL, printDir=""):
474
 
500
 
480
 
506
 
481
 def plot_us_db_takes_last( inDir, cfg, pitchL, printDir ):
507
 def plot_us_db_takes_last( inDir, cfg, pitchL, printDir ):
482
 
508
 
509
+    pitchD = get_pitches_and_takes(inDir)
510
+    
483
     takeIdL = []
511
     takeIdL = []
484
     for pitch in pitchL:
512
     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]) )
513
+        takeIdL.append( int(pitchD[pitch][-1]) )
491
 
514
 
492
     return _plot_us_db_takes( inDir, cfg, pitchL, takeIdL, printDir, "us_db_takes_last.png")
515
     return _plot_us_db_takes( inDir, cfg, pitchL, takeIdL, printDir, "us_db_takes_last.png")
493
     
516
     
535
     plt.legend()
558
     plt.legend()
536
     plt.show()
559
     plt.show()
537
 
560
 
538
-def plot_min_max_2_db( inDir, cfg, pitchL=None, takeId=2, printDir=None ):
561
+def nearest_sample_point( dbL, usL, db0, us0 ):
562
+    xL = np.array([ abs(us-us0)  for db,us in zip(dbL,usL) ])
539
 
563
 
540
-    pitchFolderL = os.listdir(inDir)
564
+    return np.argmin(xL)
541
 
565
 
542
-    print(pitchL)
566
+    
567
+def plot_min_max_2_db( inDir, cfg, pitchL=None, takeId=2, printDir=None ):
543
 
568
 
569
+    takeIdArg  = takeId
570
+    pitchTakeD = get_pitches_and_takes(inDir)
571
+    
572
+    pitchFolderL = os.listdir(inDir)
544
     if pitchL is None:
573
     if pitchL is None:
545
         pitchL = [ int( int(pitchFolder) ) for pitchFolder in pitchFolderL ]
574
         pitchL = [ int( int(pitchFolder) ) for pitchFolder in pitchFolderL ]
546
 
575
 
547
-    print(pitchL)
548
-        
549
     okL       = []
576
     okL       = []
550
     outPitchL = []
577
     outPitchL = []
551
     minDbL    = []
578
     minDbL    = []
553
     
580
     
554
     for midi_pitch in pitchL:
581
     for midi_pitch in pitchL:
555
 
582
 
556
-        print(midi_pitch)
583
+        takeId = None
584
+        if takeIdArg == -1:
585
+            takeId = pitchTakeD[midi_pitch][-1]
557
 
586
 
558
-        usL, dbL, durMsL, takeIdL, holdDutyPctL = get_merged_pulse_db_measurements( inDir, midi_pitch, cfg.analysisArgs['rmsAnalysisArgs'] )
587
+        usL, dbL, durMsL, takeIdL, holdDutyPctL = get_merged_pulse_db_measurements( inDir, midi_pitch, cfg.analysisArgs['rmsAnalysisArgs'], takeId )
559
 
588
 
560
         okL.append(False)
589
         okL.append(False)
561
 
590
 
571
         minDbL.append(elbow_db)
600
         minDbL.append(elbow_db)
572
         outPitchL.append(midi_pitch)
601
         outPitchL.append(midi_pitch)
573
 
602
 
603
+        smp_idx = nearest_sample_point( dbL, usL, elbow_db, elbow_us )
604
+
605
+        print(" %i:[-1,%i], " % (midi_pitch,smp_idx))
574
 
606
 
575
 
607
 
576
     p_dL = sorted( zip(outPitchL,minDbL,maxDbL,okL), key=lambda x: x[0] )
608
     p_dL = sorted( zip(outPitchL,minDbL,maxDbL,okL), key=lambda x: x[0] )
593
        
625
        
594
     plt.show()
626
     plt.show()
595
 
627
 
596
-def plot_min_db_manual( inDir, cfg, printDir=None ):
628
+def plot_min_db_manual( inDir, cfg, printDir=None, absMaxDb=27, absMinDb=3 ):
629
+
630
+    pitchTakeD = get_pitches_and_takes(inDir)
597
     
631
     
598
     pitchL     = list(cfg.manualMinD.keys())
632
     pitchL     = list(cfg.manualMinD.keys())
599
     
633
     
606
 
640
 
607
     for midi_pitch in pitchL:
641
     for midi_pitch in pitchL:
608
 
642
 
609
-        manual_take_id    = cfg.manualMinD[midi_pitch][0]
643
+        if cfg.manualLastFl:
644
+            manual_take_id = pitchTakeD[midi_pitch][-1]
645
+            takeId         = manual_take_id
646
+        else:
647
+            manual_take_id = cfg.manualMinD[midi_pitch][0]
648
+            takeId         = None
649
+        
610
         manual_sample_idx = cfg.manualMinD[midi_pitch][1]
650
         manual_sample_idx = cfg.manualMinD[midi_pitch][1]
611
         
651
         
612
-        usL, dbL, durMsL, takeIdL, holdDutyPctL = get_merged_pulse_db_measurements( inDir, midi_pitch, cfg.analysisArgs['rmsAnalysisArgs'] )
652
+        usL, dbL, durMsL, takeIdL, holdDutyPctL = get_merged_pulse_db_measurements( inDir, midi_pitch, cfg.analysisArgs['rmsAnalysisArgs'], takeId )
613
 
653
 
614
         okL.append(False)
654
         okL.append(False)
615
 
655
 
616
-        takeId = len(set(takeIdL))-1
656
+        if takeId is None:
657
+            takeId = len(set(takeIdL))-1
617
 
658
 
659
+            # most pitches have 3 sample takes that do not
660
+            if len(set(takeIdL)) == 3 and manual_take_id == takeId:
661
+                okL[-1] = True
662
+        else:
663
+            okL[-1] = True
664
+                
618
         # maxDb is computed on all takes (not just the specified take)
665
         # maxDb is computed on all takes (not just the specified take)
619
         db_maxL = sorted(dbL)
666
         db_maxL = sorted(dbL)
620
-        max_db = np.mean(db_maxL[-4:])
667
+        max_db = min(absMaxDb,np.mean(db_maxL[-4:]))
621
         maxDbL.append( max_db )
668
         maxDbL.append( max_db )
622
 
669
 
623
         # get the us,db values for the specified take
670
         # get the us,db values for the specified take
624
         usL,dbL = zip(*[(usL[i],dbL[i]) for i in range(len(usL)) if takeIdL[i]==manual_take_id  ])
671
         usL,dbL = zip(*[(usL[i],dbL[i]) for i in range(len(usL)) if takeIdL[i]==manual_take_id  ])
625
 
672
 
626
-        # most pitches have 3 sample takes that do not
627
-        if len(set(takeIdL)) == 3 and manual_take_id == takeId:
628
-            okL[-1] = True
629
 
673
 
630
         # min db from the sample index manually specified in cfg
674
         # min db from the sample index manually specified in cfg
631
-        manualMinDb = dbL[ manual_sample_idx ]
632
-        
675
+        manualMinDb = max(absMinDb,dbL[ manual_sample_idx ])
676
+
633
         minDbL.append( manualMinDb )
677
         minDbL.append( manualMinDb )
634
         outPitchL.append(midi_pitch)
678
         outPitchL.append(midi_pitch)
635
 
679
 
642
 
686
 
643
         
687
         
644
             
688
             
645
-    
646
-
647
     # Form the complete set of min/max db levels for each pitch by interpolating the
689
     # Form the complete set of min/max db levels for each pitch by interpolating the
648
     # db values between the manually selected anchor points.
690
     # db values between the manually selected anchor points.
649
     interpMinDbL = np.interp( pitchL, cfg.manualAnchorPitchMinDbL, anchorMinDbL )
691
     interpMinDbL = np.interp( pitchL, cfg.manualAnchorPitchMinDbL, anchorMinDbL )
861
         if len(takeDirL) == 0:
903
         if len(takeDirL) == 0:
862
             print(pitch," directory empty")
904
             print(pitch," directory empty")
863
         else:
905
         else:
864
-            with open( os.path.join(pitchDir,'0','seq.json'), "rb") as f:
865
-                r = json.load(f)
906
+            
907
+            fn = os.path.join(pitchDir,'0','seq.json')
908
+            
909
+            if not os.path.isfile(fn):
910
+                print("Missing sequence file:",fn)
911
+            else:
912
+                with open( fn, "rb") as f:
913
+                    r = json.load(f)
866
 
914
 
867
-            if len(r['eventTimeL']) != 81:
868
-                print(pitch," ",len(r['eventTimeL']))
915
+                
916
+                if len(r['eventTimeL']) != 81:
917
+                    print(pitch," ",len(r['eventTimeL']))
918
+
919
+                if len(takeDirL) != 3:
920
+                    print("***",pitch,len(takeDirL))
921
+
922
+def filter_us_db( us0L, db0L ):
923
+
924
+    us1L = [us0L[-1]]
925
+    db1L = [db0L[-1]]
926
+    dDb = 0
927
+    lastIdx = 0
928
+    for i,(us,db) in enumerate(zip( us0L[::-1],db0L[::-1])):
929
+        db1 = db1L[-1]
930
+        if db < db1 and db1-db >= dDb/2:
931
+            dDb = db1 - db
932
+            us1L.append(us)
933
+            db1L.append(db)
934
+            lastIdx = i
869
 
935
 
870
-            if len(takeDirL) != 3:
871
-                print("***",pitch,len(takeDirL))
872
 
936
 
937
+    lastIdx = len(us0L) - lastIdx - 1
938
+
939
+    
940
+    usL = [ us0L[lastIdx] ]
941
+    dbL = [ db0L[lastIdx] ]
942
+    dDb = 0
943
+    for us,db in zip(us0L[lastIdx::],db0L[lastIdx::]):
944
+        db1 = dbL[-1]
945
+        if db > db1:
946
+            dDb = db-db1
947
+            usL.append(us)
948
+            dbL.append(db)
949
+        
950
+    return usL,dbL
951
+                                    
873
 def cache_us_db( inDir, cfg, outFn ):
952
 def cache_us_db( inDir, cfg, outFn ):
874
 
953
 
954
+    pitchTakeD = get_pitches_and_takes(inDir)
955
+    
875
     pitch_usDbD = {}
956
     pitch_usDbD = {}
876
     pitchDirL = os.listdir(inDir)
957
     pitchDirL = os.listdir(inDir)
877
 
958
 
878
-    for pitch in pitchDirL:
959
+    for pitch,takeIdL in pitchTakeD.items():
879
 
960
 
880
         pitch = int(pitch)
961
         pitch = int(pitch)
962
+        takeId = takeIdL[-1]
881
 
963
 
882
         print(pitch)
964
         print(pitch)
883
         
965
         
884
-        usL, dbL, durMsL, takeIdL, holdDutyPctL = get_merged_pulse_db_measurements( inDir, pitch, cfg.analysisArgs['rmsAnalysisArgs'] )
966
+        usL, dbL, durMsL, takeIdL, holdDutyPctL = get_merged_pulse_db_measurements( inDir, pitch, cfg.analysisArgs['rmsAnalysisArgs'], takeId )
885
 
967
 
886
         pitch_usDbD[pitch] = { 'usL':usL, 'dbL':dbL, 'durMsL':durMsL, 'takeIdL':takeIdL, 'holdDutyPctL': holdDutyPctL }
968
         pitch_usDbD[pitch] = { 'usL':usL, 'dbL':dbL, 'durMsL':durMsL, 'takeIdL':takeIdL, 'holdDutyPctL': holdDutyPctL }
887
 
969
 
889
     with open(outFn,"w") as f:
971
     with open(outFn,"w") as f:
890
         json.dump(pitch_usDbD,f)
972
         json.dump(pitch_usDbD,f)
891
 
973
 
892
-        
974
+    
893
             
975
             
894
 def gen_vel_map( inDir, cfg, minMaxDbFn, dynLevelN, cacheFn ):
976
 def gen_vel_map( inDir, cfg, minMaxDbFn, dynLevelN, cacheFn ):
895
 
977
 
897
     
979
     
898
     pitchDirL = os.listdir(inDir)
980
     pitchDirL = os.listdir(inDir)
899
 
981
 
982
+    # pitchUsDbD = { pitch: 
900
     with open(cacheFn,"r") as f:
983
     with open(cacheFn,"r") as f:
901
         pitchUsDbD = json.load(f)
984
         pitchUsDbD = json.load(f)
902
         
985
         
903
 
986
 
987
+    # form minMaxDb = { pitch:(minDb,maxDb) }
904
     with open("minInterpDb.json","r") as f:
988
     with open("minInterpDb.json","r") as f:
905
         r = json.load(f)
989
         r = json.load(f)
906
         minMaxDbD = { pitch:(minDb,maxDb) for pitch,minDb,maxDb in zip(r['pitchL'],r['minDbL'],r['maxDbL']) }
990
         minMaxDbD = { pitch:(minDb,maxDb) for pitch,minDb,maxDb in zip(r['pitchL'],r['minDbL'],r['maxDbL']) }
907
-    
908
 
991
 
992
+        
909
     pitchL = sorted( [ int(pitch) for pitch in pitchUsDbD.keys()] )
993
     pitchL = sorted( [ int(pitch) for pitch in pitchUsDbD.keys()] )
910
-    
994
+
995
+    # for each pitch
911
     for pitch in pitchL:
996
     for pitch in pitchL:
997
+
998
+        # get the us/db map for this 
912
         d = pitchUsDbD[str(pitch)]
999
         d = pitchUsDbD[str(pitch)]
1000
+
1001
+
1002
+        usL, dbL = filter_us_db( d['usL'], d['dbL'] )        
1003
+        #usL = d['usL']
1004
+        #dbL = np.array(d['dbL'])
1005
+        dbL = np.array(dbL)
913
         
1006
         
914
-        usL = d['usL']
915
-        dbL = np.array(d['dbL'])
916
 
1007
 
917
         velMapD[pitch] = []
1008
         velMapD[pitch] = []
918
-        
919
-        for i in range(dynLevelN+1):
920
 
1009
 
921
-            db = minMaxDbD[pitch][0] + (i * (minMaxDbD[pitch][1] - minMaxDbD[pitch][0])/ dynLevelN)
1010
+        maxDb = minMaxDbD[pitch][1]
1011
+        minDb = minMaxDbD[pitch][0]
1012
+
1013
+        dynLevelN = len(cfg.velTableDbL)
1014
+
1015
+        # for each dynamic level
1016
+        for i in range(dynLevelN):
1017
+
1018
+            #db = minDb + (i * (maxDb - minDb)/ dynLevelN)
1019
+            db = cfg.velTableDbL[i]
922
 
1020
 
923
             usIdx = np.argmin( np.abs(dbL - db) )
1021
             usIdx = np.argmin( np.abs(dbL - db) )
924
             
1022
             
946
     
1044
     
947
 if __name__ == "__main__":
1045
 if __name__ == "__main__":
948
 
1046
 
949
-    printDir = None #os.path.expanduser( "~/src/picadae_ac_3/doc")
1047
+    printDir = os.path.expanduser("~/temp") # os.path.expanduser( "~/src/picadae_ac_3/doc")
950
     cfgFn   = sys.argv[1]
1048
     cfgFn   = sys.argv[1]
951
     inDir   = sys.argv[2]
1049
     inDir   = sys.argv[2]
952
     mode    = sys.argv[3]
1050
     mode    = sys.argv[3]
981
     elif mode == 'manual_db':
1079
     elif mode == 'manual_db':
982
         plot_min_db_manual( inDir, cfg, printDir=printDir )
1080
         plot_min_db_manual( inDir, cfg, printDir=printDir )
983
     elif mode == 'gen_vel_map':
1081
     elif mode == 'gen_vel_map':
984
-        gen_vel_map( inDir, cfg, "minInterpDb.json", 9, "cache_us_db.json" )
1082
+        gen_vel_map( inDir, cfg, "minInterpDb.json", 12, "cache_us_db.json" )
985
     elif mode == 'cache_us_db':
1083
     elif mode == 'cache_us_db':
986
         cache_us_db( inDir, cfg, "cache_us_db.json")
1084
         cache_us_db( inDir, cfg, "cache_us_db.json")
987
     else:
1085
     else:

Ładowanie…
Anuluj
Zapisz