anchor.diff:           (english #\B)
            (german #\H)))))
   
  +(defun ensure-double-float (number)
  +  (etypecase number
  +    (double-float number)
  +    (number (coerce number 'double-float))))
  +
  +(defun ensure-tuning (tuning)
  +  (etypecase tuning
  +    (symbol (case tuning
  +              ((german austrian) 443.0d0)
  +              (swiss 442.0d0)
  +              (von-kajaran 444.0d0)
  +              (T 440.0d0)))
  +    (number (ensure-double-float tuning))))
  +
   (defun notation (note octave &key flat-p sharp-p (notation 'english))
     (ecase notation
       (english (format NIL "~a~a~a"
  
positive.code:                    :sharp-p (find key-of-octave *black-keys-on-piano*)
                     :notation notation)))))
  
  (defun pitch->notation (pitch &key (tuning 440.0d0) (notation 'english))
    (multiple-value-bind (key offset)
        (pitch->piano-key pitch :tuning tuning)
  
negative.code:                    sharpness
                     (loop repeat (- octave 3) collecting #\´)))))))
  
  (defun german-notation->piano-key (key-string groups)
    (unless key-string (invalid-key-notation-error key-string))
    (let ((sharp-p (when (< 0 (length (aref groups 4))) (aref groups 4)))
          (flat-p (when (< 0 (length (aref groups 5))) (aref groups 5)))
          (low (when (< 0 (length (aref groups 2))) (length (aref groups 0))))
          (high (when (< 0 (length (aref groups 3))) (length (aref groups 6)))))
      (when (or (and high low) (and flat-p sharp-p))
        (invalid-key-notation-error key-string))
      (let ((note (string-upcase (if low (aref groups 2) (aref groups 3)))))
        (round (+ (cond (flat-p -1) (sharp-p 1) (T 0))
                  (cond
                    ((and low (= low 3)
                          (string= "A" note)) 1)
                    ((and low (= low 3)
                          (string= "B" note)) 3)
                    ((and high (= high 6)
                          (string= "C" note)) 88)
                    ((and low (< low 3))
                     (format T "~a~%" low)
                     (+ 3 (* (- 1 low) 12) (note-order-on-piano note)))
                    ((and high (< high 6))
                     (+ 27 (* high 12) (note-order-on-piano note)))
                    (T (invalid-key-notation-error key-string))))))))
  
  (defun english-notation->piano-key (key-string groups)
    (unless key-string (invalid-key-notation-error key-string))
    (let ((note (char (aref groups 0) 0))
          (flat-p (when (< 0 (length (aref groups 1))) (aref groups 1)))
          (sharp-p (when (< 0 (length (aref groups 2))) (aref groups 2)))
          (octave (parse-integer (aref groups 3))))
      (when (and flat-p sharp-p)
        (invalid-key-notation-error key-string))
      (round (+ (cond (flat-p -1) (sharp-p 1) (T 0))
                (cond
                  ((= 0 octave)
                   (cond ((string= "A" note) 1)
                         ((string= "B" note) 3)
                         (T (invalid-key-notation-error key-string))))
                  ((= 8 octave)
                   (cond ((string= "C" note) 88)
                         (T (invalid-key-notation-error key-string))))
                  (T (+ 3 (* (1- octave) 12) (note-order-on-piano note))))))))
  
  (defun notation->piano-key (note)
    (unless (or (typep note 'string) (typep note 'symbol) (typep note 'keyword))
      (invalid-key-notation-error note))
    (let* ((note (format NIL "~a" note)))
      (multiple-value-bind (key-string groups)
          (cl-ppcre:scan-to-strings *english-notation-regex* note)
        (if key-string
            (english-notation->piano-key key-string groups)
            (multiple-value-bind (key-string groups)
                (cl-ppcre:scan-to-strings *german-notation-regex* note)
              (unless (and key-string (< 0 (length key-string)))
                (invalid-key-notation-error note))
              (german-notation->piano-key key-string groups))))))
  
  (defun piano-key->pitch (key &key (tuning 440.0d0))
    (coerce (+ (- (ensure-tuning tuning) 440.0d0)
               (* 440.0d0 (expt 2.0d0 (/ (- key 49.0d0) 12.0d0))))
            'single-float))
  
  (defun pitch->piano-key (pitch &key (tuning 440.0d0))
  