This project has moved. For the latest updates, please go here.

Detecting Audio Level of a Stream, but not from device

Mar 15, 2013 at 5:46 PM
I would like to be able to determine the sound or audio level of an mp3 stream. I see how to do it using a device. However, if there are other sounds playing on the system, I believe this will reflect other sounds coming through the speaker/device and give a false reading. Any help or direction would be appreciated. --Thanks
Mar 16, 2013 at 8:27 AM
Simply take a look at the Naudiodemo shown on the front page: http://i3.codeplex.com/Download?ProjectName=naudio&DownloadId=46923
Mar 16, 2013 at 12:47 PM
... But not from a device.

From what I have tested, all the examples are getting the audio level from the sound card and not the stream. If I have some other application playing sound, it will also show audio levels from the sound card device.

Here is another example. Lets say I have two streams going at the same exact time, both playing music. how would I detect or display audio levels of each stream independently. I do not want to get the audio level from the device (sound card), as this will show the combined audio levels.
Mar 17, 2013 at 2:01 PM
Again see my previous answer.
The Naudiodemo uses realtime level detection of a stream playback. So where's your problem. Just try it out yourself. Play anything on your computer and take a look at the Demoapp. There won't be any level shown.
Mar 20, 2013 at 9:14 PM
Ok, I see what you're talking about. The demo does have both examples. However, I have been testing with code form the demo and cannot seem to get both examples combined. I need to stream a mp3, monitor volume level, and be able to adjust the volume too.

I found this snipit and it seems to work. But I can't integrate it into my test class. I'm confused as to how to use the SampleProviders.

......................................................................................................
var player = new NAudio.Wave.WaveOut();
var file = new NAudio.Wave.AudioFileReader(@"D:\Media\World's Largest Flash Mob - Audio.mp3");
var meter = new NAudio.Wave.SampleProviders.MeteringSampleProvider(file);
meter.StreamVolume += (s, e) => Console.WriteLine("{0} - {1}", e.MaxSampleValues[0], e.MaxSampleValues[1]);
player.Init(new NAudio.Wave.SampleProviders.SampleToWaveProvider(meter));
var form = new Form();
form.Load += (s, e) => player.Play();
form.FormClosed += (s, e) => player.Dispose();
form.ShowDialog();
......................................................................................................

Also, here is my test class that I'm working on for proof of concept. I would like to be able to create the class, adjust volume, and monitor the output/sample levels. Here is how I'm calling the class to test it.

......................................................................................................
using (TestStream _Stream = new TestStream(@"http://radio.reaper.fm/stream/"))
{
_Stream.Play();
System.Threading.Thread.Sleep(2000);
_Stream.SetVolume(0.5f); // Decrease Volume
System.Threading.Thread.Sleep(2000);
_Stream.SetVolume(1.5f); // Over Increase Volume
System.Threading.Thread.Sleep(2000);
_Stream.SetVolume(1); // Set Back To Normal
System.Threading.Thread.Sleep(30000);
_Stream.Stop();
System.Threading.Thread.Sleep(1000);
}
......................................................................................................

Here is my test class with the basics

......................................................................................................
public class TestStream : IDisposable
{
private System.Threading.Thread _StreamThread;
private System.IO.Stream _Stream = new System.IO.MemoryStream();
private NAudio.Wave.WaveStream _WaveStream;
private NAudio.Wave.WaveOut _WaveOut;
private const long _ChunkSize = 16384; // Testing (64k=65536, 32k=32768 16k=16384)

public void Dispose()
{
    if (_WaveOut.PlaybackState != NAudio.Wave.PlaybackState.Stopped)
    {
        this.Stop();
    }
    _WaveStream.Close();
    _WaveStream.Dispose();
    _WaveOut.Dispose();
    _Stream.Close();
    _Stream.Dispose();
    _StreamThread.Abort();
    _StreamThread.Join();
    System.Diagnostics.Debug.WriteLine("=> Disposed");
}

public TestStream(string UriString)
{
    _StreamThread = new System.Threading.Thread(delegate(object o)
                    {
                        System.Net.WebResponse response = System.Net.WebRequest.Create(UriString).GetResponse();
                        using (var stream = response.GetResponseStream())
                        {
                            byte[] buffer = new byte[_ChunkSize];
                            int read;
                            while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
                            {
                                var pos = _Stream.Position;
                                _Stream.Position = _Stream.Length;
                                _Stream.Write(buffer, 0, read);
                                _Stream.Position = pos;
                            }
                        }
                    });
    _StreamThread.Start();
    System.Diagnostics.Debug.WriteLine("=> Initialized");
}

public void Play()
{
    if (_Stream.Length < _ChunkSize * 5) // What increment should this be?
    {
        System.Diagnostics.Debug.WriteLine("=> Buffering");
        while (_Stream.Length < _ChunkSize * 5)
        { // Pre-buffering some data to allow NAudio to start playing
            System.Threading.Thread.Sleep(1000);
        }
    }
    _Stream.Position = 0;
    _WaveStream = new NAudio.Wave.BlockAlignReductionStream(NAudio.Wave.WaveFormatConversionStream.CreatePcmStream(new NAudio.Wave.Mp3FileReader(_Stream)));
    _WaveOut = new NAudio.Wave.WaveOut(NAudio.Wave.WaveCallbackInfo.FunctionCallback());
    _WaveOut.Init(_WaveStream);
    _WaveOut.Play();
    System.Diagnostics.Debug.WriteLine("=> Playing");
}

public void Stop()
{
    _WaveOut.Stop();
    System.Diagnostics.Debug.WriteLine("=> Stopped");
}

public void SetVolume(float Volume)
{
    // Adjust Volume for this stream
}

private void WriteVolumeMeterValues(object sender, NAudio.Wave.SampleProviders.StreamVolumeEventArgs e)
{
    System.Diagnostics.Debug.WriteLine(String.Format("VolumeMeter: {0} <==> {1}", e.MaxSampleValues[0], e.MaxSampleValues[1]));
}
}
......................................................................................................

If you or anyone reading this thread has any input or help, I would be appreciate it. If there is a better way to achieve my three goals, I would love some feedback.

Thanks in Advance