     @abbrs ?= [@abbr]
     @abbrs = @abbrs.split(/s/) if typeof @abbrs == 'string'
     @abbr ?= @abbrs[0]
-    if @rootPitch?
-      @rootName or= NoteNames[@rootPitch]
+
+    @rootName or= NoteNames[@rootPitch] if @rootPitch?
     if @rootName?
-      @rootPitch ?= parsePitchClass(@rootName)
+      @rootPitch ?=
+        if @rootName.match(/\d/) then pitchFromScientificNotation(@rootName) else parsePitchClass(@rootName)
+      @pitches = (pitch + @rootPitch for pitch in @pitchClasses)
       rootlessAbbr = @abbr
       rootlessFullName = @fullName
       Object.defineProperty this, 'name', get: -> "#{@rootName}#{rootlessAbbr}"
       Object.defineProperty this, 'fullName', get: -> "#{@rootName} #{rootlessFullName}"
+
     degrees = (1 + 2 * i for i in [0..@pitchClasses.length])
     degrees[1] = {'Sus2':2, 'Sus4':4}[@name] || degrees[1]
     degrees[3] = 6 if @name.match /6/
+
     @components = for pc, pci in @pitchClasses
       name = IntervalNames[pc]
       degree = degrees[pci]

  {name: 'Minor-Major 7th', abbrs: ['min/maj7', 'min(maj7)'], pitchClasses: '037e'},
  {name: '6th', abbrs: ['6', 'M6', 'M6', 'maj6'], pitchClasses: '0479'},
  {name: 'Minor 6th', abbrs: ['m6', 'min6'], pitchClasses: '0379'},
]

# Chords is an array of chord classes
Chords = ChordDefinitions.map (spec) ->
  spec.fullName = spec.name
  spec.name = spec.name
    .replace(/Major(?!$)/, 'Maj')
    .replace(/Minor(?!$)/, 'Min')
    .replace('Dominant', 'Dom')
    .replace('Diminished', 'Dim')
  spec.abbrs or= [spec.abbr]
  spec.abbrs = spec.abbrs.split(/s/) if typeof spec.abbrs == 'string'
  spec.abbr or= spec.abbrs[0]
  spec.pitchClasses = spec.pitchClasses.match(/./g).map (c) -> {'t':10, 'e':11}[c] or Number(c)
  new Chord spec

# `Chords` is also indexed by chord names and abbreviations, and by pitch classes
do ->

  [naturalName, accidentals] = match[1...]
  pitch = SharpNoteNames.indexOf(naturalName.toUpperCase())
  pitch += AccidentalValues[c] for c in accidentals
  return pitch

midi2name = (number) ->
  "#{NoteNames[(number + 12) % 12]}#{Math.floor((number - 12) / 12)}"

name2midi = (name) ->
  throw new Error "#{name} is not a note name" unless m = name.toUpperCase().match(/^([A-G])([♯#♭b𝄪𝄫]*)(\d+)/)
  [noteName, accidentals, octave] = m.slice(1)
  pitch = NoteNames.indexOf(noteName)
  pitch += AccidentalValues[c] for c in accidentals
  pitch += 12 * Number(octave)
  return pitch


