-2

それで、Arduino用のGinSingライブラリを使用していますが、問題が発生しました。変数名 (またはオブジェクト? または何か?) から値を抽出するコードチャンクがあります。ここで変数名に値を持つことについて読んだことがあります (スタック オーバーフロー)。

私は彼らのコードを変更できるほど優れたプログラマーではありませんが、それでも使用したいと思っています (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;
4

3 に答える 3

2

GSAttackDurある種の整数型を表している可能性が非常に高いです。おそらく列挙型であるため、定義を調べて、受け入れられる値を確認する必要があります。などの記号は、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

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 に答える
1
  1. ヘッダー ファイルをC / C++ソースに追加します
  2. 関数が構造体型または#defおそらく返すようにします。

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

于 2012-05-19T08:46:57.690 に答える