                                MFCC_FREQ_BANDS
                                (xtract_mel_filter/.getFilters mel-filters)))
 
-     ;;public static int xtract_init_bark(int N, double sr, SWIGTYPE_p_int band_limits) {
-     ;;(xtract/xtract_init_bark block-size SAMPLERATE bark-band-limits)
-     ;;(println (xtract/int_array_getitem bark-band-limits 0))
-
-     (let [full-window (xtract/xtract_init_window block-size xtract-hann)
-           half-window (xtract/xtract_init_window half-block-size xtract-hann)]
-
-       (raise-errors
-        (xtract/xtract_init_wavelet_f0_state))
-
-       (let [stats
-             (map-indexed
-              (fn [idx v]
-                (let [wav-data (clojure->c-double v)
-                      f0       (extract-fundemental-frequency wav-data block-size SAMPLE_RATE)
-                      cents    (frequency->cents f0)
-                      midi     (if (> f0 0.0)
-                                 (Integer/parseInt (format "%.0f" (/ cents 100)))
-                                 0)
-
-                      spectrum               (extract-fft-spectrum wav-data block-size SAMPLE_RATE full-window)
-                      peaks                  (extract-peaks spectrum block-size SAMPLE_RATE_RATIO 10.0)
-                      spectral-inharmonicity (extract-spectral-inharmonicity peaks block-size f0)
-
-                      rms                    (extract-rms-amp wav-data block-size SAMPLE_RATE_RATIO)
-
-                      spectral-irregularity (double-array [0])
-                      spectral-centroid     (double-array [0])
-                      spectral-variance     (double-array [0])
-
-                      ;;TODO
-                      noiseness             (double-array [0])
-                      loudness              (double-array [0])
-                      tonality              (double-array [0])]
+     (raise-errors  (xtract/xtract_init_wavelet_f0_state))
+
+     (let [stats
+           (map-indexed
+            (fn [idx v]
+              (let [wav-data (copy-c-double v wav-buffer)
+                    f0       (extract-fundemental-frequency wav-data block-size SAMPLE_RATE)
+                    cents    (frequency->cents f0)
+                    midi     (if (> f0 0.0)
+                               (Integer/parseInt (format "%.0f" (/ cents 100)))
+                               0)
+
+                    spectrum               (extract-fft-spectrum wav-data block-size SAMPLE_RATE full-window)
+                    peaks                  (extract-peaks spectrum block-size SAMPLE_RATE_RATIO 10.0)
+                    spectral-inharmonicity (extract-spectral-inharmonicity peaks block-size f0)
+
+                    rms                    (extract-rms-amp wav-data block-size SAMPLE_RATE_RATIO)
+
+                    spectral-irregularity (double-array [0])
+                    spectral-centroid     (double-array [0])
+                    spectral-variance     (double-array [0])
+
+                    ;;TODO
+                    noiseness             (double-array [0])
+                    loudness              (double-array [0])
+                    tonality              (double-array [0])]
+
+                (raise-errors
+                 (xtract/xtract_spectral_centroid spectrum block-size nil spectral-centroid))
+                (raise-errors
+                 (xtract/xtract_irregularity_j    spectrum half-block-size nil spectral-irregularity))
+
+                (let [spectral-skewness      (double-array [0])
+                      spectral-std-deviation (double-array [0])
+                      spectral-mean          (double-array [0])
+                      spectral-kurtosis      (double-array [0])]
 
                   (raise-errors
-                   (xtract/xtract_spectral_centroid spectrum block-size (xtract-args 0.0) spectral-centroid))
+                   (xtract/xtract_spectral_mean spectrum block-size nil spectral-mean))
                   (raise-errors
-                   (xtract/xtract_irregularity_j    spectrum half-block-size nil spectral-irregularity))
-
-                  (let [spectral-skewness      (double-array [0])
-                        spectral-std-deviation (double-array [0])
-                        spectral-mean          (double-array [0])
-                        spectral-kurtosis      (double-array [0])]
-
+                   (xtract/xtract_variance spectrum block-size (xtract-args (first spectral-mean)) spectral-variance))
+                  (raise-errors
+                   (xtract/xtract_spectral_standard_deviation spectrum block-size (xtract-args (first spectral-variance)) spectral-std-deviation))
+
+                  (let [argv (xtract-args (first spectral-mean) (first spectral-std-deviation))]
                     (raise-errors
-                     (xtract/xtract_spectral_mean spectrum block-size nil spectral-mean))
+                     (xtract/xtract_spectral_skewness spectrum block-size argv spectral-skewness))
                     (raise-errors
-                     (xtract/xtract_variance spectrum block-size (xtract-args (first spectral-mean)) spectral-variance))
-                    (raise-errors
-                     (xtract/xtract_spectral_standard_deviation spectrum block-size (xtract-args (first spectral-variance)) spectral-std-deviation))
-
-                    (let [argv (xtract-args (first spectral-mean) (first spectral-std-deviation))]
-                      (raise-errors
-                       (xtract/xtract_spectral_skewness spectrum block-size argv spectral-skewness))
-                      (raise-errors
-                       (xtract/xtract_spectral_kurtosis spectrum block-size argv spectral-kurtosis)))
-
-                    ;;(xtract/xtract_noisiness     wav-data block-size (xtract-args NUM_HARMONICS ) noiseness)
-
-                    (let [_ 10
-                          ;;bark-cofficents (clojure->c-double (range 0 xtract-bark-bands))
-                          ]
-
-                      ;;(xtract/xtract_bark_coefficients spectrum half-block-size (xtract-args ) bark-cofficents)
-                      ;;(xtract/xtract_loudness      wav-data block-size (apply xtract-args argv) loudness)
-                      )
-
-                    ;;TODO
-                    ;;(xtract/xtract_tonality      wav-data block-size (xtract-args ) tonality)
-
-                    ;;TODO: More memory, probably slower... Re-using variables faster but sad
-                    (xtract/delete_double_array wav-data)
-                    (xtract/delete_double_array spectrum)
-                    (xtract/delete_double_array peaks)
-
-                    {
-                     (format "%.6f" (/  (* idx half-block-size) SAMPLE_RATE))
-
-                     {:spectral-inharmonicity spectral-inharmonicity
-                      :spectral-irregularity  (first spectral-irregularity)
-                      :spectral-centroid      (first spectral-centroid)
-                      :spectral-skewness      (first spectral-skewness)
-                      :spectral-kurtosis      (first spectral-kurtosis)
-                      :rms-amplitude          (first rms)
-
-                      :todo {:noisiness (first noiseness)
-                             :loudness (first loudness)
-                             :tonality (first tonality)}
-                      :midi midi
-                      :f0 f0}
-                     }
-                    )))
-              data)]
-
-         (xtract/xtract_free_window full-window)
-         (xtract/xtract_free_window half-window)
-         (xtract/destroy_filterbank mel-filters)
-
-         (vec (flatten stats))
-         )))))
-
+                     (xtract/xtract_spectral_kurtosis spectrum block-size argv spectral-kurtosis)))
+
+                  {
+                   (format "%.6f" (/  (* idx half-block-size) SAMPLE_RATE))
+
+                   {:spectral-inharmonicity spectral-inharmonicity
+                    :spectral-irregularity  (first spectral-irregularity)
+                    :spectral-centroid      (first spectral-centroid)
+                    :spectral-skewness      (first spectral-skewness)
+                    :spectral-kurtosis      (first spectral-kurtosis)
+                    :rms-amplitude          (first rms)
+
+                    :todo {:noisiness (first noiseness)
+                           :loudness (first loudness)
+                           :tonality (first tonality)}
+                    :midi midi
+                    :f0 f0}
+                   }
+                  )))
+            data)]
+
+       (vec (flatten stats))))))
 
 (defn global-stats-reduce [fields]
   (fn [acc frame]

(defn extract-spectrum
  "Extract frequency domain spectrum from time domain signal"
  ([windowed-data block-size sample-ratio spectrum-type]
   (extract-spectrum windowed-data block-size sample-ratio spectrum-type 0.0 0.0))
  ([windowed-data block-size sample-ratio spectrum-type db-component normalised]

   (let [spectrum (c-double block-size)]
     (raise-errors
      (xtract/xtract_spectrum windowed-data
                              block-size (xtract-args sample-ratio
                                                      spectrum-type
                                                      db-component
                                                      normalised)
                              spectrum))
     spectrum)))

(defn extract-fft-spectrum [wave-data block-size sample-rate full-window]
  (let [windowed (c-double block-size)]
    ;;NOTE: I'm not convienced the full-window parameter is being used.
    (raise-errors
     (xtract/xtract_windowed wave-data block-size (xtract/doublea_to_voidp full-window) windowed))
    (raise-errors
     (xtract/xtract_init_fft block-size xtract-spectrum))
    (let [spectrum (extract-spectrum windowed block-size (/ sample-rate block-size) xtract-spectrum-magnitude)]
      (raise-errors
       (xtract/xtract_free_fft))
      (raise-errors
       (xtract/delete_double_array windowed))
      spectrum)))

(defn extract-peaks
  "Extract the amplitude and frequency of spectral peaks from a magnitude spectrum"
  [coefficients block-size sample-ratio peak-threshold]
  (let [peaks (c-double block-size)]
    (raise-errors
     (xtract/xtract_peak_spectrum coefficients
                                  (/ block-size 2)
                                  (xtract-args sample-ratio peak-threshold)
                                  peaks))
    peaks))

(defn extract-rms-amp
  "Extract the RMS amplitude of an input vector"

(defn max-for [field frame-stats]
  (apply max (map (fn [f] (get (first (vals f)) field))  frame-stats)))

(defn min-for [field frame-stats]
  (let [vals (map (fn [f] (get (first (vals f)) field)) frame-stats)]
    (when (seq vals)
      (apply min vals))))

(defn global-stats [frame-stats]
  (let [n (count frame-stats)
        fields (-> frame-stats first vals first (dissoc :todo) keys)
