infinity-player

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

commit
329ce6fc8d157acbf9e35b6c1d3ca6d9c965aa9b
parent
22bb2562f8514741a23c99b33487845c0ce99530
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2025-03-06 09:55
lint

Diffstat

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

1 files changed, 14 insertions, 18 deletions


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

@@ -1,16 +1,16 @@
    1     1 "Play an infinite remix of your favorite songs."
    2     2 
    3    -1 from random import random
    4     3 import argparse
    5     4 import gzip
    6     5 import os
    7     6 import pickle
    8     7 import shutil
   -1     8 from random import random
    9     9 
   10    -1 from PIL import Image
   11    10 import librosa
   12    11 import numpy
   13    12 import soundcard
   -1    13 from PIL import Image
   14    14 
   15    15 BASE_DIR = os.path.dirname(os.path.abspath(__file__))
   16    16 
@@ -34,7 +34,7 @@ def print_progress(i, n):
   34    34 
   35    35 
   36    36 def enhance_diagonals(jumps, weight=0.2, steps=1):
   37    -1     for i in range(steps):
   -1    37     for _ in range(steps):
   38    38         # combine each cell with its diagonal neighbors
   39    39         jumps1 = numpy.roll(jumps, (1, 1), (0, 1))
   40    40         jumps2 = numpy.roll(jumps, (-1, -1), (0, 1))
@@ -45,8 +45,7 @@ def enhance_diagonals(jumps, weight=0.2, steps=1):
   45    45 def iter_beat_slices(y, beat_frames):
   46    46     beat_samples = librosa.frames_to_samples(beat_frames)
   47    47     beat_samples = [0, *beat_samples, len(y) - 1]
   48    -1     for start, end in zip(beat_samples[0:-1], beat_samples[1:]):
   49    -1         yield start, end
   -1    48     yield from zip(beat_samples[0:-1], beat_samples[1:])
   50    49 
   51    50 
   52    51 def timbre(y):
@@ -54,15 +53,15 @@ def timbre(y):
   54    53     resized = numpy.array(Image.fromarray(spectrum).resize((70, 50)))
   55    54 
   56    55     k = len(TIMBRE_PATTERNS)
   57    -1     T = numpy.zeros((k, k))
   -1    56     t = numpy.zeros((k, k))
   58    57     s = numpy.zeros((k, 1))
   59    58 
   60    59     for i, pattern in enumerate(TIMBRE_PATTERNS):
   61    60         s[i][0] = numpy.sum(TIMBRE_PATTERNS[i] * resized)
   62    61         for j, pattern2 in enumerate(TIMBRE_PATTERNS):
   63    -1             T[i][j] = numpy.sum(pattern * pattern2)
   -1    62             t[i][j] = numpy.sum(pattern * pattern2)
   64    63 
   65    -1     return numpy.linalg.inv(T) @ s
   -1    64     return numpy.linalg.inv(t) @ s
   66    65 
   67    66 
   68    67 def analyze(y, sample_rate, beat_frames, bins_per_octave=12, n_octaves=7):
@@ -78,7 +77,7 @@ def analyze(y, sample_rate, beat_frames, bins_per_octave=12, n_octaves=7):
   78    77     return librosa.segment.recurrence_matrix(tim, width=4, mode='affinity')
   79    78 
   80    79 
   81    -1 def load(filename, force=False):
   -1    80 def load(filename, *, force=False):
   82    81     y, sample_rate = librosa.load(filename, mono=False)
   83    82 
   84    83     fn_inf = filename + '.inf'
@@ -124,11 +123,11 @@ def normalize(jumps, threshold):
  124   123     jumps *= numpy.ones((n, n)) - numpy.tri(n, k=-1).T * 0.5
  125   124 
  126   125     # privilege wide jumps
  127    -1     M = numpy.zeros((n, n))
   -1   126     m = numpy.zeros((n, n))
  128   127     for i in range(1, n):
  129    -1         M += numpy.tri(n, k=-i)
  130    -1         M += numpy.tri(n, k=-i).T
  131    -1     jumps *= (M / (n - 1)) ** 0.4
   -1   128         m += numpy.tri(n, k=-i)
   -1   129         m += numpy.tri(n, k=-i).T
   -1   130     jumps *= (m / (n - 1)) ** 0.4
  132   131 
  133   132     return jumps
  134   133 
@@ -170,15 +169,12 @@ def main():
  170   169     args = parse_args()
  171   170 
  172   171     print('Loading', args.filename)
  173    -1     y, sample_rate, beat_frames, jumps = load(args.filename, args.force)
   -1   172     y, sample_rate, beat_frames, jumps = load(args.filename, force=args.force)
  174   173     jumps = normalize(jumps, args.threshold)
  175   174     buffers = compute_buffers(y, beat_frames)
  176   175     jump_count = sum(sum(jumps > 0))
  177   176 
  178    -1     print('Detected {} jump opportunities on {} beats'.format(
  179    -1         jump_count, len(buffers)
  180    -1     ))
  181    -1 
   -1   177     print(f'Detected {jump_count} jump opportunities on {len(buffers)} beats')
  182   178     print('Playing… (Press Ctrl-C to stop)')
  183   179     play(buffers, sample_rate, jumps)
  184   180