infinity-player

infinite jukebox clone using librosa
git clone https://git.ce9e.org/infinity-player.git

commit
8e3bd5f69143ca1bcf70368881a06096183e5301
parent
c08e77e563fbf015b65d6401765935611bd1cd16
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2025-03-06 10:53
refactor

Diffstat

M player.py 32 ++++++++++----------------------

1 files changed, 10 insertions, 22 deletions


diff --git a/player.py b/player.py

@@ -42,9 +42,10 @@ def enhance_diagonals(jumps, weight=0.2, steps=1):
   42    42     return jumps
   43    43 
   44    44 
   45    -1 def iter_beat_slices(beat_frames):
   -1    45 def compute_buffers(y, beat_frames):
   46    46     beat_samples = librosa.frames_to_samples(beat_frames)
   47    -1     yield from zip([0, *beat_samples], [*beat_samples, None])
   -1    47     ranges = zip([0, *beat_samples], [*beat_samples, None])
   -1    48     return [y.T[start:end] for start, end in ranges]
   48    49 
   49    50 
   50    51 def timbre(y):
@@ -63,11 +64,9 @@ def timbre(y):
   63    64     return numpy.linalg.inv(t) @ s
   64    65 
   65    66 
   66    -1 def analyze(y, beat_frames):
   67    -1     tim = numpy.array([
   68    -1         timbre(y[start:end]) for start, end in iter_beat_slices(beat_frames)
   69    -1     ]).T
   70    -1     return librosa.segment.recurrence_matrix(tim, width=4, mode='affinity')
   -1    67 def analyze(buffers):
   -1    68     timbres = numpy.array([timbre(buf) for buf in buffers]).T
   -1    69     return librosa.segment.recurrence_matrix(timbres, width=4, mode='affinity')
   71    70 
   72    71 
   73    72 def load(filename, *, force=False):
@@ -81,23 +80,13 @@ def load(filename, *, force=False):
   81    80         print('Analyzing…')
   82    81         y1, sample_rate1 = librosa.load(filename)
   83    82         tempo, beat_frames = librosa.beat.beat_track(y=y1, sr=sample_rate1)
   84    -1         jumps = analyze(y1, beat_frames)
   -1    83         buffers1 = compute_buffers(y1, beat_frames)
   -1    84         jumps = analyze(buffers1)
   85    85 
   86    86         with gzip.open(path_inf, 'wb') as fh:
   87    87             pickle.dump((beat_frames, jumps), fh)
   88    88 
   89    -1     return y, sample_rate, beat_frames, jumps
   90    -1 
   91    -1 
   92    -1 def compute_buffers(y, beat_frames):
   93    -1     int_max = numpy.iinfo(numpy.int16).max
   94    -1     raw = (y * int_max).astype(numpy.int16).T.copy(order='C')
   95    -1 
   96    -1     buffers = []
   97    -1     for start, end in iter_beat_slices(beat_frames):
   98    -1         buffers.append(y.T[start:end])
   99    -1 
  100    -1     return buffers
   -1    89     return compute_buffers(y, beat_frames), sample_rate, jumps
  101    90 
  102    91 
  103    92 def normalize(jumps, threshold):
@@ -162,9 +151,8 @@ def main():
  162   151     args = parse_args()
  163   152 
  164   153     print('Loading', args.filename)
  165    -1     y, sample_rate, beat_frames, jumps = load(args.filename, force=args.force)
   -1   154     buffers, sample_rate, jumps = load(args.filename, force=args.force)
  166   155     jumps = normalize(jumps, args.threshold)
  167    -1     buffers = compute_buffers(y, beat_frames)
  168   156     jump_count = sum(sum(jumps > 0))
  169   157 
  170   158     print(f'Detected {jump_count} jump opportunities on {len(buffers)} beats')