1
- _VERSION = '0.7.0 '
1
+ _VERSION = '0.7.1 '
2
2
3
3
from collections .abc import Container
4
4
import csv
@@ -226,6 +226,7 @@ def plot_fingerprint(fingerprint, target_axes, **kwargs):
226
226
frequencies_kHz = fingerprint ['frequencies' ]
227
227
acc = fingerprint ['freq_domain' ]
228
228
digest = fingerprint ['beat_digest' ]
229
+ beat_indices = fingerprint ['beat_indices' ]
229
230
sync_bias = fingerprint ['bias_result' ]
230
231
post_kernel_flat = fingerprint ['convolution' ]
231
232
post_kernel = fingerprint ['post_kernel' ]
@@ -236,7 +237,8 @@ def plot_fingerprint(fingerprint, target_axes, **kwargs):
236
237
hide_yticks = kwargs .get ('hide_yticks' , False )
237
238
238
239
edge_discard = 5 # TODO: pull in from calling function I guess
239
- digest_axis = np .arange (digest .shape [0 ])
240
+ if beat_indices is None :
241
+ beat_indices = np .arange (digest .shape [0 ])
240
242
241
243
time_ticks = np .hstack ((
242
244
np .arange (0 , times_ms [ 0 ], - 10 ),
@@ -261,8 +263,8 @@ def plot_fingerprint(fingerprint, target_axes, **kwargs):
261
263
post_kernel_flat [edge_discard :- edge_discard ].max ()
262
264
),
263
265
(
264
- digest . shape [ 0 ] * 0.2 ,
265
- digest . shape [ 0 ] * 0.8
266
+ beat_indices . min () * 0.9 + beat_indices . max () * 0.1 ,
267
+ beat_indices . min () * 0.1 + beat_indices . max () * 0.9
266
268
))
267
269
268
270
# Accumulator in frequency domain
@@ -282,12 +284,12 @@ def plot_fingerprint(fingerprint, target_axes, **kwargs):
282
284
# Digest in beat domain
283
285
ax = target_axes [1 ]
284
286
ax .clear ()
285
- pcm = ax .pcolormesh (times_ms , digest_axis , digest )
287
+ pcm = ax .pcolormesh (times_ms , beat_indices , digest )
286
288
pcm .set_clim (np .percentile (digest [:], 10 ), np .percentile (digest [:], 90 ))
287
289
ax .set_ylabel ('Beat Index' )
288
290
ax .set_xlabel ('Time [msec]' )
289
291
ax .plot (times_ms + magic_offset_ms , post_kernel_over_beat , 'w-' )
290
- ax .plot (beatindex_line , digest_axis , 'r-' )
292
+ ax .plot (beatindex_line , beat_indices , 'r-' )
291
293
ax .set_xticks (time_ticks )
292
294
if hide_yticks :
293
295
ax .set_yticks ([])
@@ -303,10 +305,10 @@ def plot_fingerprint(fingerprint, target_axes, **kwargs):
303
305
ax .plot (times_ms + magic_offset_ms , post_kernel_over_freq , 'w-' )
304
306
ax .plot (frequency_line , frequencies_kHz , 'r-' )
305
307
else : # kernel_target == KernelTarget.DIGEST
306
- pcm = ax .pcolormesh (times_ms , digest_axis , post_kernel )
308
+ pcm = ax .pcolormesh (times_ms , beat_indices , post_kernel )
307
309
ax .set_ylabel ('Beat Index' )
308
310
ax .plot (times_ms + magic_offset_ms , post_kernel_over_beat , 'w-' )
309
- ax .plot (beatindex_line , digest_axis , 'r-' )
311
+ ax .plot (beatindex_line , beat_indices , 'r-' )
310
312
pcm .set_clim (np .percentile (post_kernel [:], 3 ), np .percentile (post_kernel [:], 97 ))
311
313
ax .set_xlabel ('Time [msec]' )
312
314
ax .set_xticks (time_ticks )
@@ -326,6 +328,7 @@ def get_full_title(base_simfile):
326
328
def check_sync_bias (simfile_dir , base_simfile , chart_index = None , report_path = None , save_plots = True , show_intermediate_plots = False , ** kwargs ):
327
329
fingerprint = {
328
330
'beat_digest' : None , # Beat digest fingerprint (beat index vs. time)
331
+ 'beat_indices' : None , # Beat indices that contributed to the digest
329
332
'freq_domain' : None , # Accumulation in frequency domain (frequency vs. time)
330
333
'post_kernel' : None , # Post-kernel
331
334
'bias_result' : None , # Scalar value result of the bias analysis
@@ -364,7 +367,9 @@ def check_sync_bias(simfile_dir, base_simfile, chart_index=None, report_path=Non
364
367
# Account for stereo audio and normalize
365
368
# https://stackoverflow.com/questions/53633177/how-to-read-a-mp3-audio-file-into-a-numpy-array-save-a-numpy-array-to-mp3
366
369
if audio .channels == 2 :
367
- audio_data = audio_data .reshape ((- 1 , 2 ))
370
+ #audio_data = audio_data.reshape((-1, 2)).sum(1) * 0.5 # Reshape to stereo and average the two channels
371
+ #audio_data = audio_data.reshape((-1, 2))[:, 0].flatten() # Pull mono only
372
+ audio_data = audio_data .reshape ((- 1 , 2 )).max (1 ) # Reshape to stereo and average the two channels
368
373
audio_data = audio_data / 2 ** 15
369
374
370
375
###################################################################
@@ -400,7 +405,7 @@ def check_sync_bias(simfile_dir, base_simfile, chart_index=None, report_path=Non
400
405
if full_spectrogram :
401
406
# print(f'audio: {audio_data.shape}, nperseg: {nperseg}, noverlap: {noverlap}, actual_step: {actual_step}, n_spectral_taps: {n_time_taps}, n_freq_taps: {n_freq_taps}')
402
407
frequencies , times , spectrogram = signal .spectrogram (
403
- audio_data [:, 0 ], # Mono left channel please
408
+ audio_data [:],
404
409
fs = audio .frame_rate ,
405
410
window = 'hann' ,
406
411
nperseg = nperseg ,
@@ -433,6 +438,8 @@ def check_sync_bias(simfile_dir, base_simfile, chart_index=None, report_path=Non
433
438
# For each beat in the song that has a full
434
439
# fingerprint's width of surrounding audio data:
435
440
b = 0
441
+ beat_indices = []
442
+ t_last = - np .inf
436
443
while True :
437
444
t = engine .time_at (b )
438
445
b += 1
@@ -442,6 +449,10 @@ def check_sync_bias(simfile_dir, base_simfile, chart_index=None, report_path=Non
442
449
if (t > audio .duration_seconds ):
443
450
# Too late
444
451
break
452
+ if (t - t_last < fingerprint_ms * 1e-3 ):
453
+ # Too soon
454
+ continue
455
+ t_last = t
445
456
446
457
# Because the spectrogram doesn't "start" until a full window is in view,
447
458
# it has an inherent offset that amounts to half a window.
@@ -467,7 +478,7 @@ def check_sync_bias(simfile_dir, base_simfile, chart_index=None, report_path=Non
467
478
# print(f't_sample: {t_sample_s}:{t_sample_f}')
468
479
469
480
frequencies , times , spectrogram = signal .spectrogram (
470
- audio_data [t_sample_s :t_sample_f , 0 ], # Mono left channel please
481
+ audio_data [t_sample_s :t_sample_f ],
471
482
fs = audio .frame_rate ,
472
483
window = 'hann' ,
473
484
nperseg = nperseg ,
@@ -486,6 +497,7 @@ def check_sync_bias(simfile_dir, base_simfile, chart_index=None, report_path=Non
486
497
# Accumulate, and add to digest
487
498
acc += spfilt [:n_freq_taps , :]
488
499
digest = np .vstack ([digest , np .sum (spfilt , axis = 0 )])
500
+ beat_indices .append (b - 1 )
489
501
490
502
491
503
###################################################################
@@ -543,6 +555,7 @@ def check_sync_bias(simfile_dir, base_simfile, chart_index=None, report_path=Non
543
555
chart_tag = ' ' + slot_abbreviation (chart ['STEPSTYPE' ], chart ['DIFFICULTY' ], chart_index = chart_index , paradigm = guess_paradigm (sync_bias_ms , ** kwargs ))
544
556
fingerprint ['sample_rate' ] = audio .frame_rate
545
557
fingerprint ['beat_digest' ] = digest
558
+ fingerprint ['beat_indices' ] = np .array (beat_indices )
546
559
fingerprint ['freq_domain' ] = acc
547
560
fingerprint ['post_kernel' ] = post_kernel
548
561
fingerprint ['convolution' ] = post_kernel_flat
0 commit comments