Ver código fonte

Added multiple PWM values per note.

Misc. changes to plot_seq.py
master
kpl 4 anos atrás
pai
commit
919ecadf8d
4 arquivos alterados com 114 adições e 52 exclusões
  1. 44
    18
      p_ac.py
  2. 22
    7
      p_ac.yml
  3. 44
    27
      plot_seq.py
  4. 4
    0
      rms_analysis.py

+ 44
- 18
p_ac.py Ver arquivo

@@ -9,11 +9,12 @@ from AudioDevice  import AudioDevice
9 9
 from result       import Result
10 10
 from common       import parse_yaml_cfg
11 11
 from plot_seq     import form_resample_pulse_time_list
12
+from plot_seq     import form_final_pulse_list
12 13
 
13 14
 class AttackPulseSeq:
14 15
     """ Sequence a fixed chord over a list of attack pulse lengths."""
15 16
     
16
-    def __init__(self, audio, api, noteDurMs=1000, pauseDurMs=1000, holdDutyPct=50 ):
17
+    def __init__(self, audio, api, noteDurMs=1000, pauseDurMs=1000, holdDutyPctL=[(0,50)] ):
17 18
         self.audio       = audio
18 19
         self.api         = api
19 20
         self.outDir      = None           # directory to write audio file and results
@@ -21,12 +22,13 @@ class AttackPulseSeq:
21 22
         self.pulseUsL    = []             # one onset pulse length in microseconds per sequence element
22 23
         self.noteDurMs   = noteDurMs      # duration of each chord in milliseconds
23 24
         self.pauseDurMs  = pauseDurMs     # duration between end of previous note and start of next
24
-        self.holdDutyPct = holdDutyPct    # hold voltage duty cycle as a percentage (0-100)
25
+        self.holdDutyPctL= holdDutyPctL    # hold voltage duty cycle table [ (minPulseSeqUsec,dutyCyclePct) ]
25 26
         
26 27
         self.pulse_idx            = 0     # Index of next pulse 
27 28
         self.state                = None  # 'note_on','note_off'
29
+        self.prevHoldDutyPct      = None
28 30
         self.next_ms              = 0     # Time of next event (note-on or note_off)
29
-        self.eventTimeL           = []    # Onset/offset time of each note [ [onset_ms,offset_ms] ]
31
+        self.eventTimeL           = []    # Onset/offset time of each note [ [onset_ms,offset_ms] ] (used to locate the note in the audio file)
30 32
         self.beginMs              = 0
31 33
         self.playOnlyFl           = False
32 34
 
@@ -37,13 +39,15 @@ class AttackPulseSeq:
37 39
         
38 40
         self.pulse_idx  = 0
39 41
         self.state      = 'note_on'
42
+        self.prevHoldDutyPct = None
40 43
         self.next_ms    = ms + 500       # wait for 500ms to play the first note (this will guarantee that there is some empty space in the audio file before the first note)
41 44
         self.eventTimeL = [[0,0]  for _ in range(len(pulseUsL))] # initialize the event time         
42 45
         self.beginMs    = ms
43 46
         self.playOnlyFl = playOnlyFl
44 47
 
45
-        for pitch in pitchL:
46
-            self.api.set_pwm( pitch, self.holdDutyPct )
48
+        #for pitch in pitchL:
49
+        #    self.api.set_pwm_duty( pitch, self.holdDutyPct )
50
+        #    print("set PWM:%i"%(self.holdDutyPct))
47 51
 
48 52
         if not playOnlyFl:
49 53
             self.audio.record_enable(True)   # start recording audio
@@ -86,20 +90,39 @@ class AttackPulseSeq:
86 90
             else:                
87 91
                 assert(0)
88 92
                     
89
-        
93
+
94
+    def _get_duty_cycle( self, pulseUsec ):
95
+        dutyPct = self.holdDutyPctL[0][1]
96
+        for refUsec,refDuty in self.holdDutyPctL:
97
+            if pulseUsec < refUsec:
98
+                break
99
+            dutyPct = refDuty
100
+
101
+        return dutyPct
102
+            
103
+    def _set_duty_cycle( self, pitch, pulseUsec ):
104
+
105
+        dutyPct = self._get_duty_cycle( pulseUsec )
106
+
107
+        if dutyPct != self.prevHoldDutyPct:
108
+            self.api.set_pwm_duty( pitch, dutyPct )
109
+            print("Hold Duty:",dutyPct)
110
+            
111
+        self.prevHoldDutyPct = dutyPct
112
+    
90 113
     def _note_on( self, ms ):
