Что такое ЗВУК?
Согласно Википедии, звук — это вибрация, которая распространяется в виде акустической волны через передающую среду, такую как газ, жидкость или твердое тело. В физиологии и психологии человека звук — это прием таких волн и их восприятие мозгом.
Чтобы начать с обработки звука в Python, ознакомьтесь со статьей: https://medium.com/comet-ml/applyingmachinelearningtoaudioanalysis-utm-source-kdnuggets11-19-e160b069e88.
Что такое частота?
Частота – это измерение количества повторений события в единицу времени. Частота волнообразных структур, включая звук, электромагнитные волны (такие как радио или свет), электрические сигналы или другие волны, выражает количество циклов повторяющейся формы волны в секунду, здесь мы имеем дело с только звуковая частота.
Что такое основная частота?
Основная частота или F0 — это частота, с которой голосовые связки вибрируют при произнесении звонких звуков. Эта частота может быть определена в воспроизводимом звуке, это будет одним из наших основных параметров для расчета ближайшего звука.
Случаи использования основной частоты:
*Основная частота является надежной характеристикой речевого сигнала. Он обеспечивает основу для группировки компонентов речи по частоте и во времени, чтобы сигнализировать об их происхождении в одной и той же гортани и голосовом тракте. Изменение основной частоты также лежит в основе просодической структуры речи и помогает слушателям выбирать между альтернативными интерпретациями высказываний, когда они частично маскируются другими звуками.
*Основная частота тесно связана с высотой, которая определяется как наше восприятие основной частоты. То есть F0 описывает фактическое физическое явление, тогда как высота тона описывает, как наши уши и мозг интерпретируют сигнал с точки зрения периодичности.
Для получения более подробных сведений и визуализации посетите: https://ccrma.stanford.edu/~pdelac/154/m154paper.htm
Что такое поле?
высота тона относится к тому, как наше ухо и мозг воспринимают основную частоту.
Загрузка аудио:
Мы используем пакет librosa для загрузки аудиофайла.
Подробнее о librosa читайте здесь: https://librosa.org/doc/latest/index.html
Прочитайте о librosa.load здесь: https://librosa.org/doc/main/generated/librosa.load.html
audio здесь - это временной ряд аудио для audio_file, sr обозначает частоту дискретизации audio_file.
Аудио временной ряд:
Аудио звуки можно рассматривать как одномерный вектор, в котором хранятся числовые значения, соответствующие каждому семплу. График временных рядов представляет собой двумерный график этих выборочных значений как функцию времени.
Частота дискретизации звуковой волны:
Частота дискретизации или частота дискретизации определяет количество выборок в секунду (или на другую единицу), взятых из непрерывного сигнала для создания дискретного или цифрового сигнала.
Алгоритмы поиска:
# Частота (средняя частота) данного аудиофайла:
1. Креп (сверточное представление для оценки высоты тона)
Подробнее о крепе: https://github.com/marl/crepe
Использовал Crepe, чтобы получить ряд частот аудиофайла, а затем использовал встроенную среднюю функцию библиотеки numpy, чтобы получить среднюю частоту звука.
Код:
импортный креп
импортировать numpy как np
импортная либроса
def run_crepe (аудио_файл):
аудио, sr = librosa.load (аудио_файл, sr = нет)
время, Frequency_crepe, достоверность, активация = crepe.predict (аудио, ср, Витерби = Истина)
результат_креп = {
«время»: время,
«частота_креп»: частота_креп,
«другие»: нет
}
вернуть результат_креп
Код:
из импорта crepe_pitch *
result_crepe=run_crepe("mySample.wav")
freq=result_crepe.get("frequency_crepe")
частота=частота[частота›70]
частота = гладкая (частота, 30)
mean_freq_crepe=np.mean(частота)
print("Средняя частота от крепа: ", mean_freq_crepe)
#сюжет
plt.plot(freq, label='Креп', color='синий')
Использована функция сглаживания для уменьшения шума, производимого на графике.
Код:
def smooth(y, box_pts):
коробка = np.ones(box_pts)/box_pts
y_smooth = np.convolve(y, box, mode='same')
вернуть y_smooth
#Основная частота (средняя) или F0 аудиофайла:
1.ИНЬ
Подробнее об YIN: https://medium.com/@neurodatalab/pitch- отслеживание-или- как-оценить-фундаментальные -частота-в-речи- на-примерах-праата- fe0ca50f61fd
ИНЬ: https://librosa.org/doc/main/generated/librosa.yin.html
Здесь мы использовали YIN для расчета основной частоты звука.
Прочитайте о librosa.yin здесь: https://librosa.org/doc/main/generated/librosa.yin.html
Код:
def run_YIN (аудио_файл):
аудио, sr = librosa.load (аудио_файл, sr = нет)
fun_frequencies_using_yin = librosa.yin (аудио, 75 600, ср)
вернуть fun_frequencies_using_yin
Код:
def run_YIN (аудио_файл):
аудио, sr = librosa.load (аудио_файл, sr = нет)
fun_frequencies_using_yin = librosa.yin (аудио, 75 600, ср)
вернуть fun_frequencies_using_yin
Код:
ffreq_YIN=run_YIN("mySample.wav")
ffreq_YIN=ffreq_YIN[ffreq_YIN›70]
ffreq_YIN=гладкий(ffreq_YIN,30)
mean_ffreq_YIN=np.mean(ffreq_YIN)
print("Средняя основная частота YIN равна ", mean_ffreq_YIN)
#Расчет высоты звука для заданного звука:
1 YAAPT (еще один алгоритм отслеживания высоты тона)
Прочитайте о YAAPT здесь: https://medium.com/@neurodatalab/pitch-tracking-or-how-to-estimate-the-fundamental-frequency-in-speech- на-примерах-праата-fe0ca50f61fd
YAAPT: http://bjbschmitt.github.io/AMFM_decompy/pYAAPT.html
Мы используем YAAPT, чтобы найти среднюю высоту звука данного аудиофайла.
Код:
импортная либроса
импортировать numpy как np
импортировать amfm_decompy.basic_tools как основной
импортировать amfm_decompy.pYAAPT как pYAAPT
#ЯАПТ
def run_YAAPT (аудио_файл):
# загрузить аудио
signal = basic.SignalObj(аудио_файл)
# поля YAAPT
pitch_YAAPT = pYAAPT.yaapt(сигнал, frame_length=40, tda_frame_length=40, f0_min=75, f0_max=600)
вернуть питч_YAAPT
Код:
pitch_YAAPT=run_YAAPT("mySample.wav")
pitch_YAAPT.samp_values=pitch_YAAPT.samp_values[pitch_YAAPT.samp_values›70]
pitch_YAAPT=гладкий(pitch_YAAPT.samp_values,30)
средний_шаг_YAAPT=np.mean(шаг_YAAPT)
print("Средний шаг YAAAPT равен ", mean_ffreq_YIN)
2.spice v2
Модель SPICE состоит из сверточного кодировщика, который создает одно скалярное вложение, которое линейно отображается в высоту тона.
Подробнее о spice v2: https://ai.googleblog.com/2019/11/spice-self-supervised-pitch-estimation.html
Прочитайте о реализации spice v2 здесь:
Код:
импортировать tensorflow_hub как концентратор
импортировать тензорный поток как tf
импортировать numpy как np
импортная либроса
def run_SPICE_v2 (аудио_файл):
модель = hub.load("https://tfhub.dev/google/spice/2)
аудио, sr = librosa.load (аудио_файл, sr = нет)
защита get_pitch_spice (аудио):
аудио = аудио/np.power(2,16)
вывод = model.signatures["serving_default"](tf.constant(аудио, tf.float32))
высота тона = вывод[«шаг»]
неопределенность_выходов = вывод[«неопределенность»]
trust_outputs = 1.0 — неопределенность_выходов
вернуть trust_outputs
def output2hz (pitch_output):
# Калибровочные константы
PT_OFFSET = 25,58
PT_SLOPE = 63,07
ФМИН = 10,0
BINS_PER_OCTAVE = 12,0
cqt_bin = pitch_output * PT_SLOPE + PT_OFFSET;
вернуть FMIN * 2.0 ** (1.0 * cqt_bin/BINS_PER_OCTAVE)
sure_pitch_values_hz_SPICEV2 = [ output2hz(p) для p в get_pitch_spice(аудио)]
sure_pitch_values_hz_SPICEV2 = np.array (confident_pitch_values_hz_SPICEV2)
Вернуть уверенно_pitch_values_hz_SPICEV2
Код:
импорт из spice_v2 *
pitch_spice=run_SPICE_v2("mySample.wav")
#threshold=np.ones(len(pitch_spice))*70
temp=pitch_spice[pitch_spice›70]
pitch_spice = гладкий (температура, 30)
mean_pitch_spice=np.mean(pitch_spice)
print("Средний шаг из spiceV2 равен ", mean_pitch_spice)
#сюжет
plt.plot(pitch_spice, метка='SpiceV2', цвет='красный')
Код для реализации их всех вместе и сохранения результата в кадре данных:
Код:
def audio_param (имя файла, аудио, частота дискретизации):
время, Frequency_crepe, достоверность, активация = crepe.predict (аудио, частота дискретизации, viterbi = True)
mean_freq_crepe = np.mean (частота_крепа)
защита get_pitch_spice (аудио):
аудио = аудио/np.power(2,16)
вывод = model.signatures["serving_default"](tf.constant(аудио, tf.float32))
высота тона = вывод[«шаг»]
неопределенность_выходов = вывод[«неопределенность»]
trust_outputs = 1.0 — неопределенность_выходов
вернуть trust_outputs
def output2hz (pitch_output):
# Калибровочные константы
PT_OFFSET = 25,58
PT_SLOPE = 63,07
ФМИН = 10,0
BINS_PER_OCTAVE = 12,0
cqt_bin = pitch_output * PT_SLOPE + PT_OFFSET;
вернуть FMIN * 2.0 ** (1.0 * cqt_bin/BINS_PER_OCTAVE)
sure_pitch_values_hz_SPICEV2 = [ output2hz(p) для p в get_pitch_spice(аудио)]
mean_pitch_SPICE=np.mean(confident_pitch_values_hz_SPICEV2)
fun_frequencies_using_yin=librosa.yin(аудио,75,600,sampling_rate)
mean_ffreq_yin=np.mean(fun_frequencies_using_yin)
def pYAAT_pitch (имя файла):
# загрузить аудио
signal = basic.SignalObj(имя файла)
# поля YAAPT
pitchY = pYAAPT.yaapt (сигнал, длина кадра = 40, длина кадра_tda = 40, f0_min = 75, f0_max = 600)
mean_pitch_YAAPT = np.mean (pitchY.samp_values)
вернуть средний_шаг_YAAPT
mean_pitch_YAAPT=pYAAT_pitch(имя файла)
вернуть mean_freq_crepe,mean_pitch_SPICE,mean_ffreq_yin,mean_pitch_YAAPT
Скорость речи:
Это алгоритмы, которые мы использовали для вычисления средней частоты, средней основной частоты и среднего тона.
Теперь мы рассчитываем скорость речи, которая относится к среднему количеству символов в секунду данного аудио.
Мы используем алгоритм преобразования речи в текст (который не может быть раскрыт), но вы можете использовать функцию распознавания речи, встроенную в Python, для преобразования речи в текст и определения среднего количества символов в секунду.
Подробнее о распознавании речи: https://pypi.org/project/SpeechRecognition/2.1.3/
Код:
def input_file_speaking_rate (имя файла):
г = ср.Распознаватель()
# открыть файл
с sr.AudioFile(имя файла) в качестве источника:
# прослушать данные (загрузить аудио в память)
audio_data = r.record (источник)
# распознать (преобразовать речь в текст)
текст = r.recognize_google(аудио_данные)
время = librosa.get_duration (имя файла = имя файла)
avg_character_per_second=длина(текст)/время
вернуть avg_character_per_second
Мы определяем функцию для расчета 30 ближайших аудиофайлов с точки зрения средней скорости речи, потому что даже если для файла все параметры близки к данному файлу, но скорость речи отличается, они будут звучать очень по-разному и будут иметь разную продолжительность в результате. в рассинхрон.
Мы сохраняем результат в новом фрейме данных.
Код:
ближайший_30_аудио=[]
ближайший_30_audio_names=[]
def ближайший_30_speaking_rate (имя файла):
my_speaking_rate=input_file_speaking_rate(имя файла)
avg_character_per_sec=df['avg_character_per_sec'].to_numpy()
avg_character_per_sec=(avg_character_per_sec-my_speaking_rate)**2
avg_character_per_sec=np.argsort(avg_character_per_sec)
ближайший_30_аудио=средний_символ_в_сек[0:30]
ближайший_30_аудио=ближайший_30_аудио.tolist()
для я в диапазоне (30):
ближайший_30_аудио [я] = целое (ближайший_30_аудио [я])
ближайший_средний_символ_за_сек=целое(ближайший_30_аудио[i])
Nearest_30_audio_names.append(df.iloc[closest_avg_character_per_sec]['файл'])
возврат ближайших_30_аудио_имен
N Ближайший звук на основе различных параметров:
Теперь мы определяем функцию, которая принимает евклидово расстояние каждого параметра (средняя частота, средняя основная частота, средний шаг) входного файла с уже доступными аудиофайлами в фрейме данных (ближайшие аудиофайлы с точки зрения скорости речи). Мы возвращаем словарь со списком из n (здесь 4) ближайших аудио по каждому параметру.
Код:
def ближайший_audio_wrt_speaking_rate (имя файла):
my_sr,my_audio=read_audio_file(имя файла)
my_mean_freq_crepe, my_mean_pitch_SPICE, my_mean_ffreq_yin, my_mean_pitch_YAAPT = audio_param (имя файла, my_audio, my_sr)
mean_freq_crepe=df_input[‘mean_freq_crepe’].to_numpy()
средний_шаг_SPICE=df_input['средний_шаг_SPICE'].to_numpy()
mean_ffreq_yin=df_input[‘mean_ffreq_yin’].to_numpy()
средний_шагYAAPT=df_input['средний_шагYAAPT'].to_numpy()
mean_freq_crepe=(mean_freq_crepe-my_mean_freq_crepe)**2
средний_шаг_SPICE=(средний_шаг_SPICE-мой_средний_шаг_SPICE)**2
mean_ffreq_yin=(mean_ffreq_yin-my_mean_ffreq_yin)**2
средний_шагYAAPT=(средний_шагYAAPT-мой_средний_шаг_YAAPT)**2
mean_freq_crepe = np.argsort (mean_freq_crepe)
mean_pitch_SPICE=np.argsort(mean_pitch_SPICE)
mean_ffreq_yin=np.argsort(mean_ffreq_yin)
mean_pitchYAAPT=np.argsort(mean_pitchYAAPT)
ближайший_mean_freq_crepe=[]
ближайший_средний_шаг_SPICE=[]
ближайший_mean_ffreq_yin=[]
ближайший_средний_шагYAAPT=[]
audio_through_crepe=[]
audio_through_spice=[]
audio_through_yin=[]
audio_through_YAAPT=[]
для я в диапазоне (4):
ближайшая_mean_freq_crepe.append(mean_freq_crepe[i])
ближайший_средний_шаг_SPICE.append(средний_шаг_SPICE[i])
ближайший_mean_ffreq_инь.append(mean_ffreq_инь[i])
ближайший_средний_шагYAAPT.append(средний_шагYAAPT[i])
audio_through_crepe.append(df.iloc[ближайшая_средняя_частота_crepe[i]][‘файл’])
audio_through_spice.append(df.iloc[ближайший_средний_шаг_SPICE[i]][‘файл’])
audio_through_yin.append(df.iloc[ближайший_mean_ffreq_yin[i]][‘файл’])
audio_through_YAAPT.append(df.iloc[ближайший_средний_шагYAAPT[i]][‘файл’])
результаты={
«audio_through_crepe»: аудио_через_креп,
«аудио_через_спайс»: аудио_через_спайс,
«аудио_через_инь»: аудио_через_инь,
«аудио_через_YAAPT»: аудио_через_YAAPT
}
возвращать результаты
Это все ЛЮДИ! Надеюсь, вы нашли что-то полезное.
Это мой первый технический блог, прошу меня извинить за ошибки. Я напишу еще один блог, связанный с этой темой, где мы узнаем скорость речи с точки зрения фонем, а не скорости символов, скорость фонемы намного точнее и дает лучшие результаты при тестировании.