Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slow on MP3 format #18

Open
BOBJohnson opened this issue Aug 6, 2023 · 2 comments
Open

Slow on MP3 format #18

BOBJohnson opened this issue Aug 6, 2023 · 2 comments

Comments

@BOBJohnson
Copy link

I am working with some rather large WAVs/MP3s which I am trying to generate small waveform graphics for. This is working. However the MP3s are 50x slower to process and render than the wav files are.

I thought it might be something I am doing wrong, but even the demo project on here is considerably slower when working with the large MP3s compared to working with the even larger WAVs. By large, I mean the MPs are 100mb to 200mb and the WAVs are 500mb to 1gb.

I've narrowed the performance problem down to this one line in the SamplingPeakProvider:

int num = base.Provider.Read(base.ReadBuffer, 0, base.ReadBuffer.Length);

Each call to this is taking on average 0.1 seconds per call on the MP3 files, resulting in it taking 15 to 20 seconds to process the file and render the waveform.

That same line on WAV files is taking 0.002 seconds.

I am unsure of how to improve the performance in the demo to get comparable speeds (or at least go from 50x slower to only 5x slower).

@markheath
Copy link
Contributor

The basic explanation is that for WAV files the samples are already uncompressed as so their peak values can easily be read, but for MP3 the audio must be decoded to PCM. Having said that, your timings do seem very slow. What class are you using? I would expect MediaFoundationReader to be fastest at reading MP3 files, but haven't done any timing tests myself.

@BOBJohnson
Copy link
Author

Sorry about the slow reply. I don't know why but GitHub never sends me alerts when I get responses on issues I create.

To answer your question, I originally used what the example project used which was an AudioFileReader. I tried the Mp3FileReader and the MediaFoundationReader. I don't remember if read rate was any different on the 3, but all 3 seemed equally slow.

This is my first foray into audio. A friend asked me to make him a basic utility that would take a folder that had 32 input and several output audio files and allow him to pick which to keep and which to delete (based on channel name in the filename) and whether there was any audio in the file (the waveform is basically a flat line if a particular input was muted the whole time).

I ended up with 2 compromises for the moment:

  1. once a waveform image is generated, it's saved as a png, so the next time the audio files are displayed in the utility, it just grabs that instead.

  2. I found an example project on Code Project (https://www.codeproject.com/Articles/811857/AAWG) that talked about loading the mp3 file in parallel and rendering the waveform as it progressed. There demo project didn't seem to be any faster, but it did render as it went. So I spliced in similar logic to update the graphic on the screen line by line as it loaded, so that the user could see that progress was being made vs the UI just kind of hanging for 20+ seconds and then a graphic appear, then hang another 20+ seconds until the next channel graphic appeared and so on.

I just re-ran the parallel demo (adding in a stopwatch) and it was actually 3.3 seconds slower on the same file as the code in my project that is not parallel. The test mp3 file is 270mb.


The only other thing I can think to try is as you mention it having to be decoded to PCM first, maybe I feed the mp3 file into a PCM decoder and just have it decode it into memory first, then generate the waveform graphic? Not sure that would help.

In my project, I just ran it 3 times:
AudioFileReader: 00:00:13.6135803
Mp3FileReader: 00:00:13.6485233
MediaFoundationReader: 00:00:13.4306794

Since these were just single timed runs, and not something fed into say Benchmark.Net, while the MediaFoundReader was the fastest of the 3, I'm sure it is within margin of error of the other 3, so performance gain is negligible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants