Repository: rwth-i6/returnn

Issue:
support new librosa version 0.9.1
Setting up a new environment I noticed that the latest version of librosa is not working currently with returnn.

One example (I did not check all functions) would be 
https://github.com/rwth-i6/returnn/blob/a86ba33e1ade77c4a4994b9b8a7cca529128d1a3/returnn/datasets/util/feature_extraction.py#L309-L312
where `audio` is given as a positional argument, but `librosa.feature.mfcc` expects keyword-only arguments now:
https://librosa.org/doc/0.9.1/generated/librosa.feature.mfcc.html

Alternatively I would also be happy if you add the min/max supported version to `requirements.txt`.


Discussion:
So, just using `y=audio`... is the only change we need? And this also works for older librosa versions?
PR is welcome.
This is the change needed for the one problem that I encountered. I do not oversee if
a) there are additional problems/changes needed in other parts of returnn, or
b) this change breaks compatibility with some older version.

Yea but anyway, a PR would be nice.
I tried to experiment with "extra" requirements to also include librosa there, but was not successful so far...

Resolving patch:
diff --git a/returnn/datasets/util/feature_extraction.py b/returnn/datasets/util/feature_extraction.py
--- a/returnn/datasets/util/feature_extraction.py
+++ b/returnn/datasets/util/feature_extraction.py
@@ -283,7 +283,12 @@ def _get_audio_linear_spectrogram(audio, sample_rate, window_len=0.025, step_len
   assert num_feature_filters*2 >= min_n_fft
   assert num_feature_filters % 2 == 0
 
-  spectrogram = numpy.abs(librosa.core.stft(
+  librosa_version = librosa.__version__.split(".")
+  if int(librosa_version[0]) >= 1 or (int(librosa_version[0]) == 0 and int(librosa_version[1]) >= 9):
+    stft_func = librosa.stft
+  else:
+    stft_func = librosa.core.stft
+  spectrogram = numpy.abs(stft_func(
     audio, hop_length=int(step_len * sample_rate),
     win_length=int(window_len * sample_rate), n_fft=num_feature_filters*2))
 
@@ -307,7 +312,7 @@ def _get_audio_features_mfcc(audio, sample_rate, window_len=0.025, step_len=0.01
   """
   import librosa  # noqa
   features = librosa.feature.mfcc(
-    audio, sr=sample_rate,
+    y=audio, sr=sample_rate,
     n_mfcc=num_feature_filters,
     hop_length=int(step_len * sample_rate), n_fft=int(window_len * sample_rate))
   librosa_version = librosa.__version__.split(".")
@@ -316,7 +321,7 @@ def _get_audio_features_mfcc(audio, sample_rate, window_len=0.025, step_len=0.01
   else:
     rms_func = librosa.feature.rmse  # noqa
   energy = rms_func(
-    audio,
+    y=audio,
     hop_length=int(step_len * sample_rate), frame_length=int(window_len * sample_rate))
   features[0] = energy  # replace first MFCC with energy, per convention
   assert features.shape[0] == num_feature_filters  # (dim, time)
@@ -342,7 +347,7 @@ def _get_audio_log_mel_filterbank(audio, sample_rate, window_len=0.025, step_len
   """
   import librosa  # noqa
   mel_filterbank = librosa.feature.melspectrogram(
-    audio, sr=sample_rate,
+    y=audio, sr=sample_rate,
     n_mels=num_feature_filters,
     hop_length=int(step_len * sample_rate), n_fft=int(window_len * sample_rate))
   log_noise_floor = 1e-3  # prevent numeric overflow in log
@@ -377,7 +382,7 @@ def _get_audio_db_mel_filterbank(audio, sample_rate,
 
   import librosa  # noqa
   mel_filterbank = librosa.feature.melspectrogram(
-    audio, sr=sample_rate,
+    y=audio, sr=sample_rate,
     n_mels=num_feature_filters,
     hop_length=int(step_len * sample_rate),
     n_fft=int(window_len * sample_rate),
@@ -407,13 +412,18 @@ def _get_audio_log_log_mel_filterbank(audio, sample_rate, window_len=0.025, step
   :rtype: numpy.ndarray
   """
   import librosa  # noqa
+  librosa_version = librosa.__version__.split(".")
+  if int(librosa_version[0]) >= 1 or (int(librosa_version[0]) == 0 and int(librosa_version[1]) >= 9):
+    db_func = librosa.amplitude_to_db
+  else:
+    db_func = librosa.core.amplitude_to_db
   mel_filterbank = librosa.feature.melspectrogram(
-    audio, sr=sample_rate,
+    y=audio, sr=sample_rate,
     n_mels=num_feature_filters,
     hop_length=int(step_len * sample_rate), n_fft=int(window_len * sample_rate))
   log_noise_floor = 1e-3  # prevent numeric overflow in log
   log_mel_filterbank = numpy.log(numpy.maximum(log_noise_floor, mel_filterbank))
-  log_log_mel_filterbank = librosa.core.amplitude_to_db(log_mel_filterbank)
+  log_log_mel_filterbank = db_func(log_mel_filterbank)
   assert log_log_mel_filterbank.shape[0] == num_feature_filters
   log_log_mel_filterbank = log_log_mel_filterbank.transpose().astype("float32")  # (time, dim)
   return log_log_mel_filterbank


Test patch: