2017-08-13 147 views
1

我正在使用Teensy在USB MIDI控制器上工作。控制器是一排7個按鈕,每個按鈕都是一個漸進程度,7個按鈕組成和絃進程。當按下時,設備發送MIDI音符開/關消息以播放和絃。使用自定義類型實現枚舉類似功能

在我的代碼我有存儲在enumintervals

/* 
* Intervals 
*/ 
typedef enum { 
    ROOT = 0, 
    UNISON = 0, 
    DIMINISHED_SECOND = 0, 
    MINOR_SECOND = 1, 
    AUGMENTED_UNISON = 1, 
    HALFSTEP = 1, 
    MAJOR_SECOND = 2, 
    DIMINISHED_THIRD = 2, 
    WHOLESTEP = 2, 
    MINOR_THIRD = 3, 
    AUGMENTED_SECOND = 3, 
    MAJOR_THIRD = 4, 
    DIMINISHED_FOURTH = 4, 
    PERFECT_FOURTH = 5, 
    AUGMENTED_THIRD = 5, 
    DIMINISHED_FIFTH = 6, 
    AUGMENTED_FOURTH = 6, 
    PERFECT_FIFTH = 7, 
    DIMINISHED_SIXTH = 7, 
    MINOR_SIXTH = 8, 
    AUGMENTED_FIFTH = 8, 
    MAJOR_SIXTH = 9, 
    DIMINISHED_SEVENTH = 9, 
    MINOR_SEVENTH = 10, 
    AUGMENTED_SIXTH = 10, 
    MAJOR_SEVENTH = 11, 
    DIMINISHED_OCTAVE = 11, 
    PERFECT_OCTAVE = 12, 
    AUGMENTED_SEVENTH = 12, 
    DIMISHED_NINTH = 12, 
    MINOR_NINTH = 13, 
    AUGMENTED_OCTAVE = 13, 
    MAJOR_NINTH = 14, 
    DIMINISHED_TENTH = 14, 
    MINOR_TENTH = 15, 
    AUGMENTED_NINTH = 15, 
    MAJOR_TENTH = 16, 
    DIMINISHED_ELEVENTH = 16, 
    PERFECT_ELEVENTH = 17, 
    AUGMENTED_TENTH = 17, 
    DIMINISHED_TWELFTH = 18, 
    AUGMENTED_ELEVENTH = 18, 
    PERFECT_TWELFTH = 19, 
    DIMINISHED_THIRTEENTH = 19, 
    MINOR_THIRTEENTH = 20, 
    AUGMENTED_TWELFTH = 20, 
    MAJOR_THIRTEENTH = 21, 
    DIMINISHED_FOURTEENTH = 21, 
    MINOR_FOURTEENTH = 22, 
    AUGMENTED_THIRTEENTH = 22, 
    MAJOR_FOURTEENTH = 23, 
    DIMINISHED_FIFTEENTH = 23, 
    PERFECT_FIFTEENTH = 24, 
    AUGMENTED_FOURTEENTH = 24, 
    AUGMENTED_FIFTEENTH = 25 
} INTERVAL; 

我也有chords數組,像這樣:

struct Chord { 
    String name; 
    int tones[7]; 
}; 

Chord chords[6] = { 
    { "maj", { 
    INTERVAL::UNISON, 
    INTERVAL::MAJOR_THIRD, 
    INTERVAL::PERFECT_FIFTH } 
    }, 
    { "min", { 
    INTERVAL::UNISON, 
    INTERVAL::MINOR_THIRD, 
    INTERVAL::PERFECT_FIFTH } 
    }, 
    { "maj7", { 
    INTERVAL::UNISON, 
    INTERVAL::MAJOR_THIRD, 
    INTERVAL::PERFECT_FIFTH, 
    INTERVAL::MAJOR_SEVENTH } 
    }, 
    { "min7", { 
    INTERVAL::UNISON, 
    INTERVAL::MINOR_THIRD, 
    INTERVAL::PERFECT_FIFTH, 
    INTERVAL::MINOR_SEVENTH } 
    }, 
    { "maj9", { 
    INTERVAL::UNISON, 
    INTERVAL::MAJOR_THIRD, 
    INTERVAL::PERFECT_FIFTH, 
    INTERVAL::MAJOR_SEVENTH, 
    INTERVAL::MAJOR_NINTH } 
    }, 
    { "min9", { 
    INTERVAL::UNISON, 
    INTERVAL::MINOR_THIRD, 
    INTERVAL::PERFECT_FIFTH, 
    INTERVAL::MINOR_SEVENTH, 
    INTERVAL::MINOR_NINTH } 
    } 
}; 

我想訪問在弦類似的方式enum的間隔,所以我可以做這樣的事情(psudeocode):

void playChord(Chord chord, int velocity, int channel) { 
    int i; 
    for(i=0; i<chord.length; i++) { 
     usbMIDI.sendNoteOn(chord[i], velocity, channel); 
    } 
} 

playChord(Chord::MAJOR, 127, 1); 

我知道不可能擁有自定義類型的枚舉,但有什麼方法可以接近這個嗎?我已經考慮過使用HashTable,但是我必須從頭開始實現它,如果我能夠提供幫助,我不會幻想。

回答

5

枚舉的一點是,你創建一個新類型,它只能採取固定值集合。因爲在實際使用中只有很多間隔,並且因爲在這裏創建新類型比使用整型常量更方便,所以對於您的間隔使用枚舉是合適的。

對於你的和絃,故事是不同的。你已經有了和絃的類型,所以把它們包裝在另一個枚舉類型中是沒有用的。另外,和絃的數量遠沒有限制。我手邊的和絃圖表顯示了22種形狀,但不包括反轉。你的和絃結構遠比用enum限制和絃更合適。

C有兩個其他機制來創建除枚舉之外的「常量」:預處理器定義和靜態變量。

使用預處理指令,我們可以定義一個Chord文字。 IIRC結構文字是C99的東西,以前只能有初始化文字。

#define CHORD_MAJOR ((Chord){"maj", {ROOT, MAJOR_THIRD, PERFECT_FIFTH}}) 

有了一個靜態變量,你會在頭聲明對象:

static const Chord chord_major = {"maj", {ROOT, MAJOR_THIRD, PERFECT_FIFTH}}; 

注意C沒有命名空間運營商像::。相反,你必須自己爲任何可能的衝突標識符加上前綴。 C++確實有名稱空間,但這不會影響在此答案中所做的要點。