#| Copyright Tom Collins 10/10/2014.

Script for loading a symbolic version of a piece, as
well as the audio_time_to_symbolic_time information,
and outputting a new file that contains the symbolic
version of the piece and an extra column for the
estimated audio time. |#

#| Set some paths. |#
(setq
 *music-data-root*
 (make-pathname
  :directory
  '(:absolute
     "Users" "tomthecollins" "Shizz" "Documents"
     "Homepage" "research" "data")))
(setq
 *path&name*
 (merge-pathnames
  (make-pathname
   :directory
   '(:relative
     "beethoven_ludwig_van" "symphony_no_1_20141011"
     "mvt_1"))
  *music-data-root*))
(setq *piece-name* "symphony_no_1")
(setq *synch-name* "symphony_no_1_synch")

#| Symbolic version, bar2beat, and
audioTime2symbolicTime information. |#
(setq
 symbolic-source
 (merge-pathnames
  (make-pathname
   :name *piece-name* :type "txt") *path&name*))
(setq
 audioTime2symbolicTime-source
 (merge-pathnames
  (make-pathname
   :name "symphony_no_1_audio_time_to_symbolic_time"
   :type "mid") *path&name*))
(setq
 dataset-destination
 (merge-pathnames
  (make-pathname
   :name *synch-name* :type "txt") *path&name*))
(setq
 dataset-destination
 (merge-pathnames
  (make-pathname
   :name *synch-name* :type "txt") *path&name*))
(setq
 csv-destination
 (merge-pathnames
  (make-pathname
   :name *synch-name* :type "csv") *path&name*))

#| Read in the symbolic version of the piece. |#
(progn
  (setq
   dataset
   (read-from-file symbolic-source))
  "Yes!")

#| Read in audioTime2symbolicTime information. |#
(progn
  (setq
   as-info-raw
   (load-midi-file audioTime2symbolicTime-source))
  "Yes!")
#| Create a list of knot-value pairs. |#
(progn
  (setq
   knot-value-pairs
   (loop for i from 0 to (- (length as-info-raw) 1)
     collect
     (list
      (* i 2) (float (first (nth i as-info-raw))))))
  "Yes!")
#| The change in time signature at bar 13 creates an
issue, which this loop fixes. |#
(progn
  (setq
   knot-value-pairs
   (mapcar
    #'(lambda (x)
        (list
         (if (>= (first x) 48)
           (+ 48 (* (- (first x) 48) 2))
           (identity (first x))) (second x)))
    knot-value-pairs))
  "Yes!")

#| Estimate the onsets and offsets. |#
(progn
  (setq
   on-est
   (linearly-interpolate-x-values
    (nth-list-of-lists 0 dataset) knot-value-pairs))
  (setq
   off-est
   (linearly-interpolate-x-values
    (add-two-lists
     (nth-list-of-lists 0 dataset)
     (nth-list-of-lists 3 dataset)) knot-value-pairs))
  (setq
   dataset-synch
   (mapcar
    #'(lambda (x y z)
        (append x (list y) (list z)))
    dataset on-est off-est))
  "Yes!")

#| Now write the symbolic-audio synchronised version
of the piece to text and csv files as usual. |#
(progn
  (write-to-file
   dataset-synch dataset-destination)
  (dataset2csv dataset-synch csv-destination))
