简体   繁体   English

简单的VST合成器以随机间隔更改音高

[英]Simple VST Synth Changes Pitch at Random Intervals

I'm learning how to use the Steinberg VST 2.4 SDK (or rather, the 2.x portion that comes with the 3.6.0 version). 我正在学习如何使用Steinberg VST 2.4 SDK(或更确切地说,是3.6.0版本随附的2.x部分)。 I've created a simple synthesizer designed to play a sine wave at a constant frequency during its lifetime. 我创建了一个简单的合成器,该合成器旨在在其生命周期内以恒定频率播放正弦波。 Here is the code for this synth: 这是此合成器的代码:

static const float TAU = 3.14159f * 2;

AudioEffect* createEffectInstance(audioMasterCallback audioMaster) {
    return new VSTTest(audioMaster);
}

VSTTest::VSTTest(audioMasterCallback audioMaster) : AudioEffectX(audioMaster, 0, NUM_PARAMS), //NUM_PARAMS is 0
                                                    fDeltaTime(1.0f / getSampleRate()), //time per sample (1.0 / 44100, presumably)
                                                    fFrequency(100.0f), //frequency of the wave (100 Hz)
                                                    fAmplitude(0.5f), //amplitude of the wave
                                                    fPos(0.0f) { //position of the wave in the x direction
    setNumInputs(0);
    setNumOutputs(2);
    canProcessReplacing();
    isSynth();
}

VSTTest::~VSTTest(void) {

}

void VSTTest::processReplacing(float** input, float** output, VstInt32 numFrames) {
    for (VstInt32 i = 0; i < numFrames; i++) {
        output[0][i] = fAmplitude * sin(fPos);
        output[1][i] = fAmplitude * sin(fPos);

        fPos += fFrequency * TAU * fDeltaTime;

        if (fPos >= TAU) {
            fPos = fmod(fPos, TAU);
        }
    }
}

void VSTTest::setSampleRate(float fSampleRate) {
    fDeltaTime = 1.0f / fSampleRate;
}

The problem is that when the VST is loaded as a channel in FL Studio, I can hear (and see) it changing pitch a couple of times over about 20 seconds until it settles on a final pitch that isn't even correct (deviates by about 10 Hz). 问题是,当VST在FL Studio中作为频道加载时,我可以听到(并看到)它在大约20秒钟内几次改变音高,直到它稳定在甚至不正确的最终音高上(按约10 Hz)。 Why is this happening? 为什么会这样呢?

您正在向fPos添加一个巨大的数字,应该将其增加1。您正在寻找的公式是:

sinf(2.0 * M_PI * fPos++ * fFrequency / fSampleRate);

Well this isn't exactly a complete answer, but this was solved by calculating the delta time in resume(). 好吧,这并不是一个完整的答案,但这可以通过计算resume()中的增量时间来解决。

void VSTTest::resume(void) {
    fDeltaTime = 1.0 / getSampleRate();
}

I'm not sure why this needs to be done or how it solves the problem, but it does. 我不确定为什么需要这样做或如何解决问题,但确实如此。 Also, I should note that fDeltaTime should not be initialized in the constructor since there's no guarantee getSampleRate() is correct at that time. 另外,我应该注意,不应在构造函数中初始化fDeltaTime ,因为不能保证此时的getSampleRate()是正确的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM