NAudio
NAudio copied to clipboard
Issues resampling mp3s with WdlResamplingSampleProvider and Mp3FileReaderBase (NLayer)
I'm having an odd issue resampling mp3s with Mp3FileReaderBase and WdlResamplingSampleProvider. For context, I'm using NAudio and NLayer in a Unity project for a WebGL app, so I need to use fully managed solutions (hence WdlResamplingSampleProvider seems to be my only option for resampling).
When I read an mp3 with Mp3FileReaderBase and create a sample provider from it, everything is fine and I can process/play the file without issue downstream. I'm using the code below to do that part:
// sourceBytes is raw bytes from mp3 file
var builder = new Mp3FileReaderBase.FrameDecompressorBuilder(wf => new Mp3FrameDecompressor(wf));
using var memoryStream = new MemoryStream(sourceBytes);
using var mp3Reader = new Mp3FileReaderBase(memoryStream, builder);
var sampleProvider = mp3Reader.ToSampleProvider();
The issue is that when I try to resample the audio (for instance from 22050 to 44100) with WdlResamplingSampleProvider, the resulting audio comes out garbled and with all kinds of artifacts. I'm using the code below to do that part:
var sampleRatio = (float) outputSampleRate / sourceSampleRate;
var outSamples = (int) (sourceSamples * sampleRatio);
ISampleProvider resampleProvider = new WdlResamplingSampleProvider(sampleProvider, outputSampleRate);
var resampled = new float[outSamples];
resampleProvider.Read(resampled, 0, resampled.Length);
After using WaveFileWriter.WriteSamples to write resampled to a file, I hear the issue for certain values of outputSampleRate and certain source samples rates.
Some more relevant info:
- If I externally resample the source file (e.g., with ffmpeg), it sounds fine. So it's not a corrupted file.
- If I convert the file to a wav externally (with ffmpeg) and then read it with NAudio using WaveFileReader, then when resampling with WdlResamplingSampleProvider everything sounds fine.
- Certain resampling values don't produce noticeable artifacts (e.g., going from 44100 to 48000). But trying to upsample from 16k or 22k to 44k produces the issue (with mp3 files).
Since the WaveFileReader approach works fine, it suggests the issue is with Mp3FileReaderBase/Mp3FrameDecompressor, not WdlResamplingSampleProvider. However, perhaps it's an interaction issue? If I just read the file in with Mp3FileReaderBase and then write it out again with a wave provider, it sounds fine. It's just the resampling that seems to produce the issue.
Would appreciate any thoughts and whether anyone sees if there is some user error here. Thanks.
Not sure I'm afraid, but just wanted to make sure you are checking the return value of Read. You can't assume that it will return the number of samples requested, and you might need to call it in a loop.