局部变量的赋值导致音频在 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 中停止处理的主要内容,如果未能解决你的问题,请参考以下文章