Search code examples
c#mp3naudio

c# reading PCM data from mp3 file stops before finishes


I'm trying to read only the data of mp3 files through NAudio, I using WaveStream I ask for the WaveStream length and I allocate byte[] according to that length. And when I try to read the whole stream at once and the outcome is exception: "Additional information: Not enough space in buffer"

using (Mp3FileReader fr = new Mp3FileReader(@"C:\Users\AmitL\Desktop\The Fabulous Thunderbirds - Powerful Stuff.mp3"))
        {
            byte[] buffer = new byte[2];
            long l_lLen = fr.Length;
            Console.WriteLine("mp3 length" + l_lLen.ToString());
            using (WaveStream pcm = WaveFormatConversionStream.CreatePcmStream(fr))
            {
                long l_lLenPCM = pcm.Length;
                int l_dLenPCM = Convert.ToInt32(l_lLenPCM);
                byte[] l_bData = new byte[l_dLenPCM];

                Console.WriteLine("l_bData len: " + l_bData.Length.ToString());
                Console.WriteLine("l_dLenPCM: " + l_dLenPCM.ToString());
                Console.WriteLine("l_bData[l_bData.Length - 1]: " + l_bData[l_bData.Length - 1].ToString());
                using (WaveStream aligned = new BlockAlignReductionStream(pcm))
                {
                    Console.WriteLine("aligned.Length" + aligned.Length);
                    Console.WriteLine("aligned.Read: " + aligned.Read(l_bData, 0 , l_dLenPCM ));
                }
            }
        }

outpout: mp3 length4377442 l_bData len: 126074880 l_dLenPCM: 126074880 l_bData[l_bData.Length - 1]: 0 aligned.Length126074880

And when I try to read the stream at Iterations it stops reading after the 382 iteration of reading 126074 bytes and another final read of 103924 bytes...???? simple replace the line in which I read to:

for (int i = 0; i < 500; i++)
{
    Console.WriteLine("i: " + i.ToString() + "aligned.Read : " + aligned.Read(l_bData, (l_dLenPCM / 1000) * i, l_dLenPCM / 1000));
}

Anyone knows what I'm doing wrong??


Solution

  • First, there is no need to use WaveFormatConversionStream or BlockAlignReductionStream with Mp3FileReader. Just call Read and you will get PCM

    Second, don't try reading entire MP3 files in one go, since the data has to be passed through a codec, which may have limited buffer sizes. Instead, call Read in a loop until it returns 0 indicating end of file. A second at a time is a good rule of thumb for determining a Read buffer size. You can use the AverageBytesPerSecond property of the WaveFormat of the Mp3FileReader to get hold of this byte size.