在使用 Naudio 播放文件时检测当前音量

Posted

技术标签:

【中文标题】在使用 Naudio 播放文件时检测当前音量【英文标题】:Detect current volume level while a file is playing using Naudio 【发布时间】:2012-10-30 15:39:46 【问题描述】:

所以我有

    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();
    

有一个停止按钮 ( button1 ),用于停止播放。加载表单时,将播放文件。在播放文件时,我想通过运行一个函数来获取文件的当前音量。那么像这样的函数在“....”中应该是什么样子的呢?

private int currentVolumeLevel(...some suitable parameters...)

  int currentVolumeLevelValue = 0;
  //....
  return currentVolumeLevelValue;

我不是在谈论您可以通过 Windows 的声音控件调节的音量。我说的是当前播放的声音文件在它正在播放的这个位置的音量,基于类似 byte[] 数组的东西。

【问题讨论】:

【参考方案1】:

NAudioDemo 展示了如何做到这一点。在AudioPlaybackPanel.cs 中查看如何将MeteringSampleProvider 添加到播放管道中。 MeteringSampleProvider 将定期引发 StreamVolume 事件,告诉您在过去 100 毫秒内收到的最大样本值(这是可配置的)。您需要决定是否要将MeteringSampleProvider放置在任何软件音量调整之前或之后(对于波形绘制,通常在之前,对于音量测量,通常在之后)

这是一个有效的 WindowsForms 演示,将流卷写入控制台:

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();

【讨论】:

我根据您的回复创建了pastebin.com/AsctdcGU,但表单标题没有变化,即您的事件没有触发。 您没有通过计量样品提供者拉取任何东西。我会用一个简短的演示来更新我的答案

以上是关于在使用 Naudio 播放文件时检测当前音量的主要内容,如果未能解决你的问题,请参考以下文章

NAudio 峰值音量计

如何使用Naudio分别控制耳机左右声道的音量

在 UWP 中使用 NAudio 播放多个音频文件

使用 NAudio 使用 asioout 录制时如何使声音更大?

使用 NAudio 标准化 32 位 PCM Wav 中的音量

C# - 使用外部 Midi 控制器更改音量