Code Monkey home page Code Monkey logo

nlayer's Introduction

NLayer

NLayer is a fully managed MP3 to WAV decoder. The code was originally based on JavaLayer (v1.0.1), which has been ported to C#.

Was previously hosted at nlayer.codeplex.com. Please see the history there for full details of contributors.

Usage

To use NLayer for decoding MP3, first reference NLayer.

using NLayer;

Then create an MpegFile, pass a file name or a stream to the constructor, and use ReadSamples for decoding the content:

// samples per second times channel count
const int samplesCount = 44100;
var fileName = "myMp3File.mp3";
var mpegFile = new MpegFile(filename);
float[] samples = new float[samplesCount];
int readCount = mpegFile.ReadSamples(samples, 0, samplesCount);

More information could be found in code documents.

Use with NAudio

NLayer is capable of using in conjunction with NAudio for file conversion and real-time playback.

You need to reference NAudio, NLayer and NLayer.NAudioSupport first.

using NAudio.Wave;
using NLayer.NAudioSupport;

Then create an Mp3FileReader, passing in a FrameDecompressorBuilder that uses the Mp3FrameDecompressor from NLayer.NAudioSupport:

var fileName = "myMp3File.mp3";
var builder = new Mp3FileReader.FrameDecompressorBuilder(wf => new Mp3FrameDecompressor(wf));
var reader = new Mp3FileReaderBase(fileName, builder);
// play or process the file, e.g.:
waveOut.Init(reader);
waveOut.Play();

nlayer's People

Contributors

basisbit avatar blealtan-bot avatar bundokin avatar ioctllr avatar kamchii avatar kvee33 avatar markheath avatar mikegoatly avatar roncli avatar starburst997 avatar ztl8702 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

nlayer's Issues

Attempted to read past the end of the stream

Hello,

I am trying to decode mp3 file. See simple console app.

var builder = new Mp3FileReader.FrameDecompressorBuilder(wf => new Mp3FrameDecompressor(wf));
using (var reader = new Mp3FileReader(@"D:\tEST\3.mp3", builder))
{
WaveFileWriter.CreateWaveFile(@"D://tEST/output.wav", reader);
}

As result the following exception was thrown.

at NLayer.NAudioSupport.Mp3FrameWrapper.ReadBits(Int32 bitCount)
at NLayer.Decoder.BitReservoir.AddBits(IMpegFrame frame, Int32 overlap)
at NLayer.Decoder.LayerIIIDecoder.DecodeFrame(IMpegFrame frame, Single[] ch0, Single[] ch1)
at NLayer.MpegFrameDecoder.DecodeFrameImpl(IMpegFrame frame, Array dest, Int32 destOffset)
at NLayer.MpegFrameDecoder.DecodeFrame(IMpegFrame frame, Byte[] dest, Int32 destOffset)
at NLayer.NAudioSupport.Mp3FrameDecompressor.DecompressFrame(Mp3Frame frame, Byte[] dest, Int32 destOffset)
at NAudio.Wave.Mp3FileReader.Read(Byte[] sampleBuffer, Int32 offset, Int32 numBytes)
at NAudio.Wave.WaveFileWriter.CreateWaveFile(String filename, IWaveProvider sourceProvider)
at NAaudioTest.Program.Main(String[] args) in D:\Data\startup\NAaudioTest\NAaudioTest\Program.cs:line 35
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()

/Best regards,
/Alexey Badyl

Support sample rate of 22500?

We have audio files from Amazon Polly (Text to Speech) and it returns MP3s with a sampling rate of 22500. Is there a way to support this?

Add additional TFM & make conditional dependency

Is your feature request related to a problem? Please describe.

I want to minimise dependencies in my project by utilising framework dependencies wherever possible

Describe the solution you'd like

The nuget package has no dependencies when used with net standard 2.0/2.1 & net 3+

Describe alternatives you've considered

Accept the additional dependency

Additional context

n/a

Unable to load mp3 correctly

Hello,
I have a problem with loading a couple of mp3 files.
They are the same track, just exported with different parameters.

