Hi everyone,
trying to encode some information about music (a different structure than the harmonex package).
I have an earlier implemenation of what I want in python (from a previous project). It heavily uses enums to describe the structure of pitch classes, intervals, chords etc.
eg one of them:
"""
Simple mapping of note name to MIDI value mod 12.
MIDI 0th octave begins at 12 + this value. (so C0 = 12, A0 = 21, etc)
"""
import aenum
Pitch : 'Pitch' = IntEnum('Pitch', {
# note, this order is NOT random
# raw note names are preferred to enharmonic equivalents
# flats are preferrable to sharps (jazz musician here)
'C': 0, 'D': 2, 'E': 4, 'F': 5, 'G': 7, 'A': 9, 'B': 11,
'Db':1, 'Gb':6, 'Ab':8, 'Bb':10, 'Eb': 3,
'C#':1, 'D#':3, 'G#':8, 'A#':10, 'F#': 6,
# these are just weird, so they exist only as aliases for B/C E/F respectively.
'Fb':4,'E#':5,'B#':0, 'Cb':11
})
Is there something equivalent in erlang/elixir that allows me to have similar properties as an enum like this? “Just use a map” only allows me to do lookups in one direction - i also want to be able to do them in the other direction. So would want to be able to do:
> Pitch.C
Pitch.C (as opposed to 0 as the representation)
> Pitch("A#") => Pitch.Aę–› #found a unicode character that elixir accepts that looks like a sharp
> Pitch(:Cę–›) => Pitch.Cę–›
> Pitch(12) => Pitch.C #appropriate instance, mod 12
> Pitch(10) => Pitch.Bb # chooses the first instance when there are more than one option
> Pitch.C => Directly choose the right instance
> Pitch.C = Pitch.Cę–› => :false
> import Pitch; import Interval
> C + m2 => Pitch.Cę–›
> major_scale = [U, M2, M3, P4, P5, M6, M7] # these are Interval.U, Interval.M2 etc
> minor_11 = ~I(m3 P5 m7 M9 P11) => [m3, P5, m7, m9, P11] # again, Interval.m3, Interval.P5 etc
The shorthand import structure are very useful to not have to type out Pitch._
and Interval._
every time.
Is this what @
is for?
defmodule Pitch
@C = 0
@Cs= 1
@Db= 1
@D = 2
...
end
?