91 114
 
92
-        #self.eventTimeL[ self.pulse_idx ][0] = ms - self.beginMs
93 115
         self.eventTimeL[ self.pulse_idx ][0] = self.audio.buffer_sample_ms().value
94 116
         self.next_ms = ms + self.noteDurMs
95 117
         self.state = 'note_off'
96 118
 
97 119
         for pitch in self.pitchL:
98
-            self.api.note_on_us( pitch, int(self.pulseUsL[ self.pulse_idx ]) )
120
+            pulse_usec = int(self.pulseUsL[ self.pulse_idx ])
121
+            self._set_duty_cycle( pitch, pulse_usec )
122
+            self.api.note_on_us( pitch, pulse_usec )
99 123
             print("note-on:",pitch,self.pulse_idx)
100 124
 
101 125
     def _note_off( self, ms ):
102
-        #self.eventTimeL[ self.pulse_idx ][1] = ms - self.beginMs
103 126
         self.eventTimeL[ self.pulse_idx ][1] = self.audio.buffer_sample_ms().value
104 127
         self.next_ms = ms + self.pauseDurMs
105 128
         self.state   = 'note_on'
@@ -123,7 +146,7 @@ class AttackPulseSeq:
123 146
             "pitchL":self.pitchL,
124 147
             "noteDurMs":self.noteDurMs,
125 148
             "pauseDurMs":self.pauseDurMs,
126
-            "holdDutyPct":self.holdDutyPct,
149
+            "holdDutyPctL":self.holdDutyPctL,
127 150
             "eventTimeL":self.eventTimeL,
128 151
             "beginMs":self.beginMs
129 152
             }
@@ -144,7 +167,7 @@ class AttackPulseSeq:
144 167
 class CalibrateKeys:
145 168
     def __init__(self, cfg, audioDev, api):
146 169
         self.cfg      = cfg
147
-        self.seq      = AttackPulseSeq(  audioDev, api, noteDurMs=1000, pauseDurMs=1000, holdDutyPct=50 )
170
+        self.seq      = AttackPulseSeq(  audioDev, api, noteDurMs=cfg.noteDurMs, pauseDurMs=cfg.pauseDurMs, holdDutyPctL=cfg.holdDutyPctL )
148 171
         
149 172
         self.pulseUsL  = None
150 173
         self.chordL   = None
@@ -198,14 +221,14 @@ class CalibrateKeys:
198 221
 
199 222
             outDir = os.path.join(outDir, dirStr )
200 223
 
201
-            print(outDir)
202 224
             if not os.path.isdir(outDir):
203 225
                 os.mkdir(outDir)
204 226
             
205
-
206 227
             # get the next available output directory id
207 228
             outDir_id = self._calc_next_out_dir_id( outDir )
208 229
 
230
+            print(outDir_id,outDir)
231
+            
209 232
             # if this is not the first time this note has been sampled then get the resample locations
210 233
             if outDir_id != 0:
211 234
                 self.pulseUsL,_,_ = form_resample_pulse_time_list( outDir, self.cfg.analysisArgs )
@@ -213,11 +236,14 @@ class CalibrateKeys:
213 236
             if playOnlyFl:
214 237
                 self.pulseUsL,_ = form_final_pulse_list( outDir,  pitchL[0],  self.cfg.analysisArgs, take_id=None )
215 238
 
216
-                
217
-            outDir = os.path.join( outDir, str(outDir_id) )
239
+                noteN = cfg.analysisArgs['auditionNoteN']
240
+                self.pulseUsL   = [ self.pulseUsL[ int(round(i*126.0/(noteN-1)))] for i in range(noteN) ]
218 241
 
219
-            if not os.path.isdir(outDir):
220
-                os.mkdir(outDir)
242
+            else:
243
+                outDir = os.path.join( outDir, str(outDir_id) )
244
+
245
+                if not os.path.isdir(outDir):
246
+                    os.mkdir(outDir)
221 247
 
