问题
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.
回答1:
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();
来源:https://stackoverflow.com/questions/13142569/detect-current-volume-level-while-a-file-is-playing-using-naudio