在 C# 中分别更改 wave 文件左右音量
Change wave file left and right volumes separately in C#
我正在处理 Wave 文件(立体声文件),我想将系统音量设置为最大并使用滚动条改变 wave 文件的声音。
即系统音量应该是 100%,我想在 60dB 到 100dB 的范围内播放我的 wave 文件,并且总是 wave 文件左声道和右声道音量不一样。 (左声道可能播放 60dB,右声道可能播放 70dB)。
为了实现这一点,我使用了 CSCore 音频库,因为我的项目是在 C# 上开发的。
// Creating the Wave source from the source file
IWaveSource waveSource = CodecFactory.Instance.GetCodec("C:\SampleWave.wav");
WasAPIOut mWasAPIOutObj = new WasapiOut();
AudioEndOutputVolume aeovObj = AudioEndpointVolume.FromDevice(_soundOut.Device);
// Getting the maximum and minimum volume range of Wave source.
aeovObj.GetVolumeRange(out vMinDB, out vMaxDB, out vIncrDB);
// Setting the System Master Volume to maximum (100%)
aepv.SetMasterVolumeLevel(vMaxDB, Guid.Empty);
// I want to play the wave file in a loop, so pushing the wave file to loop stream
LoopStream stream = new LoopStream(waveSource);
mWasAPIOutObj.Initialize(stream);
在播放波形文件之前,我想将我的波形文件左声道设置为 60 dB,右声道设置为 70dB,然后开始播放。
mWasAPIOutObj.Play();
mWasAPIOutObj.Volume
属性 仅取 0.0 到 1.0 之间的单个值。这里不讨论任何频道。
我需要在 WaveSource 级别设置音量吗?
我也浏览过 NAudio 音频库,但无法找到解决方案。
ArgumentOutOfRange 异常的堆栈跟踪:
at CSCore.SampleSourceBase.Read(Single[] buffer, Int32 offset, Int32 count)
at SampleTool.VPWaveSource.Read(Single[] buffer, Int32 offset, Int32 count) in c:\****\*****\Projects\Sample Tool\Try\SampleTool\SampleTool\SoundManager.cs:line 308
at CSCore.Streams.SampleConverter.SampleToIeeeFloat32.Read(Byte[] buffer, Int32 offset, Int32 count)
at CSCore.WaveAggregatorBase.Read(Byte[] buffer, Int32 offset, Int32 count)
at CSCore.Streams.LoopStream.Read(Byte[] buffer, Int32 offset, Int32 count)
at CSCore.SoundOut.WasapiOut.FeedBuffer(AudioRenderClient renderClient, Byte[] buffer, Int32 numFramesCount, Int32 frameSize)
at CSCore.SoundOut.WasapiOut.PlaybackProc(Object playbackStartedEventWaithandle)
谁能帮我解决这个问题。
提前致谢。
我不确定这段代码能否编译,但我猜是你的意图。 SetChannelVolumeLevelNative API 允许您设置每个通道的 dB 设置,而不是 SetMasterVolume。
您可以简单地创建一个新来源:
class ChannelVolumeControlSource : SampleSourceBase
{
public ChannelVolumeControlSource(ISampleSource source) : base(source)
{
if(source.WaveFormat.Channels != 2)
throw new ArgumentException("Source must have two channels.", "source");
}
//todo: add some validation -> make sure only values between 0 and 1 are allowed.
public float VolumeLeft { get; set; }
public float VolumeRight { get; set; }
public override int Read(float[] buffer, int offset, int count)
{
int read = base.Read(buffer, offset, count);
for (int i = 0; i < read; i+=2)
{
buffer[i] *= VolumeLeft;
buffer[i + 1] *= VolumeRight;
}
return read;
}
}
用法:
var channelVolumeSourceControl = new ChannelVolumeControlSource(stream.ToSampleSource());
mWasAPIOutObj.Initialize(channelVolumeSourceControl.ToWaveSource());
//control the volume during playback by setting the volume properties
channelVolumeSourceControl.VolumeLeft = 0.5f; //left channel 50%
channelVolumeSourceControl.VolumeRight = 1.0f; //right channel 100%
我正在处理 Wave 文件(立体声文件),我想将系统音量设置为最大并使用滚动条改变 wave 文件的声音。 即系统音量应该是 100%,我想在 60dB 到 100dB 的范围内播放我的 wave 文件,并且总是 wave 文件左声道和右声道音量不一样。 (左声道可能播放 60dB,右声道可能播放 70dB)。
为了实现这一点,我使用了 CSCore 音频库,因为我的项目是在 C# 上开发的。
// Creating the Wave source from the source file
IWaveSource waveSource = CodecFactory.Instance.GetCodec("C:\SampleWave.wav");
WasAPIOut mWasAPIOutObj = new WasapiOut();
AudioEndOutputVolume aeovObj = AudioEndpointVolume.FromDevice(_soundOut.Device);
// Getting the maximum and minimum volume range of Wave source.
aeovObj.GetVolumeRange(out vMinDB, out vMaxDB, out vIncrDB);
// Setting the System Master Volume to maximum (100%)
aepv.SetMasterVolumeLevel(vMaxDB, Guid.Empty);
// I want to play the wave file in a loop, so pushing the wave file to loop stream
LoopStream stream = new LoopStream(waveSource);
mWasAPIOutObj.Initialize(stream);
在播放波形文件之前,我想将我的波形文件左声道设置为 60 dB,右声道设置为 70dB,然后开始播放。
mWasAPIOutObj.Play();
mWasAPIOutObj.Volume
属性 仅取 0.0 到 1.0 之间的单个值。这里不讨论任何频道。
我需要在 WaveSource 级别设置音量吗?
我也浏览过 NAudio 音频库,但无法找到解决方案。
ArgumentOutOfRange 异常的堆栈跟踪:
at CSCore.SampleSourceBase.Read(Single[] buffer, Int32 offset, Int32 count)
at SampleTool.VPWaveSource.Read(Single[] buffer, Int32 offset, Int32 count) in c:\****\*****\Projects\Sample Tool\Try\SampleTool\SampleTool\SoundManager.cs:line 308
at CSCore.Streams.SampleConverter.SampleToIeeeFloat32.Read(Byte[] buffer, Int32 offset, Int32 count)
at CSCore.WaveAggregatorBase.Read(Byte[] buffer, Int32 offset, Int32 count)
at CSCore.Streams.LoopStream.Read(Byte[] buffer, Int32 offset, Int32 count)
at CSCore.SoundOut.WasapiOut.FeedBuffer(AudioRenderClient renderClient, Byte[] buffer, Int32 numFramesCount, Int32 frameSize)
at CSCore.SoundOut.WasapiOut.PlaybackProc(Object playbackStartedEventWaithandle)
谁能帮我解决这个问题。
提前致谢。
我不确定这段代码能否编译,但我猜是你的意图。 SetChannelVolumeLevelNative API 允许您设置每个通道的 dB 设置,而不是 SetMasterVolume。
您可以简单地创建一个新来源:
class ChannelVolumeControlSource : SampleSourceBase
{
public ChannelVolumeControlSource(ISampleSource source) : base(source)
{
if(source.WaveFormat.Channels != 2)
throw new ArgumentException("Source must have two channels.", "source");
}
//todo: add some validation -> make sure only values between 0 and 1 are allowed.
public float VolumeLeft { get; set; }
public float VolumeRight { get; set; }
public override int Read(float[] buffer, int offset, int count)
{
int read = base.Read(buffer, offset, count);
for (int i = 0; i < read; i+=2)
{
buffer[i] *= VolumeLeft;
buffer[i + 1] *= VolumeRight;
}
return read;
}
}
用法:
var channelVolumeSourceControl = new ChannelVolumeControlSource(stream.ToSampleSource());
mWasAPIOutObj.Initialize(channelVolumeSourceControl.ToWaveSource());
//control the volume during playback by setting the volume properties
channelVolumeSourceControl.VolumeLeft = 0.5f; //left channel 50%
channelVolumeSourceControl.VolumeRight = 1.0f; //right channel 100%