222 248
             # start the sequencer
223 249
             self.seq.start( ms, outDir, pitchL, self.pulseUsL, playOnlyFl )
@@ -533,7 +559,7 @@ def parse_args():
533 559
     ap = argparse.ArgumentParser(description=descStr)
534 560
 
535 561
 
536
-    ap.add_argument("-c","--config",                     default="cfg/p_ac.yml",  help="YAML configuration file.")
562
+    ap.add_argument("-c","--config",                     default="p_ac.yml",  help="YAML configuration file.")
537 563
     ap.add_argument("-l","--log_level",choices=logL,     default="warning",             help="Set logging level: debug,info,warning,error,critical. Default:warning")
538 564
 
539 565
     return ap.parse_args()

+ 22
- 7
p_ac.yml Ver arquivo

@@ -18,15 +18,29 @@
18 18
 
19 19
 
20 20
     # MeasureSeq args
21
-    outDir: "~/temp/p_ac_3",
21
+    outDir: "~/temp/p_ac_3c",
22 22
     noteDurMs: 1000,
23 23
     pauseDurMs: 1000,
24
-    holdDutyPct: 50,
24
+    holdDutyPctL: [ [0,50], [17000,65] ],
25 25
 
26 26
     full_pulse0L: [ 500, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000, 5500, 6000, 6500, 7000, 8000, 9000, 10000, 12000, 14000, 18000, 22000, 26000, 30000, 34000, 40000],
27 27
     full_pulse1L: [  10000, 11000, 12000, 13000, 14000, 15000, 16000, 17000, 18000, 20000, 22000, 24000, 26000, 30000, 32000, 34000, 36000, 40000],
28
-    full_pulseL: [  10000, 10500, 11000, 11500, 12000, 12500, 13000, 13500, 14000, 14500, 15000, 15500, 16000, 16500, 17000, 17500, 18000, 18500, 20000, 22000, 24000, 26000, 30000, 32000, 34000, 36000, 40000],
28
+    full_pulse2L: [  10000, 10500, 11000, 11500, 12000, 12500, 13000, 13500, 14000, 14500, 15000, 15500, 16000, 16500, 17000, 17500, 18000, 18500, 20000, 22000, 24000, 26000, 30000, 32000, 34000, 36000, 40000],    
29 29
 
