简体   繁体   中英

Detect current volume level while a file is playing using Naudio

So I have

    IWavePlayer waveOutDevice;
    WaveStream mainOutputStream;
    WaveChannel32 volumeStream;

    private WaveStream CreateInputStream(string fileName)
    {
        WaveChannel32 inputStream;
        if (fileName.EndsWith(".mp3"))
        {
            WaveStream mp3Reader = new Mp3FileReader(fileName);
            inputStream = new WaveChannel32(mp3Reader);
        }
        else
        {
            throw new InvalidOperationException("Unsupported extension");
        }
        volumeStream = inputStream;
        return volumeStream;
    }

    private void Stop()
    {
        if (waveOutDevice != null)
        {
            waveOutDevice.Stop();
        }
        if (mainOutputStream != null)
        {
            // this one really closes the file and ACM conversion
            volumeStream.Close();
            volumeStream = null;
            // this one does the metering stream
            mainOutputStream.Close();
            mainOutputStream = null;
        }
        if (waveOutDevice != null)
        {
            waveOutDevice.Dispose();
            waveOutDevice = null;
        }
    }

    private void Play(string was)
    {
        waveOutDevice = new WaveOut();
        mainOutputStream = CreateInputStream(was);
        waveOutDevice.Init(mainOutputStream);
        waveOutDevice.Play();

    }

    private void Form1_Load(object sender, EventArgs e)
    {
        Play(@"E:\Eigene Audiodateien\Musik\Alben\Pur\Abenteuerland\ -  - .mp3");
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Stop();
    }

There is a Stop-Button ( button1 ), which stops playback. When the form is loaded, the file is played. While the file is playing I want to get the current volume of the file by running a function. So what does a function like this has to look like at "...."?

private int currentVolumeLevel(...some suitable parameters...)
{
  int currentVolumeLevelValue = 0;
  //....
  return currentVolumeLevelValue;
}

I am not talking about the volume level you can adjust with windows' sound controls. I am talking about the currently played sound file's volume at this very position it is playing right now, based on something like a byte[] array.

The NAudioDemo shows how to do this. Look in AudioPlaybackPanel.cs at how a MeteringSampleProvider is added to the playback pipeline. MeteringSampleProvider will periodically raise StreamVolume events telling you the maximum sample value you have received in the last 100ms (this is configurable). You will need to decide whether you want to place the MeteringSampleProvider before or after any software volume adjustment (for waveform drawing it is usually before, and for volume metering it is usually after)

Here's a working WindowsForms demo, writing the stream volume to the Console:

var player = new WaveOut();
var file = new AudioFileReader(@"test.mp3");
var meter = new MeteringSampleProvider(file);
meter.StreamVolume += (s,e) => Console.WriteLine("{0} - {1}", e.MaxSampleValues[0],e.MaxSampleValues[1]);
player.Init(new SampleToWaveProvider(meter));

var form = new Form();
form.Load += (s,e) => player.Play();
form.FormClosed += (s,e) => player.Dispose();
form.ShowDialog();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM