Outils pour utilisateurs

Outils du site


reconnaissance_audio

Ceci est une ancienne révision du document !


Test:

      import numpy as np, scipy.signal, glob, subprocess, collections, os, pickle, scipy.io.wavfile
      spectrogram = lambda x: 20 * np.log10(np.abs(scipy.signal.stft(x, nperseg=1024, noverlap=1)[2]))
      A = 0
      def add_constellations(s, hash_table, song_id):
          global A
          global_peaks = []
          for t in range(s.shape[1]):
              peaks, prop = scipy.signal.find_peaks(s[:, t], prominence=10)
              global_peaks += [(t, f) for _, f in sorted(zip(prop["prominences"], peaks), reverse=True)][:4]    
          for i1, (t1, f1) in enumerate(global_peaks):
              for (t2, f2) in global_peaks[i1 + 1:i1 + 20]:
                  delta_t = t2 - t1
                  if delta_t <= 1 or delta_t >= 4:
                      continue
                  h = f1 + (f2 << 8) + (delta_t << 16)
                  hash_table[h].append((t1, song_id) if song_id is not None else t1)
                  A += 1
      def create_library(path, db_filename, FFMPEG_PATH=r"D:\Documents\software\portable\youtube-dl\ffmpeg.exe"):
          hash_table, songs = collections.defaultdict(list), []
          for i, f in enumerate(glob.glob(path)):
              print(f"adding to library: {f}, current size: {len(hash_table)=} {A/(i+1)=:,}")
              songs.append(os.path.basename(f))
              p = subprocess.Popen([FFMPEG_PATH, '-i', f, '-f', 's16le', '-acodec', 'pcm_s16le', '-ar', '44100', '-ac', '1', "-hide_banner", "-loglevel", "fatal", "-"], stdout=subprocess.PIPE, bufsize=10**8)
              x = np.frombuffer(p.communicate()[0], dtype="int16")
              s = spectrogram(x)[:256]
              add_constellations(s, hash_table, i)
              if i == 200:
                  break
          with open(db_filename, "wb") as g:
              pickle.dump({"hash_table": hash_table, "songs": songs}, g)
          print("create_library: finished.")
      def load_library(db_filename="db.db"):
          return pickle.load(open(db_filename, "rb"))
      def recognize(f, db):
          sr, x = scipy.io.wavfile.read(f)
          s = spectrogram(x)
          recording_hash_table = collections.defaultdict(list)
          matches_per_song = collections.defaultdict(list)
          scores = collections.defaultdict(int)    
          add_constellations(s, recording_hash_table, None)
          for h, T in recording_hash_table.items():
              for t1 in T:
                  for (t0, song_id) in db["hash_table"][h]:
                      matches_per_song[song_id].append((h, t1, t0))       
          for song_id, matches in matches_per_song.items():
              song_scores_by_offset = collections.defaultdict(int)
              for h, t1, t0 in matches:
                  song_scores_by_offset[t0 - t1] += 1
              scores[song_id] = max(song_scores_by_offset.items(), key=lambda x: x[1])
          scores = sorted(scores.items(), key=lambda x: x[1][1], reverse=True)
          print(f, db["songs"][scores[0][0]], scores)
      # create_library(r"D:\Documents\mp3\_misc\*.mp3", "misc.db")
      db = load_library("misc.db")
      recognize("test6_ragazzo.wav", db)
reconnaissance_audio.1716479886.txt.gz · Dernière modification : de joseph