所以,我正在为Arduino使用GinSing库,我遇到了一个问题。有一大块他们的代码,他们从变量名(或对象?或其他东西?)中提取一个值。我已经读过关于在这里使用变量名称的值(Stack Overflow),我知道你不应该这样做,但我被卡住了!
我不是一个足够好的程序员来修改他们的代码,但我仍然想要使用它(GinSing盾很酷)。以下是他们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;
答案 0 :(得分: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
。最近有一个related question你应该检查。请记住,随机枚举生成将始终与枚举定义相关联。如果后者发生变化,则必须修改前者。
答案 1 :(得分:1)
答案 2 :(得分: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] ;
}