views:

557

answers:

3

Hi, this question derives from my previous thread Play mp3 from internet without FileOpenDialog

I really hope someone knows anything about this. I was told to use a WebRequest to start a download stream and then play the stream instead of playing a locally stored file. However, trying to use the code from PlayMp3FromUrl gives me this error:

"'NAudio.Wave.WaveOut' does not contain a constructor that takes '3' arguments"

Compiling failes at this line:

using (WaveOut waveOut = new WaveOut(0, 500, null))

This is the full code:

public static void PlayMp3FromUrl(string url)
    {
        using (MemoryStream ms = new MemoryStream())
        {
            using (Stream stream = WebRequest.Create(url)
                .GetResponse().GetResponseStream())
            {
                byte[] buffer = new byte[32768];
                int read;
                while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    ms.Write(buffer, 0, read);
                }
            }

            ms.Position = 0;

            using (WaveStream blockAlignedStream =
                new BlockAlignReductionStream(
                    WaveFormatConversionStream.CreatePcmStream(
                        new Mp3FileReader(ms))))
            {
                using (WaveOut waveOut = new WaveOut(0, 500, null))
                {
                    waveOut.Init(blockAlignedStream);
                    waveOut.Play();
                    while (blockAlignedStream.Position < blockAlignedStream.Length)
                    {
                        System.Threading.Thread.Sleep(100);
                    }
                }
            }
        }
    }

Can someone help me find out which arguments the WaveOut takes?

Edit: You probably want to look at the WaveOut.cs, and it's pretty long. So just have a look at it here WaveOut.cs

A: 

You are passing three arguments to the WaveOut constructor: 0, 500, null but there is no constructor on the WaveOut class that takes that many arguments.

Why are you passing three arguments to the WaveOut constructor?

Chris Dunaway
This is because the code looks like that by the person who wrote it, in this Stackoverflow-link: http://stackoverflow.com/questions/184683/play-audio-from-a-stream-using-c
Kenny Bones
I guess WaveOut.cs has changed or something since then. But I can't figure out which arguments to pass.
Kenny Bones
+1  A: 

I've never used the waveout class, I would suggest using DirectX if you could.

using (IWavePlayer directOut = new DirectSoundOut(300))               
{                    
   directOut.Init(blockAlignedStream);                    
   directOut.Play();                    
   while (blockAlignedStream.Position < blockAlignedStream.Length)
   {                       
      System.Threading.Thread.Sleep(100);                    
   }                
}
Will
Wow, this actually works :) But the program still freezes (while playing the mp3 file), what could be causing this issue? It seems hard to debug as well since alot of stuff is happening in the code. And I can't really tell what might be causing it.
Kenny Bones
Your while loop is blocking your program. Make the player a class field and run start stop commands into it, or take care of it in a different thread.
Will
Ok, I have no idea how to do just that. Would it require alot of changes? And another thing, do you know how the stream is stored locally? Will I play back the downloaded cache or do the download again no matter what? I would really like some kind of cache. Like OpenFileDialog does by itself. Would it be possible for this, as far as you know? And yes, I suck at C#.. I tried to do this with VB.NET but I ran into difficulties. So I thought I'd try the C# original source instead.
Kenny Bones
+1  A: 

Just use the default constructor (no parameters). The very latest NAudio code has properties on the WaveOut class instead of the old constructor with 3 parameters. If it causes lots of problems I might put the old constructor back though and mark it with the [Obsolete] attribute.

The first parameter was the device number. 0 means use the default device.

The second was the latency. 500ms is the amount of audio we buffer up in advance. This is a very conservative figure and should ensure glitch free playback.

The third is to do with the callback mechanism for waveOut. Unfortunately there is no one-size-fits all solution. If you pass null, NAudio will use function callbacks, but this can hang on certain audio chipsets. It's better to pass a window handle if at all possible.

Mark Heath
Hi Mark! I've already tried to use no parameters. And this causes the form to freeze completely. And the playback didn't seem to work either. Using DirectSoundOut freezes the form as well, but the playback works, after like 3-4 seconds or so. Unfortunately, I'm a complete moron so I wouldn't know how to pass a window handle. I think I know what it means, you've written something about it in documentation or similar. But I wouldn't know how to do just that because of the reason stated above.
Kenny Bones