30
+    full_pulse3L: [  10000, 10125, 10250, 10500, 10625, 10750, 10875, 11000, 11125, 11250, 11500, 11625, 11750, 11875, 12000, 12125, 12250, 12500, 12625, 12750, 12875, 13000, 13125, 13250, 13500, 13625, 13750, 13875, 14000, 14125, 14250, 14500, 14625, 14750, 14875, 15000, 15500, 16000, 16500, 17000, 17500, 18000, 18500, 20000, 22000, 24000, 26000, 30000, 32000, 34000, 36000, 40000],    
31
+
32
+    full_pulse4L: [  8000, 8125, 8250, 8375, 8500, 8625, 8750, 8875, 9000, 9125, 9250, 9375, 9500, 9625, 9750, 9875, 10000, 10125, 10250, 10375, 10500, 10625, 10750, 10875, 11000, 11125, 11250, 11375, 11500, 11625, 11750, 11875, 12000, 12125, 12250, 12375, 12500, 12625, 12750, 12875, 13000, 13125, 13250, 13375, 13500, 13625, 13750, 13875, 14000, 14125, 14375, 14250, 14500, 14625, 14750, 14875, 15000, 15250, 15375, 15500, 15750, 16000, 16250, 16500, 16750, 17000, 17250, 17500, 17750, 18000, 18250, 18500, 18750, 20000, 21000, 22000, 23000, 24000, 25000, 26000, 27000, 28000, 30000, 32000, 34000, 36000, 40000],    
33
+
34
+    full_pulse5L: [  10000, 10125, 10250, 10375, 10500, 10625, 10750, 10875, 11000, 11125, 11250, 11375, 11500, 11625, 11750, 11875, 12000, 12125, 12250, 12375, 12500, 12625, 12750, 12875, 13000, 13125, 13250, 13375, 13500, 13625, 13750, 13875, 14000, 14125, 14250, 14375, 14500, 14625, 14750, 14875, 15000, 15250, 15375, 15500, 15750, 16000, 16250, 16500, 16750, 17000, 17250, 17500, 17750, 18000, 18250, 18500, 18750, 20000, 21000, 22000, 23000, 24000, 25000, 26000, 27000, 28000, 30000, 32000, 34000, 36000, 40000],    
35
+
36
+    full_pulse6L: [  12000, 12125, 12250, 12375, 12500, 12625, 12750, 12875, 13000, 13125, 13250, 13375, 13500, 13625, 13750, 13875, 14000, 14125, 14250, 14375, 14500, 14625, 14750, 14875, 15000, 15250, 15375, 15500, 15750, 16000, 16250, 16500, 16750, 17000, 17250, 17500, 17750, 18000, 18250, 18500, 18750, 19000, 19500, 20000, 20500, 21000, 21500, 22000, 22500, 23000, 23500, 24000, 24500, 25000, 25500, 26000, 26500, 27000, 27500, 28000, 28500, 29000, 30000, 31000, 32000, 33000, 34000, 35000, 36000, 37000, 38000, 39000, 40000 ],    
37
+
38
+    full_pulse7L: [  11000, 11125, 11250, 11375, 11500, 11625, 11750, 11875, 12000, 12125, 12250, 12375, 12500, 12625, 12750, 12875, 13000, 13125, 13250, 13375, 13500, 13625, 13750, 13875, 14000, 14125, 14250, 14375, 14500, 14625, 14750, 14875, 15000, 15250, 15375, 15500, 15750, 16000, 16250, 16500, 16750, 17000, 17250, 17500, 17750, 18000, 18250, 18500, 18750, 19000, 19500, 20000, 20500, 21000, 21500, 22000, 22500, 23000, 23500, 24000, 24500, 25000, 25500, 26000, 26500, 27000, 27500, 28000, 28500, 29000, 30000, 31000, 32000, 33000, 34000, 35000, 36000, 37000, 38000, 39000, 40000 ],    
39
+
40
+    full_pulseL: [  10000, 10050, 10100, 10150, 10200, 10250, 10300, 10350, 10400, 10450, 10500, 10550, 10600, 10650, 10700, 10750, 10800, 10850, 10900, 10950, 11000, 11125, 11250, 11375, 11500, 11625, 11750, 11875, 12000, 12125, 12250, 12375, 12500, 12625, 12750, 12875, 13000, 13125, 13250, 13375, 13500, 13625, 13750, 13875, 14000, 14125, 14250, 14375, 14500, 14625, 14750, 14875, 15000, 15250, 15375, 15500, 15750, 16000, 16250, 16500, 16750, 17000, 17250, 17500, 17750, 18000, 18250, 18500, 18750, 19000, 19500, 20000, 20500, 21000, 21500, 22000, 22500, 23000, 23500, 24000, 24500, 25000, 25500, 26000, 26500, 27000, 27500, 28000, 28500, 29000, 30000, 31000, 32000, 33000, 34000, 35000, 36000, 37000, 38000, 39000, 40000 ],    
41
+
42
+    full_pulse9L: [  8750, 8800, 8850, 8900, 8950, 9000, 9050, 9100, 9150, 9200, 9250, 9300, 9350, 9400, 9450,9500, 9550, 9600, 9650, 9700, 9750, 9800, 9850, 9900, 9950, 10000, 10050, 10100, 10150, 10200, 10250, 10300, 10350, 10400, 10450, 10500, 10550, 10600, 10650, 10700, 10750, 10800, 10850, 10900, 10950, 11000, 11125, 11250, 11375, 11500, 11625, 11750, 11875, 12000, 12125, 12250, 12375, 12500, 12625, 12750, 12875, 13000, 13125, 13250, 13375, 13500, 13625, 13750, 13875, 14000, 14125, 14250, 14375, 14500, 14625, 14750, 14875, 15000, 15250, 15375, 15500, 15750, 16000, 16250, 16500, 16750, 17000, 17250, 17500, 17750, 18000, 18250, 18500, 18750, 19000, 19500, 20000, 20500, 21000, 21500, 22000, 22500, 23000, 23500, 24000, 24500, 25000, 25500, 26000, 26500, 27000, 27500, 28000, 28500, 29000, 30000, 31000, 32000, 33000, 34000, 35000, 36000, 37000, 38000, 39000, 40000 ],    
43
+    
30 44
     # RMS analysis args
