使用 NAudio 改变左右声道的声音平衡

Posted

技术标签:

【中文标题】使用 NAudio 改变左右声道的声音平衡【英文标题】:Changing the sound balance in the right and left channels with NAudio 【发布时间】:2020-04-16 13:40:24 【问题描述】:

播放声音时,需要分别调节左右声道的音量。 我有课来播放声音:

public class SoundPlayer

    private WaveOutEvent _outputDevice;
    private AudioFileReader _audioFile;
    private float _volume = 1f;

    public float Volume
    
        get => _volume;
        set
        
            _volume = value;

            if (_audioFile != null)
                _audioFile.Volume = value;
        
    

    public void Play(string fileName)
    
        if (_outputDevice == null)
        
            _outputDevice = new WaveOutEvent();
            _outputDevice.PlaybackStopped += (sender, args) =>
            
                _outputDevice.Dispose();
                _outputDevice = null;
                _audioFile.Dispose();
                _audioFile = null;
            ;
        
        if (_audioFile == null)
        
            _audioFile = new AudioFileReader(fileName)  Volume = _volume ;
            _outputDevice.Init(_audioFile);

        
        else
        
            if (string.IsNullOrWhiteSpace(fileName))
                _outputDevice = null;
            else
            
                if (_audioFile.FileName != fileName)
                
                    _audioFile = new AudioFileReader(fileName)  Volume = _volume ;
                    _outputDevice.Init(_audioFile);
                
            
        

        _outputDevice?.Play();
    

    public void Stop()
    
        _outputDevice?.Stop();
    

但在本课程中,您只能调整整体音量。如何制作这样的财产: soundPlayer.LeftChannelVolume = 1.0f soundPlayer.RightChannelVolume = 0.5f

【问题讨论】:

【参考方案1】:

在 PanningSampleProvider 的帮助下制作。但为此,您必须转换为单声道。此外,对改变 Pan - 的反应会稍有延迟。如何避免这种情况?如何使用立体声并仅更改其左右声道的音量?我认为这应该会更快。

_audioFile = new AudioFileReader(_fileName)  Volume = _volume ;
var mono = new StereoToMonoSampleProvider(_audioFile)  LeftVolume = 1f, RightVolume = 1f ;
var panner = new PanningSampleProvider(mono);

_outputDevice.Init(panner);

【讨论】:

【参考方案2】:

我创建了我的提供者,它成功了!) 如果有人需要它,那么在这里:

/// <summary>
/// Very simple sample provider supporting adjustable gain
/// </summary>
public class VolumeStereoSampleProvider : ISampleProvider

    private readonly ISampleProvider source;

    /// <summary>
    /// Allows adjusting the volume left channel, 1.0f = full volume
    /// </summary>
    public float VolumeLeft  get; set; 

    /// <summary>
    /// Allows adjusting the volume right channel, 1.0f = full volume
    /// </summary>
    public float VolumeRight  get; set; 

    /// <summary>
    /// Initializes a new instance of VolumeStereoSampleProvider
    /// </summary>
    /// <param name="source">Source sample provider, must be stereo</param>
    public VolumeStereoSampleProvider(ISampleProvider source)
    
        if (source.WaveFormat.Channels != 2)
            throw new ArgumentException("Source sample provider must be stereo");

        this.source = source;
        VolumeLeft = 1.0f;
        VolumeRight = 1.0f;
    

    /// <summary>
    /// WaveFormat
    /// </summary>
    public WaveFormat WaveFormat => source.WaveFormat;

    /// <summary>
    /// Reads samples from this sample provider
    /// </summary>
    /// <param name="buffer">Sample buffer</param>
    /// <param name="offset">Offset into sample buffer</param>
    /// <param name="sampleCount">Number of samples desired</param>
    /// <returns>Number of samples read</returns>
    public int Read(float[] buffer, int offset, int sampleCount)
    
        int samplesRead = source.Read(buffer, offset, sampleCount);

        for (int n = 0; n < sampleCount; n += 2)
        
            buffer[offset + n] *= VolumeLeft;
            buffer[offset + n + 1] *= VolumeRight;
        

        return samplesRead;
    

【讨论】:

以上是关于使用 NAudio 改变左右声道的声音平衡的主要内容,如果未能解决你的问题,请参考以下文章

使用 NAudio 在特定频道上播放声音

iOS 使用 AudioQueueNewOutput 在左右声道输出声音

NAudio 通过我的代码设置左右扬声器电平(平衡控制)

Android 左右声道

NAudio 与 MultiplexingSampleProvider 和 WasapiOut

电子学会图形化scratch编程等级考试一级真题答案解析(选择题)2020-9A卷