    * :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.
+   * :squared           - Squared segments
+   * :cubed             - Cubed segments
+   * a float            - a curvature value to be repeated for all segments.
                           Positive numbers curve the segment up whilst
                           negative numbers curve the segment down.
+   * a list of keywords - individual values for each segment. To be cycled
+     and or floats        through for all segments.
+
 
    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

  ;;See prAsArray in supercollider/SCClassLibrary/Common/Audio/Env.sc
  ([levels durations]
     (envelope levels durations :linear))
  ([levels durations curve]
     (envelope levels durations curve -99))
  ([levels durations curve release-node]
     (envelope levels durations curve release-node -99))
  ([levels durations curve release-node loop-node]
     (let [shapes (shape->id curve)
           curves (curve-value curve)]
       (apply vector
              (concat [(first levels) (count durations) release-node loop-node]
                      (interleave (rest levels) durations shapes curves))))))

(defunk triangle
  "Create a triangle envelope description array suitable for use with 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.
