使用Naudio进行RawSourceWaveStream音量控制和播放时间估计

时间:2015-06-15 14:11:49

标签: audio volume naudio

我正在使用Naudio播放内存中的音频样本。

        private RawSourceWaveStream waveStream;
        private MemoryStream ms;
        private int sampleRate = 48000;
        private IWavePlayer wavePlayer;

        //generate sine wave signal
        short[] buffer = new short[(int)Math.Round(sampleRate * 10.00)];
        double amplitude = 0.25 * short.MaxValue;
        double frequency = 1000;
        for (int n = 0; n < buffer.Length; n++)
        {
            buffer[n] = (short)(amplitude * Math.Sin((2 * Math.PI * n * frequency) / sampleRate));
        }
        byte[] byteBuffer = new byte[buffer.Length * sizeof(short)];
        Buffer.BlockCopy(buffer, 0, byteBuffer, 0, byteBuffer.Length);

        //create audio player to play samples from memory
        ms = new MemoryStream(byteBuffer);
        waveStream = new RawSourceWaveStream(ms, new WaveFormat(sampleRate, 16, 1));
        //wavePlayer = new WaveOutEvent();
        wavePlayer = new DirectSoundOut();

        wavePlayer.Init(waveStream);
        wavePlayer.PlaybackStopped += wavePlayer_PlaybackStopped;

我想分别控制每个流的RawSourceWaveStream音量。 (我将播放多个流)。

1)使用wavePlayer.Volume = volumeSlider1.Volume;就足够了?它已被弃用。

2)我看到AudioFileReader使用SampleChannel进行音量控制。如果我重写RawSourceWaveStream的Read方法并添加Volume Property应该是一个很好的解决方案吗?

3)我希望尽可能好地回放时间估计(毫秒级)。我看到WaveOutEvent的时间分辨率大约是几百毫秒。 DirectSoundOut的时间分辨率更好,但仍然不够。

提前谢谢!

1 个答案:

答案 0 :(得分:0)

1)是的,您可以使用WaveOut.Volume。另一个选择是使用VolumeSampleProvider之类的东西在我们的信号链中而不是在设备上进行音量

2)无需重写 - 调用.ToSampleProvider()扩展方法,然后通过VolumeSampleProvider

传递

3)RawSourceStream上的Position显示您已读取文件的距离,但不准确显示回放的位置,因为某些音频可能仍然可以缓冲以备播放。查看GetPosition()上的WaveOut,它返回到目前为止播放的字节数,是最准确的选项。