1
votes

I'm trying to reimplement an existing Matlab 8-band equalizer GUI I created for a project last week in C#. In Matlab, songs load as a dynamic array into memory, where they can be freely manipulated and playing is as easy as sound(array).

I found the NAudio library which conveniently already has Mp3 extractors, players, and both convolution and FFT defined. I was able to open the Mp3 and read all its data into an array (though I'm not positive I'm going about it correctly.) However, even after looking through a couple of examples, I'm struggling to figure out how to take the array and write it back into a stream in such a way as to play it properly (I don't need to write to file).

Following the examples I found, I read my mp3's like this:

   private byte[] CreateInputStream(string fileName)
    {
        byte[] stream;
        if (fileName.EndsWith(".mp3"))
        {
            WaveStream mp3Reader = new Mp3FileReader(fileName);
            songFormat = mp3Reader.WaveFormat; // songFormat is a class field
            long sizeOfStream = mp3Reader.Length;
            stream = new byte[sizeOfStream];
            mp3Reader.Read(stream, 0, (int) sizeOfStream);
        }
        else
        {
            throw new InvalidOperationException("Unsupported Exception");
        }
        return stream;
    }

Now I have an array of bytes presumably containing raw audio data, which I intend to eventually covert to floats so as to run through the DSP module. Right now, however, I'm simply trying to see if I can play the array of bytes.

        Stream outstream = new MemoryStream(stream);
        WaveFileWriter wfr = new WaveFileWriter(outstream, songFormat);
        // outputStream is an array of bytes and a class variable
        wfr.Write(outputStream, 0, (int)outputStream.Length);
        WaveFileReader wr = new WaveFileReader(outstream);
        volumeStream = new WaveChannel32(wr);
        waveOutDevice.Init(volumeStream);
        waveOutDevice.Play();

Right now I'm getting errors thrown in WaveFileReader(outstream) which say that it can't read past the end of the stream. I suspect that's not the only thing I'm not doing correctly. Any insights?

1

1 Answers

1
votes

Your code isn't working because you never close the WaveFileWriter so its headers aren't written correctly, and you also would need to rewind the MemoryStream.

However, there is no need for writing a WAV file if you want to play back an array of byes. Just use a RawSourceWaveStream and pass in your MemoryStream.

You may also find the AudioFileReader class more suitable to your needs as it will provide the samples as floating point directly, and allow you to modify the volume.