    through and a list of durations (the duration in time of the lines
    between each point).
 
-   Optionally a curve may be specified. This may be one of:
+   Optionally a curve or list of curves may be specified. A single
+   curve (as a keyword or float) will be repeated for all segments. A
+   list of keywords or floats will be cycled through for all segments.
+
+   Options are:
+
    * :step              - flat segments
    * :linear            - linear segments, the default
    * :exponential       - natural exponential growth and decay. In this

   * :sine              - sinusoidal S shaped segments.
   * :welch             - sinusoidal segments shaped like the sides of a
                          Welch window.
   * a Float            - a curvature value to be repeated for all segments.
   * an Array of Floats - individual curvature values for each segment.
                          Positive numbers curve the segment up whilst
                          negative numbers curve the segment down.

   If a release-node is specified (an integer index) the envelope will sustain
   at the release node until released which occurs when the gate input of the

   :cubed       7
   })

(defn- curve->shape-id
    "Map curve to envelope shape. If curve is a keyword, look it up in
     ENV-SHAPES, otherwise assume it to be the generic cuve shape id of
     5"
    [curve]
    (get ENV-SHAPES curve 5))

(defn- curve->curve-id
    "Map curve to curve id. If curve is a keyword, assume the curve id
     is a generic shape (0) otherwise, preserve curve id"
    [curve]
    (if-let [id (get ENV-SHAPES curve)]
      0
      curve))

(defn- curves->shape-ids
  "Create a repeating shapes list corresponding to a specific shape type.
  Looks shape s up in ENV-SHAPES if it's a keyword. If not, it assumes the
  val represents the bespoke curve vals for a generic curve shape (shape
  type 5). the bespoke curve vals aren't used here, but are picked up in
  curve-value.
  Mirrors *shapeNumber in supercollider/SCClassLibrary/Common/Audio/Env.sc"
  [curves]
  (cycle (map curve->shape-id curves)))

(defn- curves->curve-ids
  "Create the curves id list for the specified curves. For all standard shapes this
  list of vals isn't used. It's only required when the shape is a generic
  'curve' shape when the curve vals represent the curvature value for each
  segment. A single float is repeated for all segments whilst a list of floats
  can be used to represent the curvature value for each segment individually.
  Mirrors curveValue in supercollider/SCClassLibrary/Common/Audio/Env.sc"
  [curves]
  (cycle (map curve->curve-id curves)))


;; Envelope specs describe a series of segments of a line, which can be used to automate
;; control values in synths.
