Copyright | (c) 2012--2013 W. Bas de Haas and Jose Pedro Magalhaes |
---|---|
License | LGPL-3 |
Maintainer | bas@chordify.net, dreixel@chordify.net |
Stability | experimental |
Portability | non-portable |
Safe Haskell | Safe-Inferred |
Language | Haskell2010 |
Summary: A set of types and classes for representing musical time, mainly (but not necessarily) in the context of recognising chords from an arbitrary audio source.
- type NumData = Double
- data Timed a = Timed {
- getData :: a
- getTimeStamps :: [BeatTime]
- data Beat
- data BeatTime
- timed :: a -> NumData -> NumData -> Timed a
- timedBT :: a -> BeatTime -> BeatTime -> Timed a
- getBeatTime :: Timed a -> BeatTime
- getBeat :: Timed a -> Beat
- onset :: Timed a -> NumData
- offset :: Timed a -> NumData
- duration :: Timed a -> NumData
- setData :: Timed a -> b -> Timed b
- getEndTime :: [Timed a] -> NumData
- mergeTimed :: Eq a => [Timed a] -> [Timed a]
- mergeTimedWith :: forall a. Eq a => (a -> a -> Bool) -> [Timed a] -> [Timed a]
- expandTimed :: [Timed a] -> [Timed a]
- concatTimed :: a -> Timed a -> Timed a -> Timed a
- splitTimed :: Show a => Timed a -> NumData -> (Timed a, Timed a)
- nextBeat :: Beat -> Beat
- prevBeat :: Beat -> Beat
- dropTimed :: [Timed a] -> [a]
- timeStamp :: BeatTime -> NumData
- timeComp :: NumData -> NumData -> Ordering
- roundingError :: NumData
- beat :: BeatTime -> Beat
- pprint :: Show a => Timed a -> String
- prettyPrint :: Show a => [Timed a] -> String
Documentation
A type synonym is defined for our main numerical representation, this allows us to easily change the precision.
Representing musical time
A datatype that wraps around an (musical) datatype, adding information
about the musical time to this datatype. Musical time is stored as
a list of BeatTime
time stamps that can optionally be augmented
with information about the Beat
position of the particular time stamp
inside the bar.
Timed | |
|
For now, we fix the number of available beats to four, because this is also hard-coded into the bar and beat-tracker.
Functions
Data access
getBeatTime :: Timed a -> BeatTime Source
Returns the start time stamp
getEndTime :: [Timed a] -> NumData Source
Given a list of Timed
values, returns the end time of the latest element
in the list.
Type conversion and other utilities
mergeTimed :: Eq a => [Timed a] -> [Timed a] Source
merges consecutive Timed
values that store the same element (using
('(==)'). For example:
>>>
mergeTimed [timed "c" 0 1, timed "c" 1 2, timed "d" 3 4, timed "d" 4 5, timed "e" 5 6]
>>>
[Timed {getData = "c", getTimeStamps = [(0.0),(1.0),(2.0)]}
>>>
,Timed {getData = "d", getTimeStamps = [(3.0),(4.0),(5.0)]}
>>>
,Timed {getData = "e", getTimeStamps = [(5.0),(6.0)]}]
mergeTimedWith :: forall a. Eq a => (a -> a -> Bool) -> [Timed a] -> [Timed a] Source
Does exactly what mergeTimed
does, but allows for a custom equality
function
expandTimed :: [Timed a] -> [Timed a] Source
the inverse of mergeTimed
, expanding the list Timed
elements to all
timestamps stored in the getTimeStamps
list. N.B.
>>>
expandTimed (mergeTimed x) = x :: [Timed a]
also,
>>>
(expandTimed cs) = cs
and,
>>>
mergeTimed (mergeTimed (mergeTimed cs)) = (mergeTimed cs)
hold. This has been tested on the first tranche of 649 Billboard songs.
concatTimed :: a -> Timed a -> Timed a -> Timed a Source
nextBeat :: Beat -> Beat Source
returns the next beat, e.g. nextBeat Two = Three
.
Following the (current) definition of Beat
, we still assume 4/4, in the
future this function should also have the meter as an argument.
timeComp :: NumData -> NumData -> Ordering Source
compares to NumData
timestamps taking a rounding error roundingError
into account.
roundingError :: NumData Source
When reducing and expanding Timed
types there might be rounding
errors in the floating point time stamps. The roundingError
parameter
sets the acceptable rounding error that is used in the comparison of
time stamps (e.g. see timeComp
)