In track 1, the audio is extremely sped up and with a wrong length. In track 2, on the other hand, the audio is fine but the duration is wrong (it should be about 45 seconds instead it is almost 6 minutes).

The code I am using is as follows:
var mpgFile = new NLayer.MpegFile(path);
var samples = new float[mpgFile.Length];
mpgFile.ReadSamples(samples, 0, (int)mpgFile.Length);
clip = AudioClip.Create("clip-mp3", samples.Length, mpgFile.Channels, mpgFile.SampleRate, false);
clip.SetData(samples, 0);

I'm using Unity and the last two lines are for creating the audio clip, but I think the problem is earlier, in reading the samples.

Here are the two tracks: Tracks.zip

Thank you in advance.

Strange result when convert MP3 to WAV with NLayer

I have mp3 file created with NAudio.Lame. Conversion to wav with naudio (with default acm driver) is ok, but with nlayer result is noised.
Please help, I don't understand my mp3 file corrupted or NLayer has some restriction I didn't notice?
Project (code+mp3 file): TestNLayer.zip

How it looks in Audacity (first row original mp3, second wav by naudio, third by nlayer):
TestNLayer

Write Mp3 files on Linux.

Good Morning all,

I've been using NLayer to read and convert MP3 to wav files with some success. However, the target machine is Linux and I can't see a way of writing MP3 files.

Currently, I have a workaround which uses Sox to do any post processing however, this takes twice as long. I have to write the WAV file then MP3. Is there a way that NLayer can do this?

Also, I need to write some other file formats which are (ulaw, pcm, alaw, wav44k). Does NLayer support this and are there any good examples on how to do this.

Thanks, in advance. R.

Independency (to NAudio) request on both documentation and interface

As this project (NLayer) is a fully managed implementation of MPEG decoder, I tried to use it in a .Net Standard project, but soon find no documents presented for NLayer itself, only a small sample showing how it works with NAudio. That's not what I want, so I looked into the source code, trying to figure out how itself works; but later I find that to use the PCM data decoded by NLayer, I have to manually separate stereo channels, while the backing decoder is all internal which I can't directly use.

The reason I came to this project is that I need a platform independent MP3 decoder; but the only "expected" way to use this is through NAudioSupport. So if I can make use of NAudio, which is Windows only, WHY take the trouble use NLayer? Ridiculous. This project, as an fully managed library, should work well by itself; but there are few interfaces and runtime configurations for me to use it directly, as well as few explanation on the interface.

I hope this platform independent project will become "independent" (at least be able to use by itself) to the platform dependent NAudio; in the meantime, may anyone figure out how may I use NLayer itself to decode a single stereo mp3 to two separate channels? If currently no way, it seems I'll have to use mono samples for my audio analysis.

Update Nuget package readme

Summary

I wish for the nuget packages to have a more informative readme.

Details

The nuget package should be using the same readme as the repo to make it as easy as possible for a user to get started with the package.

Async write to mpeg Stream

Hi, seems like we have a finite stream support only.
When there is a streaming mp3 file read out from a network resource then adding data to stream seems to be ignored by the decoder.

First MPEG frame is thrown away

In MpegStreamReader constructor the first MpegFrame found in the file gets thrown away.

`
// find the first Mpeg frame
var frame = FindNextFrame();
while (frame != null && !(frame is MpegFrame))
{
frame = FindNextFrame();
}

        // if we still don't have a frame, we never sync'ed
        if (frame == null) throw new InvalidDataException("Not a valid MPEG file!");

        // the very next frame "should be" an mpeg frame
        frame = FindNextFrame();

`

If the next frame isn't an MpegFrame then the entire decode fails.
At the point before the comment 'the very next frame "should be" an mpeg frame', frame already refers to an MpegFrame so there is no need to read the following one.

This causes me a problem because I am decoding a stream that only contains a single MpegFrame at a time.

MpegStreamReader Buffer resize/move logic issue

for (int i = 0, srcIdx = Data.Length - 1, destIdx = Data.Length - 1 - moveCount; i < moveCount; i++, srcIdx--, destIdx--)

