Последние несколько дней были заняты - но начали разбираться с этим сегодня ...
Наверное, потребуется некоторое время, чтобы совершенствоваться, но я подумал, что дам вам несколько мыслей и некоторый кодЯ начал работать над тем, чтобы атаковать это!
Во-первых, псевдокод - это хороший способ разработать первоначальный метод.
1 / использовать import matplotlib.pyplot as plt
для спектрального анализа звука и построения различных графиков. fft и аудиосигналы.
2 / import numpy as np
для базовой обработки массивов.
(я знаю, что это больше, чем псевдокод, но эй: -)
3 / plt.specgram
создает спектральные карты вашего аудио. Помимо создаваемого изображения (которое можно использовать для начала ручной деконструкции вашего аудиофайла), он возвращает 4 структуры.
Например,
ffts,freqs,times,img = plt.specgram(signal,Fs=44100)
ffts
- это двумерный массив, в котором столбцы представляют собой ffts
(быстрые преобразования Фурье) временных отрезков (строк).
Простой ваниль specgram
анализирует временные отрезки длиной 256 выборок с шагом 128 выбороквперед каждый раз.
Это дает очень низкое разрешение частотного массива с довольно высокой скоростью.
Поскольку музыкальные ноты сливаются в один звук при воспроизведении с более или менее 10 Гц, я решилиспользуйте параметры specgram
, чтобы разделить звук на 4096 сэмплов (около 10 Гц), шагая вперед каждые 2048 сэмплов (т.е. 20 раз в секунду).
Это дает приемлемое разрешение по частоте, а временные отрезки составляютРазнесение на 20 секунд быстрее, чем люди могут воспринимать отдельные заметки.
Это означает, что specgram
следует вызывать следующим образом:
plt.specgram(signal,Fs=44100,NFFT=4096,noverlap=2048,mode='magnitude')
(Обратите внимание на режим - thПохоже, что это дает мне амплитуды в диапазоне от 0 до 0,1: у меня проблема с fft
, не давая мне амплитуды той же шкалы, что и аудиосигнал (возможно, вы видели вопрос, который я разместил). Но вот мы ...
4 / Далее я решил избавиться от шума в вернувшихся ffts
. Это означает, что мы можем сконцентрироваться на freqs
приличной амплитуды и обнулить шум, который всегда присутствует в ffts
(по моему опыту).
Вот мои функции:
def gate(signal,minAmplitude):
return np.array([int((((a-minAmplitude)+abs(a-minAmplitude))/2) > 0) * a for a in signal])
Выглядит немного сумасшедшим - и я уверен, что настоящий математик мог бы придумать что-то более эффективное - но это лучшее, что я мог придумать. Он обнуляет любые частоты амплитуды, меньшие minAmplitude
.
. Это соответствующий код для вызова из ffts
, возвращаемого plt.specgram
следующим образом, моя функция более сложна, так как является частьюкласс, и имеет другие функции, на которые он ссылается - но этого должно быть достаточно:
def fft_noise_gate(minAmplitude=0.001,check=True):
'''
zero the amplitudes of frequencies
with amplitudes below minAmplitude
across self.ffts
check - plot middle fft just because!
'''
nffts = ffts.shape[1]
gated_ffts = []
for f in range(nffts):
fft = ffts[...,f]
# Anyone got a more efficient noise gate formula? Best I could think up!
fft_gated = gate(fft,minAmplitude)
gated_ffts.append(fft_gated)
ffts = np.array(gated_ffts)
if check:
# plot middle fft just to see!
plt.plot(ffts[int(nffts/2)])
plt.show(block=False)
return ffts
Это должно дать вам начало, я все еще работаю над ним и вернусь к вам, когда я буду дальше -но если у вас есть какие-либо идеи, пожалуйста, поделитесь ими.
В любом случае моя стратегия заключается в следующем:
1 / найти пики (то есть начало любых звуков), затем 2 / Искать диапазонычастот, которые поднимаются и опускаются в унисон (т. е. издают звук).
и
3 / Дифференцируйте их на отдельные инструменты (в частности, источники звука) и нанесите график времени и амплитудсоздать свой анализ (оценка).
Надеюсь, вам весело с ним - я знаю, что я.
Как я уже говорил любые мысли ...
С уважением
Тони