使用NAudio在指定位置应用线性淡入淡出 [英] Applying a linear fade at a specify position using NAudio

查看:263
本文介绍了使用NAudio在指定位置应用线性淡入淡出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在我编写的C#程序中使用 NAudio .

I am making use of NAudio in a C# program I've written.

我想在正在处理的音频中的某个位置应用线性淡入.

在NAudio示例项目中有一个名为FadeInOutSampleProvider.cs的文件(

In the NAudio example project is a file called FadeInOutSampleProvider.cs (Cached example) which has BeginFadeIn(double fadeDurationInMilliseconds) and BeginFadeOut(double fadeDurationInMilliseconds) methods.

我对这些方法进行了重新设计 BeginFadeOut(double fadeDurationInMilliseconds, double beginFadeAtMilliseconds)BeginFadeOut(double fadeDurationInMilliseconds, double beginFadeAtMilliseconds)

I've reworked these methods to BeginFadeOut(double fadeDurationInMilliseconds, double beginFadeAtMilliseconds) and BeginFadeOut(double fadeDurationInMilliseconds, double beginFadeAtMilliseconds)

但是我很难为这些更改实现间隔逻辑.

However I'm having difficulty implementing the interval logic for these changes to work.

我的第一个想法是在Read()方法中引入代码.调用时,它会将请求的字节数除以采样率,从而得出请求的音频秒数.

My first thought was to introduce code in the Read() method. When called it would divide the number of bytes being requested by the sample rate, which would give the number of seconds of audio requested.

然后我可以跟踪此情况,并在读取了正确数量的自动数据后,允许应用渐变.

I could then keep track of this and when the correct amount of auto data had been read, allow the fade to be applied.

但是我在计算中没有得到期望的数字.我相信有更好的方法来解决这个问题.

However I'm not getting the numbers in my calculations I would expect to see. I'm sure there's a better way to approach this.

任何帮助将不胜感激.

推荐答案

听起来您正在按照正确的方向工作.正如您所说,可以通过将请求的样本数除以采样率来计算所请求的音频量.但是,您还必须考虑渠道.在立体声文件中,每秒的采样数是采样率的两倍.

It sounds like you are working along the right lines. As you say the amount of audio being requested can be calculated by dividing number of samples requested by the sample rate. But you must also take into account channels as well. In a stereo file there are twice as many samples per second as the sample rate.

我在 GitHub要点这里放置了一个非常基本的延迟淡出代码示例.可以进行一些改进,例如允许淡入淡出从调用Read返回的音频中途开始,但希望这可以让您大致了解如何通过对以下内容进行一些小的修改来实现它: FadeInOutSampleProvider.

I've put a very basic code sample of a delayed fade out in a GitHub gist here. There are improvements that could be made such as allowing the fade-out to begin part-way through the audio returned from a call to Read but holpefully this gives you a rough idea of how it can be achieved with a few small modifications to FadeInOutSampleProvider.

主要更改是BeginFadeOut的一个额外参数,该参数设置了两个新变量(fadeOutDelaySamples,fadeOutDelayPosition):

The main changes are an extra parameter to BeginFadeOut, that sets two new variables (fadeOutDelaySamples, fadeOutDelayPosition):

/// <summary>
/// Requests that a fade-out begins (will start on the next call to Read)
/// </summary>
/// <param name="fadeDurationInMilliseconds">Duration of fade in milliseconds</param>
public void BeginFadeOut(double fadeAfterMilliseconds, double fadeDurationInMilliseconds)
{
    lock (lockObject)
    {
        fadeSamplePosition = 0;
        fadeSampleCount = (int)((fadeDurationInMilliseconds * source.WaveFormat.SampleRate) / 1000);
        fadeOutDelaySamples = (int)((fadeAfterMilliseconds * source.WaveFormat.SampleRate) / 1000);
        fadeOutDelayPosition = 0;

       //fadeState = FadeState.FadingOut;
   }
}

然后在Read方法中,我们可以跟踪延迟有多远,如果有,我们可以开始淡出

Then in the Read method we can keep track of how far into the delay we are, and if so, we can start the fade-out

public int Read(float[] buffer, int offset, int count)
{
   int sourceSamplesRead = source.Read(buffer, offset, count);

   lock (lockObject)
   {
        if (fadeOutDelaySamples > 0)
        {
            fadeOutDelayPosition += sourceSamplesRead / WaveFormat.Channels;
            if (fadeOutDelayPosition >= fadeOutDelaySamples)
            {
                fadeOutDelaySamples = 0;
                fadeState = FadeState.FadingOut;
            }
        }
       if (fadeState == FadeState.FadingIn)
       {
           FadeIn(buffer, offset, sourceSamplesRead);
       }
       else if (fadeState == FadeState.FadingOut)
       {
           FadeOut(buffer, offset, sourceSamplesRead);
       }
       else if (fadeState == FadeState.Silence)
       {
           ClearBuffer(buffer, offset, count);
       }
   }
   return sourceSamplesRead;
}

这篇关于使用NAudio在指定位置应用线性淡入淡出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