module Sound.Analysis.Meapsoft
( MEAP
, read_meap
, features
, n_frames
, uarray_data
, n_columns
, frame_l
, column_l
, position
, segments_l
, feature_names
, from_onsets
, module Sound.Analysis.Meapsoft.Data
, module Sound.Analysis.Meapsoft.Header ) where
import Data.Array.Unboxed
import Sound.Analysis.Meapsoft.Data
import Sound.Analysis.Meapsoft.Header
data MEAP t = MEAP {
features :: [Feature]
, n_frames :: Int
, uarray_data :: UArray (Int, Int) t }
read_meap :: Meap_Data t => FilePath -> IO (Either String (MEAP t))
read_meap fn = do
r <- read_header fn
case r of
(Left e) -> return (Left e)
(Right h) -> do let nc = sum (map feature_degree h)
(nf, d) <- read_data fn nc
let ua = meap_data_uarray nc nf d
return (Right (MEAP h nf ua))
n_columns :: MEAP t -> Int
n_columns = sum . map feature_degree . features
column_l :: Meap_Data t => MEAP t -> Int -> [t]
column_l m j =
let d = uarray_data m
is = [0 .. n_frames m 1]
in map (\i -> d `meap_data_index` (i, j)) is
frame_l :: Meap_Data t => MEAP t -> Int -> [t]
frame_l m i =
let d = uarray_data m
js = [0 .. n_columns m 1]
in map (\j -> d `meap_data_index` (i, j)) js
position :: Meap_Data t => MEAP t -> (Int, Int) -> t
position m (i, j) = uarray_data m `meap_data_index` (i, j)
segments_l :: Meap_Data t => MEAP t -> [(t,t)]
segments_l m =
let fs = features m
ec n = feature_column (required_feature n fs)
o = ec "onset_time"
d = ec "chunk_length"
in zip (column_l m o) (column_l m d)
feature_names :: [String]
feature_names =
["onset_time"
,"chunk_length"
,"AvgChroma"
,"AvgChromaScalar"
,"AvgChunkPower"
,"AvgFreqSimple"
,"AvgMelSpec"
,"AvgMFCC"
,"AvgPitch"
,"AvgSpec"
,"AvgSpecCentroid"
,"AvgSpecFlatness"
,"AvgTonalCentroid"
,"ChunkLength"
,"ChunkStartTime"
,"Entropy"
,"RMSAmplitude"
,"SpectralStability"]
from_onsets :: Meap_Data t => [(t,t)] -> MEAP t
from_onsets t =
let f = [Feature "onset_time" 0 1
,Feature "chunk_length" 1 1]
n = length t
t' = concatMap (\(p,q) -> [p,q]) t
d = meap_data_uarray 2 n t'
in MEAP f n d