【问题标题】:Audio playback, creating nested loop for fade in/out音频播放,为淡入/淡出创建嵌套循环
【发布时间】:2010-03-07 21:17:29
【问题描述】:

第一次在这里发布海报。

关于在此处设置循环的快速问题。我想为主循环的前 1/3 设置一个 for 循环,它将增加一个从 .00001 或类似于 1 的值。所以我可以用它来乘以一个样本变量,以便创建一个淡入这个简单的音频文件播放例程。

到目前为止,这有点让人头疼,任何帮助都非常受欢迎。

for(i=0; i < end && !feof(fpin); i+=blockframes) 
{ 
    samples = fread(audioblock, sizeof(short), blocksamples, fpin); 
    frames = samples; 
    for(j=0; j < frames; j++)
    {   
        for (f = 0; f< frames/3 ;f++)
        {
            fade = fade--;
        } 
    output[j] = audioblock[j]/fade;
    }

    fwrite(output,sizeof(short), frames, fpoutput); 
} 

抱歉, 到目前为止,我已经成功读取并重写了文件。我的问题是我正在尝试找出一种方法来循环变量“fade”,以便它增加或减少到 1,以便我可以修改输出变量。

我想分 3 个阶段执行此操作: 1.从0到frames/3将倍增因子从0.0001增加到1 2. 从第 1/3 帧到第 2/3 帧什么都不做(乘以 1)和 3. 使因子再次减​​小到 1 以下,从而使输出变量减小回原点。

如何创建一个循环来增加和减少外部循环中的这些值?

【问题讨论】:

  • 欢迎来到 Stack Overflow。我们很乐意提供帮助,但您没有提出任何问题,也没有指出出现的问题。请使用“编辑”链接将该信息添加到您的帖子中。

标签: c audio fade playback synthesis


【解决方案1】:

我想你认为自己陷入了困境,这么说。无需创建嵌套循环来修改衰减增益,您可以简单地通过循环跟踪它并在必要时进行调整。此外,您对帧/样本的变量命名对我来说似乎有点混乱,我希望我做对了。

float fadeTime = 0.5f;
float outputGain = 0.0f;
float gainProgressionPerSample = 1.0f/(fadeTime*SAMPLERATE);
float fadeInStop = fadeTime*SAMPLERATE;
float fadeOutBegin;

for(i=0; i < end && !feof(fpin); i+=blockframes) 
{ 
    samples = fread(audioblock, sizeof(short), blocksamples, fpin); 
    fadeOutBegin = samples - fadeTime*SAMPLERATE;
    for(j=0; j < samples; j++)
    {
       if (j < fadeInStop)   
       {
         outputGain += gainProgressionPerSample;
       }
       // else is not used intentionally to allow fade in/out blending for short tracks
       if (j > fadeOutBegin)
       {
         outputGain -= gainProgressionPerSample;
       }
       output[j] = audioblock[j]*outputGain;
    }

    fwrite(output,sizeof(short), samples, fpoutput); 
} 

【讨论】:

  • @Johannes Rudolph 可能是我失明了,但我看不出这段代码是如何完成淡出部分的。
  • 是的,不这样做,但很容易添加。我现在太累了,明天再联系你。
  • 命名确实很混乱。原始例程将交错文件拆分为两个单声道文件。我已经将其分解以进行实验。因此这里和那里的双变量,有几行写每一第二个样本到单独的文件。
  • 如果 outputGain * progress 的总和最终不完全等于 1.0,那么此代码将超过 1.0 并不断增加增益。
  • @John:好地方,适应了褪色被时间束缚。关于他的日志淡出的好点。
【解决方案2】:

我的第一个观察:

fade = fade--;

不起作用,因为它相当于

int temp = fade - 1;
fade = fade;

这就是后增量运算符的工作方式。所以你应该简单地写

fade--;

改为(或 --fade - 随你喜欢 :-)。

然后你应该像这样构建你的循环:

for(j=0; j < frames/3; j++)
{   
    fade--;
    output[j] = audioblock[j]/fade;
}
for( ; j < 2*frames/3; j++)
{   
    output[j] = audioblock[j]/fade;
}
for( ; j < frames; j++)
{   
    fade++;
    output[j] = audioblock[j]/fade;
}

【讨论】:

  • @thorkia 的确如此,但话说回来,--fade 会以更简单的形式产生相同的效果。
【解决方案3】:

在现代处理器中,没有理由不使用浮点数进行数学运算。它更准确,性能与整数数学大致相同。而且,如果您使用的是浮点数,则没有理由不将所有临时变量都加倍。将它们声明为浮动实际上会降低性能。

此代码将为您提供超过(帧/3)个样本的线性淡入淡出

double gain = 0.0f;
double deltaGain = (1.0 - gain)/(frames/3);
for (int i=0; i < end && !feof(fpin); i += blockframes) 
{ 
    samples = fread(audioblock, sizeof(short), blocksamples, fpin); 

    j = 0;
    // do the fade in.
    for ( ; j < samples; ++j)
    {
       gain += deltaGain; // adjust the gain
       if (gain >= 1.0)
          break;

       output[j] = (short)(audioblock[j] * gain);
    }

    // copy the remainder.
    for ( ; j < samples; ++j)
       output[j] = audioblock[j];

    fwrite(output,sizeof(short), samples, fpoutput); 
} 

基本技巧是预先确定增益乘数的起点和终点,然后除以(结束-开始)/步长,以获得每个样本的增益应该改变的量。然后在你的内部循环中,调整增益只是一个补充。您可以在内部循环中只添加两个加法来获得 x 平方增益曲线。 x 平方是对数衰减的合理近似值,其中听起来更“自然”,因为我们的耳朵听到对数刻度。

【讨论】:

  • 你们摇滚!首先尝试了 Peters 代码。尽管“淡化”变量似乎等于否。循环结束时的样本数。虽然我可能是错的。然而,它确实会淡入淡出,但会导致削波。我假设省略了第二个 if 语句的 j=0 部分,只是让它从最后一个停止的地方开始。太好了,我不知道你能做到这一点。谢谢大家的帮助。 D.
猜你喜欢
  • 2014-06-12
  • 2015-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-23
  • 2011-11-19
  • 1970-01-01
相关资源
最近更新 更多