31 45
     analysisArgs: {
32 46
       rmsAnalysisArgs: {
@@ -37,11 +51,12 @@
37 51
         harmN: 3,         # count of harmonics to use to calculate harmonic based RMS analysis
38 52
       },
39 53
       
40
-      minAttkDb: 5.0,   # threshold of silence level 
41
-      maxDbOffset: 0.5, # travel down the from the max. note level by at most this amount to locate the max. peak
42
-      maxDeltaDb: 2.0,  # maximum db change between volume samples (changes greater than this will trigger resampling)
54
+      minAttkDb: 7.0,   # threshold of silence level 
55
+      maxDbOffset: 0.25, # travel down the from the max. note level by at most this amount to locate the max. peak
56
+      maxDeltaDb: 1.5,  # maximum db change between volume samples (changes greater than this will trigger resampling)
43 57
       samplesPerDb: 4,   # count of samples per dB to resample ranges whose range is less than maxDeltaDb
44
-      minSampleDistUs: 500 # minimum distance between sample points in microseconds
58
+      minSampleDistUs: 50, # minimum distance between sample points in microseconds
59
+      auditionNoteN: 19     # count of notes to play for audition
45 60
       },
46 61
     
47 62
      key_mapL: [

+ 44
- 27
plot_seq.py Ver arquivo

@@ -120,7 +120,8 @@ def form_final_pulse_list( inDir, midi_pitch, analysisArgsD, take_id=None ):
120 120
             multValL.append((out_idx,multi_value_count))
121 121
 
122 122
     if len(multValL) > 0:
123
-        print("Multi-value pulse locations were found during velocity table formation: ",multValL)
123
+        # print("Multi-value pulse locations were found during velocity table formation: ",multValL)
124
+        pass
124 125
 
125 126
     return pulseUsL,pulseDbL
126 127
     
@@ -158,8 +159,18 @@ def merge_close_sample_points( pkDbUsL, minSampleDistanceUs ):
158 159
     return pkDbUsL
159 160
 
160 161
 
162
+def _calc_resample_points( dPkDb, pkUs0, pkUs1, samplePerDb, minSampleDistUs ):
161 163
 
162
-def calc_resample_ranges( pkDbL, pkUsL, min_pk_idx, max_pk_idx, maxDeltaDb, samplePerDb ):
164
+    dPkUs = pkUs1 - pkUs0
165
+    sampleCnt = max(int(round(abs(dPkDb) * samplePerDb)),samplePerDb)
166
+    dUs       = max(int(round(dPkUs/sampleCnt)),minSampleDistUs)
167
+    sampleCnt = int(round(dPkUs/dUs))
168
+    dUs = int(round(dPkUs/sampleCnt))
169
+    usL       = [ pkUs0 + dUs*j  for j in range(sampleCnt+1)]
170
+
171
+    return usL
172
+
173
+def calc_resample_ranges( pkDbL, pkUsL, min_pk_idx, max_pk_idx, maxDeltaDb, samplePerDb, minSampleDistUs ):
163 174
 
164 175
     if min_pk_idx == 0:
165 176
         print("No silent notes were generated.  Decrease the minimum peak level or the hold voltage.")
@@ -180,16 +191,13 @@ def calc_resample_ranges( pkDbL, pkUsL, min_pk_idx, max_pk_idx, maxDeltaDb, samp
180 191
         # it is below the previous max peak
181 192
         if d > maxDeltaDb or d <= 0 or pkDbL[i] < refPkDb:
182 193
 
183
-            sampleCnt = max(int(round(abs(d) * samplePerDb)),samplePerDb)
184
-            dUs       = int(round((pkUsL[i] - pkUsL[i-1])/sampleCnt))
185
-            usL       = [ pkUsL[i-1] + dUs*j  for j in range(sampleCnt)]
186
-
187
-            if i + 1 < len(pkDbL):
194
+            usL = _calc_resample_points( d, pkUsL[i-1], pkUsL[i], samplePerDb, minSampleDistUs )
195
+            
196
+            if d <= 0 and i + 1 < len(pkDbL):
188 197
                 d = pkDbL[i+1] - pkDbL[i]
189
-                
190
-                sampleCnt = max(int(round(abs(d) * samplePerDb)),samplePerDb)
191
-                dUs       = int(round((pkUsL[i+1] - pkUsL[i])/sampleCnt))
192
-                usL      += [ pkUsL[i] + dUs*j  for j in range(sampleCnt)]
198
+
199
+                usL += _calc_resample_points( d, pkUsL[i-1], pkUsL[i], samplePerDb, minSampleDistUs )
200
+
193 201
 
194 202
         if pkDbL[i] > refPkDb:
195 203
             refPkDb = pkDbL[i]
@@ -239,10 +247,12 @@ def form_resample_pulse_time_list( inDir, analysisArgsD ):
239 247
     min_pk_idx, max_pk_idx = find_min_max_peak_index( pkDbL, analysisArgsD['minAttkDb'], analysisArgsD['maxDbOffset'] )    
240 248
 
241 249
     # estimate the microsecond locations to resample
242
-    resampleUsSet = calc_resample_ranges( pkDbL, pkUsL, min_pk_idx, max_pk_idx, analysisArgsD['maxDeltaDb'], analysisArgsD['samplesPerDb'] )
250
+    resampleUsSet = calc_resample_ranges( pkDbL, pkUsL, min_pk_idx, max_pk_idx, analysisArgsD['maxDeltaDb'], analysisArgsD['samplesPerDb'], analysisArgsD['minSampleDistUs'] )
243 251
 
244 252
     resampleUsL = sorted( list(resampleUsSet) )
245 253
 
254
+    #print(resampleUsL)
255
+
246 256
     return resampleUsL, pkDbL, pkUsL
247 257
 
248 258
 
@@ -282,8 +292,8 @@ def find_min_max_peak_index( pkDbL, minDb, maxDbOffs ):
282 292
     for i in range( max_i, 0, -1 ):
283 293
 
284 294
         # if this peak is within maxDbOffs of the loudest then choose this one instead
285
-        if maxDb - yV[i] < maxDbOffs:
286
-            max_i = i
295
+        #if maxDb - yV[i] < maxDbOffs:
296
+        #    max_i = i
287 297
 
288 298
         # if this peak is less than minDb then the previous note is the min note
289 299
         if yV[i] < minDb:
@@ -291,7 +301,10 @@ def find_min_max_peak_index( pkDbL, minDb, maxDbOffs ):
291 301
         
292 302
         min_i = i
293 303
 
294
-    assert( min_i < max_i )
304
+    if min_i >= max_i:
305
+        min_i = 0
306
+        max_i = len(pkDbL)-1
307
+    
295 308
 
296 309
     if min_i == 0:
297 310
         print("No silent notes were generated.  Decrease the minimum peak level or the hold voltage.")
@@ -404,9 +417,9 @@ def plot_spectral_ranges( inDir, pitchL, rmsWndMs=300, rmsHopMs=30, harmN=5, dbR
404 417
 def td_plot( ax, inDir, midi_pitch, id, analysisArgsD ):
405 418
 
406 419
     r = rms_analysis_main( inDir, midi_pitch, **analysisArgsD['rmsAnalysisArgs'] )
407
-    
408
-    min_pk_idx, max_pk_idx = find_min_max_peak_index( r.pkDbL, analysisArgsD['minAttkDb'], analysisArgsD['maxDbOffset'] )    
409 420
 
421
+    min_pk_idx, max_pk_idx = find_min_max_peak_index( r.pkDbL, analysisArgsD['minAttkDb'], analysisArgsD['maxDbOffset'] )    
422
+    
410 423
     skipPkIdxL = find_skip_peaks( r.rmsDbV, r.pkIdxL, min_pk_idx, max_pk_idx )
411 424
 
412 425
     jmpPkIdxL = find_out_of_range_peaks( r.rmsDbV, r.pkIdxL, min_pk_idx, max_pk_idx, analysisArgsD['maxDeltaDb'] )
@@ -423,7 +436,7 @@ def td_plot( ax, inDir, midi_pitch, id, analysisArgsD ):
423 436
         ax.axvline( x=endMs/1000.0, color="red")
424 437
         ax.text(begMs/1000.0, 20.0, str(i) )
425 438
 
426
-    return
439
+
427 440
     # plot peak markers
428 441
     for i,pki in enumerate(r.pkIdxL):
429 442
         marker = 4 if i==min_pk_idx or i==max_pk_idx else 5
@@ -434,18 +447,19 @@ def td_plot( ax, inDir, midi_pitch, id, analysisArgsD ):
434 447
             ax.plot( [pki / r.rms_srate], [ r.rmsDbV[pki] ], marker=6, color="blue")
435 448
 
436 449
 
437
-
450
+    return r
438 451
     
439 452
 def do_td_plot( inDir, analysisArgs ):
440 453
     
441
-    fig,ax = plt.subplots()
454
+    fig,axL = plt.subplots(2,1)
442 455
     fig.set_size_inches(18.5, 10.5, forward=True)
443 456
 
444
-
445 457
     id         = int(inDir.split("/")[-1])
446 458
     midi_pitch = int(inDir.split("/")[-2])
447 459
 
448
-    td_plot(ax,inDir,midi_pitch,id,analysisArgs)
460
+    r = td_plot(axL[0],inDir,midi_pitch,id,analysisArgs)
461
+
462
+    axL[1].plot( r.pkUsL, r.pkDbL, marker='.' )
449 463
 
450 464
     plt.show()
451 465
 
@@ -469,14 +483,17 @@ if __name__ == "__main__":
469 483
 
470 484
     inDir = sys.argv[1]
471 485
     cfgFn = sys.argv[2]
486
+    take_id = None if len(sys.argv)<4 else sys.argv[3]
472 487
 
473 488
     cfg = parse_yaml_cfg( cfgFn )
474
-    
475
-    #do_td_plot(inDir,cfg.analysisArgs)
476 489
 
477
-    #o_td_multi_plot(inDir,cfg.analysisArgs)
490
+    if take_id is not None:
491
+        inDir = os.path.join(inDir,take_id)
492
+        do_td_plot(inDir,cfg.analysisArgs)
493
+    else:    
494
+        #do_td_multi_plot(inDir,cfg.analysisArgs)
478 495
 
479
-    #plot_spectral_ranges( inDir, [ 24, 36, 48, 60, 72, 84, 96, 104] )
496
+        #plot_spectral_ranges( inDir, [ 24, 36, 48, 60, 72, 84, 96, 104] )
480 497
 
481
-    plot_resample_pulse_times( inDir, cfg.analysisArgs )
498
+        plot_resample_pulse_times( inDir, cfg.analysisArgs )
482 499
 

+ 4
- 0
rms_analysis.py Ver arquivo

@@ -148,6 +148,8 @@ def rms_analysis_main( inDir, midi_pitch, rmsWndMs=300, rmsHopMs=30, dbRefWndMs=
148 148
 
149 149
     tdRmsDbV, rms0_srate = audio_rms( srate, sigV, rmsWndMs, rmsHopMs, dbRefWndMs )
150 150
 
151
+    tdPkIdxL = locate_peak_indexes( tdRmsDbV, rms0_srate,  r['eventTimeL'])
152
+    
151 153
     rmsDbV, rms_srate, binHz = audio_harm_rms( srate, sigV, rmsWndMs, rmsHopMs, dbRefWndMs, midi_pitch, harmCandN, harmN  )
152 154
     
153 155
     pkIdxL = locate_peak_indexes( rmsDbV, rms_srate, r['eventTimeL'] )
@@ -155,6 +157,8 @@ def rms_analysis_main( inDir, midi_pitch, rmsWndMs=300, rmsHopMs=30, dbRefWndMs=
155 157
     r = types.SimpleNamespace(**{
156 158
         "audio_srate":srate,
157 159
         "tdRmsDbV": tdRmsDbV,
160
+        "tdPkIdxL": tdPkIdxL,
161
+        "tdPkDbL": [ tdRmsDbV[i] for i in tdPkIdxL ],
158 162
         "binHz": binHz,
159 163
         "rmsDbV":rmsDbV,
160 164
         "rms_srate":rms_srate,

Carregando…
Cancelar
Salvar