tags:

views:

212

answers:

1

I am trying to read PCM samples from a (converted) MP3 file using NAudio, but failing as the Read method returns zero (indicating EOF) every time.

Example: this piece of code, which attempts to read a single 16-bit sample, always prints "0":

using System;
using NAudio.Wave;

namespace NAudioMp3Test
{
    class Program
    {
        static void Main(string[] args)
        {
            using (Mp3FileReader fr = new Mp3FileReader("MySong.mp3"))
            {
                byte[] buffer = new byte[2];
                using (WaveStream pcm = WaveFormatConversionStream.CreatePcmStream(fr))
                {
                    using (WaveStream aligned = new BlockAlignReductionStream(pcm))
                    {
                        Console.WriteLine(aligned.WaveFormat);
                        Console.WriteLine(aligned.Read(buffer, 0, 2));
                    }
                }
            }
        }
    }
}

output:

16 bit PCM: 44kHz 2 channels
0

But this version which reads from a WAV file works fine (I used iTunes to convert the MP3 to a WAV so they should contain similar samples):

static void Main(string[] args)
{
    using (WaveFileReader pcm = new WaveFileReader("MySong.wav"))
    {
        byte[] buffer = new byte[2];
        using (WaveStream aligned = new BlockAlignReductionStream(pcm))
        {
            Console.WriteLine(aligned.WaveFormat);
            Console.WriteLine(aligned.Read(buffer, 0, 2));
        }
    }
}

output:

16 bit PCM: 44kHz 2 channels
2

What is going on here? Both streams have the same wave formats so I would expect to be able to use the same API to read samples. Setting the Position property doesn't help either.

+1  A: 

You probably need to read in larger chunks. NAudio uses ACM to perform the conversion from MP3 to WAV, and if your target buffer isn't big enough, the codec may refuse to convert any data at all. In other words, you need to convert a block of samples before you can read the first sample.

WAV files are a different matter as it is nice and easy to read a single sample from them.

Mark Heath
I assumed the `BlockAlignReductionStream` would do that. Maybe I need to pass it a parameter to tell it to allocate a larger buffer?
finnw
yes, the block align reduction stream does help you out in some instances, but probably the sourceReadCount it calculates in the Read method is 0 or too low. Would be interesting if you can debug to see what it is calculating sourceReadCount as. Perhaps I can put a fix in
Mark Heath