9

I am trying to sample (convert analog to digital) mp3 files via the following Python code using the librosa library, but it takes too much time (around 4 seconds for one file). I suspect this is because librosa doesn't support mp3 and hence uses the slower audioread to sample mp3

Code:

import time
import librosa

s = time.time()
for i in mp3_list[:10]: # list of mp3 file paths, doing for 10 files
    y, sr = librosa.load(i)

print('time taken =', time.time() - s)

time taken = 36.55561399459839

I also get this warning:

UserWarning: "PySoundFile failed. Trying audioread instead."

Obviously, this is too much time for any practical application. I want to know if there are better alternatives to this?

For comparison, it only took around 1.2 seconds total time to sample 10 same-sized wav conversions

john doe
  • 437
  • 2
  • 5
  • 13

1 Answers1

4

So the warning kind of hints it. The Librosa developers addressed a similar question in this GitHub question:

This warning will always occur when loading mp3 because libsndfile does not (yet/currently) support the mp3 format. Librosa tries to use libsndfile first, and if that fails, it will fall back on the audioread package, which is a bit slower and more brittle, but supports more formats.

This is confirmed in the Librosa-code: try ... except RuntimeError ...

So what you can do in this case is either implement your own load() that directly uses audioread to avoid the time wasted in the first block of librosa.load(), or you can use a different library such as pydub. Alternatively, you can use ffmpeg to convert your mp3 to wave before loading them.

SuperKogito
  • 2,998
  • 3
  • 16
  • 37
  • Thanks for the answer, in Pydub you can sample by following this https://github.com/jiaaro/pydub/blob/master/API.markdown#audiosegmentget_array_of_samples right? I mean using AudioSegment.from_file().get_array_of_samples() ? – john doe Jan 24 '20 at 11:35
  • Also, I think the link I mentioned can't be used for sampling. I can't even find where to mention the sampling rate. Do you know how Pydub can be used for sampling? – john doe Jan 24 '20 at 12:13
  • So when using the pydub lib you essentially read your audio as an `AudioSegment` object which has the attribute `frame_rate`. So you can do the following: `mp3_audio = AudioSegment.from_file("path/to/audio.mp3", format="mp3")` and then `sr = mp3_audio.frame_rate`. Please let me know if this pydub version is faster than the Librosa alternative (in your question), as this would be a good edit for the answer. – SuperKogito Jan 24 '20 at 13:13
  • 1
    I am not sure if by sampling you mean changing the sampling rate, but if so that is possible using: `newly_sampled_audio = mp3_audio.set_frame_rate(new_sampling_rate)` – SuperKogito Jan 24 '20 at 13:19
  • 1
    sorry for the late reply. Yes, what I wanted was to resample to a new sampling rate. There is an improvement in time with `pydub` but still not comparable to loading `wav` files. It took `sound = AudioSegment.from_file("path/to/audio.mp3", format="mp3").set_frame_rate(8000)` `1.26` seconds on a file while `y, sr = librosa.load("path/to/audio.mp3", sr=8000)` took `1.77` seconds – john doe Jan 28 '20 at 09:30