This loop trying to do this backward move operation on the buffer is extremely extremely busted.

Not only does this never run because in this context moveCount should be negative. where i is always greater than 0 so the first loop iteration the check will fail. But destIdx = Data.Length - 1 - moveCount increases the destination index past the end of the array so if this does run it would result in an exception.

I don't really understand the original intent with this code enough to submit a PR so issue it is.

DownmixToMono doesn't convert to mono

Hi,

I'm trying to convert an .mp3 file to a mono .wav file. I'm using StereoMode.DownmixToMono in the decompressor, but I'm still getting a stereo file in the output. Here's my code:

var builder = new Mp3FileReader.FrameDecompressorBuilder(wf => new Mp3FrameDecompressor(wf){StereoMode = StereoMode.DownmixToMono});
using (var reader = new Mp3FileReader(mp3FileName, builder)) {
	using (var writer = new WaveFileWriter(waveFileName, reader.WaveFormat))
		reader.CopyTo(writer);
}

If I specify a mono format, I get a double length mono record filled with garbage:

var builder = new Mp3FileReader.FrameDecompressorBuilder(wf => new Mp3FrameDecompressor(wf){StereoMode = StereoMode.DownmixToMono});
using (var reader = new Mp3FileReader(mp3FileName, builder)) {
	var waveFormat = new WaveFormat(reader.WaveFormat.SampleRate, 1);
	using (var writer = new WaveFileWriter(waveFileName, waveFormat))
		reader.CopyTo(writer);
}

I also tried specifying a mono format in the Mp3FrameDecompressor constructor:

var builder = new Mp3FileReader.FrameDecompressorBuilder(wf => new Mp3FrameDecompressor(new WaveFormat(44100, 1)){StereoMode = StereoMode.DownmixToMono});
using (var reader = new Mp3FileReader(mp3FileName, builder)) {
	using (var writer = new WaveFileWriter(waveFileName, reader.WaveFormat))
		reader.CopyTo(writer);
}

The result was a mono record slown down 2x.

What am I doing wrong? How do you use the DownmixToMono option properly?

Array index is out of range

I'm getting:

Array index is out of range.
NLayer.Decoder.LayerIIIDecoder.Dequantize (Int32 idx, Single val, Int32 gr, Int32 ch)
NLayer.Decoder.LayerIIIDecoder.ReadSamples (Int32 sfBits, Int32 gr, Int32 ch)
NLayer.Decoder.LayerIIIDecoder.DecodeFrame (IMpegFrame frame, System.Single[] ch0, System.Single[] ch1)
NLayer.MpegFrameDecoder.DecodeFrameImpl (IMpegFrame frame, System.Array dest, Int32 destOffset)
NLayer.MpegFrameDecoder.DecodeFrame (IMpegFrame frame, System.Single[] dest, Int32 destOffset)
NLayer.MpegFile.ReadSamplesImpl (System.Array buffer, Int32 index, Int32 count)
NLayer.MpegFile.ReadSamples (System.Single[] buffer, Int32 index, Int32 count)

after loading a mpeg stream into mpegfile and calling read samples with a float[]. I'm not sure what's going on in the dequantize function so I'm at a loss on how to fix this. I'd love your help!

Issue converting MP3 to Wav files.

Hello All,
I have an issue with converting from MP3 to Wav files using NLayer. There appears to be an anomaly when creating the .wav file. Let me explain.
Steps.

  1. Using Audacity, I create a tone waveform to 10 minutes and save this as .mp3 file (Tone-10m.mp3).

  2. Using the following code (see below), I convert this to a .wav file (Tone-10m-to-wave.wav).

` static void Main(string[] args)
{

        // set up source and target files
        var sourceFile = Path.Combine("C:\\tmp", "Tone-1m.mp3");
        var targetFile = Path.Combine("C:\\tmp", "Tone-1m-to-wave.wav");

        // create the builder
        var builder = new Mp3FileReaderBase.FrameDecompressorBuilder(wf => new Mp3FrameDecompressor(wf));

        // write the wav file
        using (var reader = new Mp3FileReaderBase(sourceFile, builder))
        {
            WaveFileWriter.CreateWaveFile(targetFile, reader);
        }

        Console.WriteLine("Done!");

    }`
  1. Comparing the two, waveforms in Audacity, I can see at 1.38m, 5.12m and at 8.46m there are spikes in the waveform. See original .mp3 and processed.wav files below.

  2. Processing other more musical waveforms, I cannot see any other anomalies. This seems to be just on this, but Iโ€™m wondering if there is a bug in the code somewhere.

Has anyone else experienced this?

tempsnip

Mp3ToWavConversion.zip

Wrong Frame Size for MPEG-2

I was getting an exception when decoding MPEG Version 2. Figured out it was because the frame lengths were being calculated incorrectly. I believe the issue is here (in MpegFrame.cs):

// calculate the frame's length
int frameSize;
if (BitRateIndex > 0)
{
    if (Layer == MpegLayer.LayerI)
    {
        frameSize = (12 * BitRate / SampleRate + Padding) * 4;
    }
    else
    {
        frameSize = 144 * BitRate / SampleRate + Padding;
    }
}

Compare to the length calculation used by NAudio:

int coefficient = frame.SampleCount/8;
if (frame.MpegLayer == MpegLayer.Layer1)
{
    frame.FrameLength = (coefficient*frame.BitRate/frame.SampleRate + nPadding)*4;
}
else
{
    frame.FrameLength = (coefficient*frame.BitRate)/frame.SampleRate + nPadding;
}

I don't have access to the specs, but it looks like the hard-coded 144 is only going to be correct for MPEG-1 (when sample count is 1152). Appears to have solved my error switching to use SampleCount / 8.

The example of the use of NLayer is not precise

I think the example should be like the following

var fileName = "myMp3File.mp3";
var mpegFile = new MpegFile(filename);
int audioDataLength = (int)(mpegFile.Length/sizeof(float));
float[] samples = new float[audioDataLength ];
mpegFile.ReadSamples(samples, 0, audioDataLength);

Fix license file

The license file in the root directory got cut off at the top, so I can't tell what license is used (I'm guessing LGPL 2.1, but I'm no license expert). :)

File decodes to a longer length than the audio

Attached is an MP3 file I created. It is intended to be used as a loop.

In Adobe Audition, it decodes to a length of 1,181,541 samples, and loops seamlessly.

In NLayer, it decodes to a length of 1,184,256 samples, which includes 2,715 extra samples, or approx 2.36 frames of additional audio, which are largely inaudible, causing the loop to have a gap.

After some trial and error, I've found that if I take my NLayer data and chop off the first 1,152 samples (a full frame) and the last 1,563 samples (a full frame plus the ending padding), the loop is seamless.

I'm not too familiar with the technical details behind the MP3 format, but it does appear something is off here. Any idea what might be causing this?

title.zip

Set repo url for nuget package

Summary

I wish for the nuget packages to have the repo url set correctly.

Details

By providing the repo url it will make it easier to contribute and can be used by source-link.

.NetFramework issue during installation through MS-VS

Hello.
I read your post on your blog for this nodriver calling acmformatsuggest
I am using the NAudio.dll with an mp3 upload script for reading tags in ASP.NET (VB)
Using .NetFramework v4.5
This component used to work with our older Windows 2016 Server DC, but we lost it, and the same weekend, we lost our array and had to build the web farm again from scratch.
But since we are now in a freshly installed Windows 2016 Server DC and Server Farm setup, nothing is working as it used to.
Which included, the NAudio.dll within our Windows CORE Servers.
(To read more on this issue we are having, please look at the StackExchange thread.

I opened the site in Visual Studio, and found your NLayer, and tried to install it.
However, it gives an error about the .netframework version being incompatible.
Could you please let me know what the highest version you are designing the component with, so I can attempt to drop my site down to that version to install this component?

Also, can you please let me know if your component will work with reading mp3 tags?
Thanks
Wayne

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.