Advertisement
GeorgiLukanov87

audio-rithm

Aug 2nd, 2024 (edited)
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.90 KB | None | 0 0
  1. from pydub import AudioSegment
  2. import numpy as np
  3. from scipy.signal import find_peaks
  4. import matplotlib.pyplot as plt
  5.  
  6. audio = AudioSegment.from_file('file_example_MP3_2MG.mp3', format='mp3')
  7. # audio = AudioSegment.from_file('heartbeat-03.mp3', format='mp3')
  8.  
  9. samples = np.array(audio.get_array_of_samples())
  10. """
  11. Семплите са дискретни измервания на амплитудата на аудио сигнал, направени на равни интервали във времето. Те
  12. представляват цифровото "превод" на аналоговия звук. Честотата на семплиране определя колко семпла се вземат за
  13. секунда (например 44100 Hz). Всеки семпъл е числова стойност, представяща силата на звука в конкретен момент. В
  14. цифровата обработка на аудио, семплите са основните градивни елементи, позволяващи манипулация,
  15. анализ и възпроизвеждане на звук в компютърните системи.
  16. """
  17.  
  18. # Ако аудиото е стерео, раздели на два канала
  19. if audio.channels == 2:
  20.     samples = samples.reshape((-1, 2))
  21.  
  22. # Конвертиране на стерео аудио към моно ако е нужно
  23. if samples.ndim == 2:
  24.     samples = samples.mean(axis=1)
  25.  
  26. # Намиране на пикове
  27. peaks, _ = find_peaks(samples, height=0.6 * np.max(samples), distance=audio.frame_rate / 2)
  28.  
  29. """"
  30. find_peaks() е функция, която открива локални максимуми (пикове) в едномерен масив
  31. В контекста на аудио сигнал, тези пикове могат да представляват ударите на сърцето
  32.  
  33. Параметърът height определя минималната амплитуда = 60% или 0.6, която се счита за пик
  34.  
  35. Параметърът distance (не се прилага в секунди, а в брой семпли.)
  36. Гарантира, че пиковете са разделени от минимално разстояние, което помага да се избегнат фалшиви детекции
  37. """
  38.  
  39. # Конвертиране на пиковете в секунди
  40. times = peaks / audio.frame_rate
  41.  
  42. print('Ритъм (в секунди):\n', times)
  43.  
  44. # Ако numpy array е бил моно, конвертирай обратно към стерео
  45. if samples.ndim == 1:
  46.     samples = np.column_stack([samples, samples])
  47.  
  48. # Получаване на sample_width от оригиналния аудио файл
  49. sample_width = audio.sample_width
  50.  
  51. # Конвертиране на numpy array към pydub аудио сегмент
  52. new_audio = AudioSegment(
  53.     samples.tobytes(),
  54.     frame_rate=audio.frame_rate,
  55.     sample_width=sample_width,
  56.     channels=samples.shape[1]
  57. )
  58.  
  59. # Запис на аудио сегмента като WAV файл
  60. new_audio.export('output_audio.wav', format='wav')
  61.  
  62. # конвертирай WAV към MP3
  63. # !ffmpeg -i output_audio.wav output_audio.mp3
  64.  
  65. # графика амплитудата на сигнала във времето с маркирани пикове
  66. plt.plot(samples)
  67. plt.plot(peaks, samples[peaks], "x",color = 'blue')
  68. for peak in peaks:
  69.     plt.axvline(x=peak,
  70.                 color='green')
  71. plt.show()
  72.  
  73. print()
  74. average_time_between_beats = np.mean(np.diff(times))
  75. bpm = 60 / average_time_between_beats
  76. print(f"Средно BPM: {bpm}")
  77.  
  78. # Изчислете стандартното отклонение на времето между ударите.
  79. beat_variation = np.std(np.diff(times))
  80. print(f"Вариация в ритъма: {beat_variation} секунди")
  81.  
  82.  
  83.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement