3GBPEYPD42RVRUM5CGQ564MZ4ETQ5IL4QBMOF4YT3SRIJJG3WPEQC // setScale sets the scale to sharp or flat based on tonicfunc setScale(tonic string) (scale []string, err error) {for _, v := range sharps {if v == tonic {return sharpScale, nil}}for _, v := range flats {if v == tonic {return flatScale, nil}}return nil, errors.New("tonic has not found: neither in sharps, nor in flats")}
var selectScale = map[string][]string{"a": sharpScale, "C": sharpScale, "G": sharpScale, "D": sharpScale, "A": sharpScale, "E": sharpScale, "B": sharpScale, "F#": sharpScale, "e": sharpScale, "b": sharpScale, "f#": sharpScale, "c#": sharpScale, "g#": sharpScale, "d#": sharpScale, "F": flatScale, "Bb": flatScale, "Eb": flatScale, "Ab": flatScale, "Db": flatScale, "Gb": flatScale, "d": flatScale, "g": flatScale, "c": flatScale, "f": flatScale, "bb": flatScale, "eb": flatScale}
// genChromatic generates the choromatic scale starting with the given tonicfunc genChromatic(scale []string, tonic string) (chr []string) {
// Scale gives back the proper scale for the given tonic and intervals.func Scale(tonic, interval string) (result []string) {scale, ok := selectScale[tonic]if !ok {fmt.Fprintf(os.Stderr, "Scale not found for tonic")}var act int
if strings.ToLower(v) == strings.ToLower(tonic) {chr = scale[k:]chr = append(chr, scale[:k]...)
if v == strings.Title(tonic) {if len(interval) == 0 {result = append(scale[k:], scale[:k]...)return result}act = kresult = append(result, scale[act])for k := 0; k < len(interval)-1; k++ {switch {case interval[k] == 'm':act += 1case interval[k] == 'M':act += 2case interval[k] == 'A':act += 3}if act >= len(scale) {act = act - len(scale)}result = append(result, scale[act])}
// genDiatonic generates the diatonic scale based on intervalsfunc genDiatonic(scale []string, interval string) (diat []string) {act := 0diat = append(diat, scale[0])for k := 0; k < len(interval)-1; k++ {switch {case interval[k] == 'm':act += 1case interval[k] == 'M':act += 2case interval[k] == 'A':act += 3}if act >= len(scale) {act = act - len(scale)}diat = append(diat, scale[act])}return}// Scale gives back the proper scale for the given tonic and intervals.func Scale(tonic, interval string) (s []string) {scale, err := setScale(tonic)if err != nil {fmt.Fprintln(os.Stderr, err)os.Exit(1)}s = genChromatic(scale, tonic)if len(interval) == 0 {return}s = genDiatonic(s, interval)return}