1

I'm trying to convert a mp3 into a wave stream using NAudio. Unfortunately I receive the error Not a WAVE file - no RIFF header on the third line when creating the wave reader.

var mp3Reader = new Mp3FileReader(mp3FileLocation);
var pcmStream = WaveFormatConversionStream.CreatePcmStream(mp3Reader);
var waveReader = new WaveFileReader(pcmStream)

Shouldn't these streams work together properly? My goal is to combine several mp3s and wavs into a single stream for both playing and saving to disc( as a wav).

  • Have a look to this https://stackoverflow.com/questions/2488426/how-to-play-a-mp3-file-using-naudio and this https://stackoverflow.com/questions/2795021/trouble-converting-an-mp3-file-to-a-wav-file-using-naudio – Carles Feb 19 '18 at 14:05

2 Answers2

2

I'm going to preface this with a note that I've never used NAudio. Having said that, there's a guide to concatenating audio on their Github site.

Having looked at the API, you can't use Mp3FileReader directly as it doesn't implement ISampleProvider. However, you can use AudioFileReader instead.

Assuming you have an IEnumerable<string> (aka List or array) of the filenames you want to join named files:

var sampleList = new List<ISampleProvider>();

foreach(string file in files)
{
    sampleList.add(new AudioFileReader(file));
}

WaveFileWriter.CreateWaveFile16("outfilenamegoeshere.wav", new ConcatenatingSampleProvider(sampleList));
Powerlord
  • 87,612
  • 17
  • 125
  • 175
  • There does appear to be a caveat that all the files have to use the same sample rate, channel count, and bit depth. Otherwise, you might have to do some finagling with the files first (and save them as new files files?). – Powerlord Feb 19 '18 at 15:04
  • `CreateWaveFile16` doesn't take an `IEnumerable` so this code won't compile. If you want concatenation of `ISampleProviders` you can use the `FollowedBy` extension method to chain them together. The sample rate and channel count are likely to match with MP3s as they are most commonly 44.1kHz stereo – Mark Heath Feb 20 '18 at 08:22
  • @MarkHeath Whoops, I missed creating the `ConcatenatingSampleProvider` object. – Powerlord Feb 20 '18 at 08:24
  • yes, this will work with the caveat about sample rate/channel count. – Mark Heath Feb 20 '18 at 08:27
  • My wavs are the same sample/channel but the mp3 is a totaly different file type, yet it worked with the above code (had to add the ConcatenatingSampleProvider part). The sample/channel thing must be wav only, or the mp3 is converted to wav and they automatically match the first wav? – Chris Chevalier Feb 20 '18 at 15:23
  • mp3 is just a lossy compressed form of PCM and WAV is just PCM with a header. Chances are all the files you're dealing with have a 44.1kHz sample rate and 2 channel (stereo) sound... and a 16-bit sample size. Why? Because that's what a CD uses. – Powerlord Feb 20 '18 at 17:38
  • On a side note, you may see a bitrate referenced for MP3s. A WAV with the specs mentioned takes 1411.2 kb/s, so you can see a 128 kb/s, 256 kb/s, or even a 384 kb/s mp3 would be considerably smaller, let alone a variable bitrate mp3. – Powerlord Feb 20 '18 at 17:57
0

you don't need the second and third lines. Mp3FileReader will convert to PCM for you and you can play it directly with a player like WaveOutEvent. To actually produce a WAV file on disk, pass it into WaveFileWriter.CreateWaveFile

using(var reader = new Mp3FileReader(mp3FileLocation))
{
    WaveFileWriter.CreateWaveFile(reader);
}
Mark Heath
  • 48,273
  • 29
  • 137
  • 194