Convert PCM to MP3/OGG
Asked Answered
B

3

2

I need to convert a continuous stream of PCM, or encoded audio (ADPCM, uLaw, Opus), into MP3/OGG format so that it can be streamed to a browser (using html's audio tag). I have the "stream-mp3/ogg-using-audio-tag" part working, now I need to develop the conversion layer.

I have two questions:

  1. How can I convert PCM into MP3/OGG using NAudio and/or some other C# library/framework? I assume there is a code snippet or two in the NAudio demo app that may be doing this, but I haven't been able to find it.
  2. Do I have to convert the encoded data (ADPCM, uLaw, OPUS) into PCM (which I can) before I convert it into MP3/OGG, or can the MP3/OGG 'containers' accept the encoded data?

NOTE: I understand there my be licensing issues with MP3 so we are open to using OGG.

Thanks.

Bicorn answered 10/12, 2013 at 17:9 Comment(1)
I think the information I need is a the bottom of this linkBicorn
S
1

To answer your first question, to create MP3 or OGG you need an encoder. NAudio does not include an MP3 or an OGG encoder. All it does is give you ways to access encoders that are already installed on your computer (such as ACM or Media Foundation Transforms). However, with both MP3 and OGG you'll find that the easiest way is to find an unmanaged DLL or a command line utility and access that from .NET. The article I wrote which you linked to above includes a brief explanation of how you can use LAME.exe with stdin and stdout to convert PCM to MP3 on the fly.

As for your second question, the answer is yes. Whenever you transcode, you first decode to PCM, then re-encode in the target codec. I think theoretically you can put audio encoded in any format into an OGG container, but in practice, audio in an OGG container is usually encoded with Vorbis. FLAC and OPUS may be options, but once again you'd need to find an application or library that can write the OGG container format for you, as I'm not aware of any fully managed OGG writers.

Sync answered 10/12, 2013 at 21:3 Comment(5)
Thanks for the response. I'm looking at the NAudioWpfDemo code right now. I think the 'Media Foundation Encode' might have what I need.Bicorn
I've looked at the demo code but for some reason when I select 'MP3' the 'Encoder Setting' list box doesn't populate with anything, any ideas why? I also noticed that in NAudio 1.7 (which I'm using ) there is an EncodeToMp3, but if I read the Code Project page correctly, it has to write to a real file, not a stream, is that correct?Bicorn
because it only shows MP3 encodings that are valid for the sample rate of the input file. And yes, this one writes to a file - it's just a helper method wrapping the Media Foundation encoder.Sync
So, I'll need to "convert" my 8K,16-bit,mono input to something that the MP3 encoder would accept before I can use the MF encoder, right? Where can I find the list of MP3 encoder acceptable formats?Bicorn
Since our current dev environment (Win7 and Server 2008 R2) do NOT have a native MP3 encoder, I made use of lame.exe and redirected stdin/stdout to handle our conversion. If/when this project has any hope of leaving the prototype phase, I'll look into using Win8/Server2012 (which have mp3 encoders, that I hope support Stream-to-Stream) and/or take a deeper look at Corey's NAudio.Lame (at quick glance it appears to support Stream-to-Stream).Bicorn
T
2

<Shameless Plug>
I wrote an addon for NAudio that uses libmp3lame from the LAME Encoder suite to handle MP3 encoding. It's on NuGet as NAudio.Lame, and the source is on GitHub.
</Shameless Plug>

Sadly the licensing issues remain if you are planning to use this for anything other than personal use. LAME itself is licensed under the LGPL, but the patents it implements still require licencing from Frauenhofer/Thompson according to the LAME Wikipedia entry. If you're planning to produce something for others this can get expensive.

The Vorbis compressor is unencumbered by patents and such, so it's a reasonable alternative. At some point I plan to do a similar wrapper to the OGG/Vorbis format. In the meantime, a quick Google Search turns up the Ogg Vorbis Interop Library which might be useful to you.

And yes, you will need PCM as an intermediate format in pretty much any conversion. NAudio gives you the tools to get PCM from a wide variety of audio formats.

Tiffin answered 10/12, 2013 at 21:50 Comment(4)
Thanks for the suggestion. Upon further review it seems as though I can't use OGG as IE doesn't support it according to Wikipedia.Bicorn
Corey, I was able to get your NAudio.Lame to work with a command-line .exe tool, but as soon as I move to the code into an ASP.NET Web API project, I get an exception loading libmp3lame.64.dll even though the file is found in the bin folder of my website. Any ideas? Is there a better place to post NAudio.Lame questions?Bicorn
Sorry for the delay Tony... check out this answer about exactly this type of problem.Tiffin
Thank, I saw the entry in your Wiki but I always forget that Web API is basically MVC for web services so many of the MVC "issues/fixes" apply to it as well. I'll give it a try once I return to work.Bicorn
S
1

To answer your first question, to create MP3 or OGG you need an encoder. NAudio does not include an MP3 or an OGG encoder. All it does is give you ways to access encoders that are already installed on your computer (such as ACM or Media Foundation Transforms). However, with both MP3 and OGG you'll find that the easiest way is to find an unmanaged DLL or a command line utility and access that from .NET. The article I wrote which you linked to above includes a brief explanation of how you can use LAME.exe with stdin and stdout to convert PCM to MP3 on the fly.

As for your second question, the answer is yes. Whenever you transcode, you first decode to PCM, then re-encode in the target codec. I think theoretically you can put audio encoded in any format into an OGG container, but in practice, audio in an OGG container is usually encoded with Vorbis. FLAC and OPUS may be options, but once again you'd need to find an application or library that can write the OGG container format for you, as I'm not aware of any fully managed OGG writers.

Sync answered 10/12, 2013 at 21:3 Comment(5)
Thanks for the response. I'm looking at the NAudioWpfDemo code right now. I think the 'Media Foundation Encode' might have what I need.Bicorn
I've looked at the demo code but for some reason when I select 'MP3' the 'Encoder Setting' list box doesn't populate with anything, any ideas why? I also noticed that in NAudio 1.7 (which I'm using ) there is an EncodeToMp3, but if I read the Code Project page correctly, it has to write to a real file, not a stream, is that correct?Bicorn
because it only shows MP3 encodings that are valid for the sample rate of the input file. And yes, this one writes to a file - it's just a helper method wrapping the Media Foundation encoder.Sync
So, I'll need to "convert" my 8K,16-bit,mono input to something that the MP3 encoder would accept before I can use the MF encoder, right? Where can I find the list of MP3 encoder acceptable formats?Bicorn
Since our current dev environment (Win7 and Server 2008 R2) do NOT have a native MP3 encoder, I made use of lame.exe and redirected stdin/stdout to handle our conversion. If/when this project has any hope of leaving the prototype phase, I'll look into using Win8/Server2012 (which have mp3 encoders, that I hope support Stream-to-Stream) and/or take a deeper look at Corey's NAudio.Lame (at quick glance it appears to support Stream-to-Stream).Bicorn
B
0

1) PCM to OGG

string fileName = @"e:\Down\male.wav";
Sox.Convert(@"sox.exe", fileName, fileName + ".ogg");

2) PCM to MP3

    static void AnyToMp3(string fileName)
    {
        DsReader dr = new DsReader(fileName);
        IntPtr formatPcm = dr.ReadFormat();
        byte[] dataPcm = dr.ReadData();
        dr.Close();
        IntPtr formatMp3 = AudioCompressionManager.GetCompatibleFormat(formatPcm,
            AudioCompressionManager.MpegLayer3FormatTag);
        byte[] dataMp3 = AudioCompressionManager.Convert(formatPcm, formatMp3, dataPcm, false);
        Mp3Writer mw = new Mp3Writer(File.Create(fileName + ".mp3"));
        mw.WriteData(dataMp3);
        mw.Close();
    }
Bulletproof answered 9/4, 2014 at 20:45 Comment(1)
We had mothballed this project for a few months until yesterday, the fact that you posted on the same day must be destiny. I'll send you a few questions about your library via your website.Bicorn

© 2022 - 2024 — McMap. All rights reserved.