局部变量的赋值导致音频在 JUCE 中停止处理

Posted

技术标签:

【中文标题】局部变量的赋值导致音频在 JUCE 中停止处理【英文标题】:Assignment of local variables causes Audio to stop processing in JUCE 【发布时间】:2017-08-20 22:04:20 【问题描述】:

编辑:结果证明这是一个未初始化的变量,造成混乱行为。有关获得更多 JUCE 编译器警告的信息,请参阅 this post

我试图创建一个基本的合成器,但在尝试为新声明的变量赋值时很快遇到了一个荒谬的问题。 在遵循 JUCE 简单正弦合成教程之后,我遇到了问题。这是我的getNextAudioBlock() 函数在产生白噪声时的基本代码。请注意在整个过程中如何声明和分配四个整数:

const int numChannels = bufferToFill.buffer->getNumChannels();
const int numSamples = bufferToFill.numSamples;
for (int channel = 0; channel < numChannels; channel++)
    float* const buffer = bufferToFill.buffer -> getWritePointer(channel, bufferToFill.startSample);
    for (int sample; sample < numSamples; sample++)
        buffer[sample] = (randomGen.nextFloat() * 2.0f - 1.0f);
    

但是,一旦我尝试添加另一个 int,我就再也听不到声音了。只需在 getNextAudioBlock() 函数中的任意位置添加 int unusedVariable = 0; 行,但在 buffer[sample] 赋值之前立即从函数返回,因此不会产生音频。

如果我只是声明新变量 (int unusedVariable;),那么它仍然有效。仅具体是导致错误的分配部分。另外,如果我将变量声明为全局成员,那么函数内的赋值就可以正常工作。

重申一下,这是可行的:

buffer[sample] = (randomGen.nextFloat() * 2.0f - 1.0f;

这行得通:

int unusedVariable;
buffer[sample] = (randomGen.nextFloat() * 2.0f - 1.0f;

但这不是:

int unusedVariable = 0;
buffer[sample] = (randomGen.nextFloat() * 2.0f - 1.0f;

我唯一的想法是在音频线程上分配新内存会导致错误,但我已经看到在其他在线资源中完成声明和分配,甚至在我完全相同的函数中使用 numChannels、numSamples、channel 和 sample 全部分配和分配正好。我还认为它与使用 Random 类有关,但即使它生成正弦波,我也会遇到同样的问题。

编辑:这是从项目中复制的确切代码。这里 nextSample 是全局声明的,因为在本地声明缓冲区时缓冲区不会被填满

  void MainContentComponent::getNextAudioBlock (const AudiosourceChannelInfo& bufferToFill)
  
    const int numChannels = bufferToFill.buffer->getNumChannels();
    const int numSamples = bufferToFill.numSamples;
    for (int channel = 0; channel < numChannels; channel++)
        float* const buffer = bufferToFill.buffer -> getWritePointer (channel, bufferToFill.startSample);
        for (int sample; sample < numSamples; sample++)
            // nextSample = (randomGen.nextFloat() * 2.0f - 1.0f); // For Randomly generated White Noise
            nextSample = (float) std::sin (currentAngle);
            currentAngle += angleDelta;
            buffer[sample] = nextSample * volumeLevel;
        
    
  

【问题讨论】:

可能不是您的问题的解决方案,但for (int channel = 0; numChannels; channel++) 中的条件numChannels 是有意的吗?它很可能会产生无限循环。 对不起,我的原始代码正确地说是 (...; channel 请在此处粘贴真实代码。 buffer[sample] = (randomGen.nextFloat() * 2.0f - 1.0f; 甚至无法编译,因为缺少关闭 )。或者实际提供mcve。 我添加了确切的代码并链接到 FirstSynth 和 AdditiveManual,这两个项目仅在变量是全局成员时才有效 @brenthompson2 -- 如果您是付费被许可人并且实时构建不适合您,您应该在 JUCE 论坛forum.juce.com 上发帖,该论坛由 JUCE 开发团队监控。跨度> 【参考方案1】:

我在 Projucer 中创建了一个新的 AudioApplication 项目,并将这段代码粘贴到 getNextAudioBlock() 方法中(添加明智的成员变量,因为您在此处引用它们)。

编译器立即指出了问题——下面的循环变量sample 没有初始化(C++ 不会默认为你初始化它),所以如果该变量使用的内存恰好包含一个小于缓冲区大小的值,您将生成一些音频;如果不是,则传递给此函数的缓冲区不受影响,因为循环永远不会运行。

    for (int sample; sample < numSamples; sample++)
        nextSample = (randomGen.nextFloat() * 2.0f - 1.0f); // For Randomly generated White Noise
        //nextSample = (float) std::sin (currentAngle);
        //currentAngle += angleDelta;
        buffer[sample] = nextSample * volumeLevel;
    

看看将其更改为 for (int sample=0; 是否不能为您解决问题。

【讨论】:

非常感谢。这很有意义。我会在早上试试。你用的是什么编译器? Xcode 8,但我希望这里的行为在任何地方都同样不可预测——请参阅这个 SO 答案:***.com/questions/1597405/… 这就是解决方案。它还解决了我的音频没有输出到两个通道的问题。现在只要I can figure out how to compile with those warnings on my Ubuntu machine...

以上是关于局部变量的赋值导致音频在 JUCE 中停止处理的主要内容,如果未能解决你的问题,请参考以下文章

在 DB2 PL/SQL 匿名块中声明局部变量和声明继续处理程序会导致错误?

赋值前引用的局部变量?

在python中赋值之前引用的局部变量'form'

对象方法中的局部变量音频未播放

Python基础局部变量全局变量,递归的特性——07

mysql补充:局部变量