Как получить результаты, аналогичные pydub.silence.detect_nonsilent (), используя librosa.effects.split ()? - PullRequest
0 голосов
/ 02 августа 2020

Люблю pydub. Это просто понять. Но когда дело доходит до обнаружения не тихих фрагментов, librosa кажется намного быстрее. Поэтому я хочу попробовать использовать librosa в проекте, чтобы ускорить мой код.

До сих пор я использовал pydub следующим образом (segment - это AudioSegment):

thresh = segment.dBFS - (segment.max_dBFS - segment.dBFS)
non_silent_ranges = pydub.silence.detect_nonsilent(segment, min_silence_len=1000, silence_thresh=thresh)

Формула thresh работает в основном хорошо, а когда это не так, можно сдвинуть ее примерно на 5 дБ вверх или вниз.

Используя librosa, я пробую это numpy массив, загруженный с librosa.load(), с sr 22050)

non_silent_ranges = librosa.effects.split(y, frame_length=sr, top_db=mistery)

Чтобы получить аналогичные результаты с pydub, я попытался установить mistery на следующее:

mistery = y.mean() - (y.max() - y.mean())

и то же самое после преобразования y в dbs:

ydbs = librosa.amplitude_to_db(y)
mistery = ydbs.mean() - (ydbs.max() - ydbs.mean())

В обоих случаях результаты сильно отличаются от результатов, получаемых от pydub.

У меня нет опыта обработки звука, и хотя Я читал о rms, dbFS, et c, просто не понимаю - наверное, старею :)

Может ли кто-нибудь указать мне правильное направление? Что было бы эквивалентом моего решения pydub в librosa? Или, по крайней мере, объясните мне, как получить значения max_dBFS и dBFS pydub в librosa (я знаю, как преобразовать и AudioSegment в эквивалентный массив librosa numpy, благодаря отличному ответу здесь )?

1 Ответ

1 голос
/ 04 августа 2020

max_dBFS всегда по своей природе 0. dBFS - насколько "тише" звук, чем максимально возможный сигнал.

Я подозреваю, что другая часть вашей проблемы заключается в том, что ydbs.max() - это максимальное значение среди данных в ярдах, а не максимально возможное значение, которое может

Еще одним отличием от pydub является использование ydbs.mean(), pydub использует RMS при вычислении dBFS.

Вы можете преобразовать ydbs.mean() в dbfs вот так:

from numpy import mean, sqrt, square, iinfo

max_sample_value = iinfo(ydbs.dtype).max
ydbs_rms = sqrt(mean(square(ydbs))

ydbs_dbfs = 20 * log(ydbs_rms) / max_sample_value, 10)
...