An NAudio WaveStream
is a stream of sample data with a specified format, not a RIFF WAV file as expected by LAME. To convert it to a RIFF WAV file you need to add RIFF headers and so on. The NAudio.Wave.WaveFileWriter
class does this.
If you're working with smallish output files that aren't going to blow your memory, you can do something simple like (assuming Yeti's LAME wrapper or similar):
(code updated 19-Aug-2013):
public byte[] EncodeMP3(IWaveProvider ws, uint bitrate = 128)
{
// Setup encoder configuration
WaveLib.WaveFormat fmt = new WaveLib.WaveFormat(ws.WaveFormat.SampleRate, ws.WaveFormat.BitsPerSample, ws.WaveFormat.Channels);
Yeti.Lame.BE_CONFIG beconf = new Yeti.Lame.BE_CONFIG(fmt, bitrate);
// Encode WAV to MP3
int blen = ws.WaveFormat.AverageBytesPerSecond;
byte[] buffer = new byte[blen];
byte[] mp3data = null;
using (MemoryStream mp3strm = new MemoryStream())
using (Mp3Writer mp3wri = new Mp3Writer(mp3strm, fmt, beconf))
{
int rc;
while ((rc = ws.Read(buffer, 0, blen)) > 0)
mp3wri.Write(buffer, 0, rc);
mp3data = mp3strm.ToArray();
}
return mp3data;
}
-- Update: Setting MP3 encoding parameters
Using the Yeti
LAME wrapper, you can specify the MP3 encoding parameters by passing in a BE_CONFIG
structure like so:
WaveLib.WaveFormat fmt = new WaveLib.WaveFormat(ws.WaveFormat.SampleRate, ws.WaveFormat.BitsPerSample, ws.WaveFormat.Channels);
Yeti.Lame.BE_CONFIG beconf = new Yeti.Lame.BE_CONFIG(fmt, 64);
using (MemoryStream mp3strm = new MemoryStream())
using (Mp3Writer mp3wri = new Mp3Writer(mp3strm, fmt, beconf))
{
...
}
The BE_CONFIG
constructor takes a WaveLib.WaveFormat
and an optional CBR bit rate in Kb/s. If you don't specify a bit rate it defaults to 128Kb/s output. If you don't supply the configuration to the Mp3Writer
it creates a default one from the WaveFormat
.
The code above creates a BE_CONFIG
with the output rate set to 64Kb/s. If you want a different bit rate, just specify it in place of the 64
in new Yeti.Lame.BE_CONFIG(fmt, 64);
BE_CONFIG
contains a lot of other options, most of which you won't ever use. Check out the (slightly sketchy) documentation here.