Это звучит как проблема квантования.Если сэмплы в волновом файле хранятся как float
, а librosa просто выполняет прямое приведение к int
, а значение меньше 1 будет усечено до 0. Более вероятно, поэтому sig
является массивомвсех нулей.float
должен быть масштабирован, чтобы отобразить его в диапазоне int
.Например,
>>> a = sp.randn(10)
>>> a
array([-0.04250369, 0.244113 , 0.64479281, -0.3665814 , -0.2836227 ,
-0.27808428, -0.07668698, -1.3104602 , 0.95253315, -0.56778205])
Преобразование в тип int
без масштабирования
>>> a.astype(int)
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
Преобразование в int
с масштабированием для 16-разрядного целого числа
>>> b = (a* 32767).astype(int)
>>> b
array([ -1392, 7998, 21127, -12011, -9293, -9111, -2512, -42939,
31211, -18604])
Преобразовать масштабированный int
обратно в float
>>> c = b/32767.0
>>> c
array([-0.04248177, 0.24408704, 0.64476455, -0.36655782, -0.28360851,
-0.27805414, -0.0766625 , -1.31043428, 0.9525132 , -0.56776635])
c
и b
равны только примерно 3 или 4 десятичным знакам из-за квантования в int
.
Если librosa возвращает float
, вы можете масштабировать ее на 2**15
и привести ее к int
, чтобы получить тот же диапазон значений, который возвращает читатель scipy wave.Поскольку librosa возвращает float
, скорее всего, значения будут лежать в гораздо меньшем диапазоне, например [-1, +1]
, чем 16-разрядное целое число, которое будет в [-32768, +32767]
.Так что вам нужно масштабировать единицу, чтобы получить диапазоны для соответствияНапример,
sig, rate = librosa.load(spec_file, mono=True)
sig = sig × 32767