-2

所以,我正在使用 Arduino 的GinSing库,但遇到了问题。他们的代码中有一大块是从变量名(或对象?或其他东西?)中提取值。我已经阅读了关于变量名中有值的信息(堆栈溢出),我知道你不应该这样做,但我被困住了!

我不是一个足够好的程序员来修改他们的代码,但我仍然想使用它(GinSing shield 很酷)。以下是它们的用法示例s->setEnvelope

s->setEnvelope (OSC_1, AT_100MS, 1.0f, DR_100MS, 1.0f, DR_100MS, 0.0f);

我想随机更改这些值,所以我做了这个:

String adsrMake(String type, int attack){
    return type + attack + "MS";
}

然后我这样做:

 s->setEnvelope (OSC_1, adsrMake("AT_",time/2),  etc..

但它不喜欢那样。它不想要一个字符串,它想要一个名字(?)或其他东西。我得到的错误说它想要:

void GinSingSynth::setEnvelope(GSSynthOsc, GSAttackDur, float, GSDecRelDur, float, GSDecRelDur, float)

我打开了.cpp文件,它说它在另一端这样做:

void GinSingSynth::setEnvelope (GSSynthOsc  oscIdx ,
                                GSAttackDur attackDur , float attackAmp,
                                GSDecRelDur decayDur  , float decayAmp ,
                                GSDecRelDur releaseDur, float releaseAmp )
{
    ubyte voiceIdx = OscIdxToVoiceIdx(oscIdx);

    // Construct ADR bytes ( high four bits amplitude, low four bits duration )

    ubyte atkByte = ( (ubyte) ( 0x0f * attackAmp   ) << 4 ) + attackDur;
    ubyte dcyByte = ( (ubyte) ( 0x0f * decayAmp    ) << 4 ) + decayDur;
    ubyte rlsByte = ( (ubyte) ( 0x0f * releaseAmp  ) << 4 ) + releaseDur;
4

3 回答 3

2

很可能GSAttackDur代表某种intergal类型。它可能是一个枚举,因此您必须查找定义并查看接受的值是什么。诸如AT_100MS可能代表整数值的符号。

这一切都意味着您可以通过像这样传递整数来更改值:

s->setEnvelope (OSC_1, GsAttackDur(42), 1.0f, DR_100MS, 1.0f, DR_100MS, 0.0f);
                                    ^ random                  

但是,您必须检查有效值的范围。不要传递不在可接受范围内的枚举值,这一点非常重要。不幸的是,GsAttackDur(n)将接受任何n,而不管它是否有效。这意味着您必须知道有效范围,并n在此范围内生成一个数字。最近有一个相关的问题,您应该检查一下。请记住,您的随机枚举生成将始终与枚举定义耦合。如果后者发生变化,您将不得不修改前者。

于 2012-05-19T08:45:15.307 回答
1
  1. 将他们的头文件添加到您的C / C++源代码中
  2. 让你的函数返回它们的结构类型或#def可能。

GSAttackDur adsrMake(String type, int attack) { .... }

于 2012-05-19T08:46:57.690 回答
1

虽然您知道GSAttackDur枚举成员是顺序数值,但依靠第三方库(甚至您自己的库)的内部信息来推断将整数转换为枚举是有效或安全的并不是最佳实践

在一般情况下或在代码维护的情况下,值是连续的甚至是算术级数可能并不总是正确的。更好的通用解决方案是使用查找表将您的随机整数转换为有效的枚举类型值,因此不需要了解实际枚举文字值的大小或顺序:

GSAttackDur getRandomDuration()
{
    static const GSAttackDur lookup[]
    {
        AT_2MS, AT_8MS, AT_16MS, AT_24MS, AT_38MS, 
        AT_56MS, AT_68MS, AT_80MS, AT_100MS // add more as necessary
    } ;

    // Get random index into lookup - 0 to N-1 where N is the number 
    // of elements in lookup.
    int r = rand() / (RAND_MAX / (sizeof(lookup) / sizeof(*lookup)) ) ;

    // Return a random GSAttackDur value
    return lookup[r] ;
}
于 2012-05-20T08:08:58.773 回答