temporal-music-notation 0.2.2 → 0.2.3
raw patch · 5 files changed
+88/−51 lines, 5 filesdep ~temporal-media
Dependency ranges changed: temporal-media
Files
- src/Temporal/Music/Note.hs +24/−15
- src/Temporal/Music/Pitch.hs +5/−5
- src/Temporal/Music/Score.hs +48/−17
- src/Temporal/Music/Volume.hs +9/−12
- temporal-music-notation.cabal +2/−2
src/Temporal/Music/Note.hs view
@@ -4,8 +4,8 @@ -- It defines the notion of note. module Temporal.Music.Note( -- * Types- Note(..), note,- Drum(..), bam,+ Note(..), nx, mapNoteParam,+ Drum(..), bam, mapDrumParam, -- * Shortcuts -- ** Note shortcuts -- | Function n[i] is equivalent to call @note i@.@@ -30,7 +30,7 @@ data Note a = Note { noteVolume :: Volume, notePitch :: Pitch,- noteParam :: a+ noteParam :: Maybe a } deriving (Show, Eq) @@ -38,7 +38,7 @@ fmap f n = Note { notePitch = notePitch n , noteVolume = noteVolume n- , noteParam = f $ noteParam n+ , noteParam = fmap f $ noteParam n } instance PitchLike (Note a) where@@ -49,46 +49,55 @@ setVolume v a = a{ noteVolume = v } getVolume = noteVolume -instance Default a => Default (Note a) where+instance Default (Note a) where def = Note def def def --- | Constructs default 'Note' with given step value.-note :: Default a => Step -> Score (Note a)-note a = temp $ Note def def{ pitchStep = a } def+mapNoteParam :: (Maybe a -> Maybe b) -> Note a -> Note b+mapNoteParam f x = x{ noteParam = f $ noteParam x } -- drum -- | 'Drum' has only pitch and some timbral paramters. data Drum a = Drum { drumVolume :: Volume,- drumParam :: a+ drumParam :: Maybe a } deriving (Show, Eq) instance Functor Drum where fmap f n = Drum { drumVolume = drumVolume n- , drumParam = f $ drumParam n+ , drumParam = fmap f $ drumParam n } instance VolumeLike (Drum a) where setVolume v a = a{ drumVolume = v } getVolume = drumVolume -instance Default a => Default (Drum a) where+instance Default (Drum a) where def = Drum def def +mapDrumParam :: (Maybe a -> Maybe b) -> Drum a -> Drum b+mapDrumParam f x = x{ drumParam = f $ drumParam x }+ -- | Constructs drum note with given accent. Level is set to the default -- value.-bam :: Default a => Accent -> Score (Drum a)+bam :: Accent -> Score (Drum a) bam a = accent a $ temp def -------------------------------------------------------------- -- notes -- +-- | Constructs default 'Note' with given step value.+nx :: Step -> Score (Note a)+nx = note++note :: Step -> Score (Note a)+note a = temp $ Note def def{ pitchStep = a } def+ n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16, n17, n18, n19, n20, n21, n22, n23- :: Default a => Score (Note a)+ :: Score (Note a) n0 = note 0; n1 = note 1; n2 = note 2; n3 = note 3; n4 = note 4; n5 = note 5; n6 = note 6; n7 = note 7;@@ -102,7 +111,7 @@ -- drums -- -bd, wd, hd, qd, ed, sd, td :: Default a => Accent -> Score (Drum a)+bd, wd, hd, qd, ed, sd, td :: Accent -> Score (Drum a) bd = bn . bam wd = bam@@ -112,7 +121,7 @@ sd = sn . bam td = tn . bam -dbd, dwd, dhd, dqd, ded, dsd, dtd :: Default a => Accent -> Score (Drum a) +dbd, dwd, dhd, dqd, ded, dsd, dtd :: Accent -> Score (Drum a) dbd = dot . bd dwd = dot . wd
src/Temporal/Music/Pitch.hs view
@@ -9,7 +9,7 @@ -- * PitchLike PitchLike(..), mapPitch, -- * Render - hz, pitchAsDouble, scaleAt+ absPitch, pitchAsDouble, scaleAt ) where @@ -148,12 +148,12 @@ --------------------------------------------------------- -- rendering -absPitch :: Pitch -> Hz-absPitch p = pitchScale p `scaleAt` pitchAsDouble p+renderPitch :: Pitch -> Hz+renderPitch p = pitchScale p `scaleAt` pitchAsDouble p -- | Calculates cycles per second for a pitch.-hz :: PitchLike a => a -> Hz-hz = absPitch . getPitch+absPitch :: PitchLike a => a -> Hz+absPitch = renderPitch . getPitch -- | scale value on integers
src/Temporal/Music/Score.hs view
@@ -3,8 +3,12 @@ -- * Types Dur, Score, Event(..), eventEnd, within, -- * Composition- temp, rest, stretch, delay, reflect, (+|), (*|), (=:=), (+:+), (=:/),- line, chord, chordT, loop, sustain, sustainT, + temp, event, rest, stretch, delay, reflect, (+|), (*|), (=:=), (+:+), (=:/),+ line, chord, chordT, loop, sustain, sustainT, + -- ** Common patterns+ lineTemp, chordTemp, + lineMap, chordMap, chordTMap, + -- * Filtering slice, takeS, dropS, filterEvents, -- * Mappings@@ -21,7 +25,7 @@ module Data.Monoid, -- * Volume control setDiap, setDiapRel, setLevel, setAccent, accent, (!),- louder, quieter, loud, quiet, envelope, envelopeSeg, envelopeRel, + louder, quieter, loud, quiet, withAccent, withAccentSeg, withAccentRel, -- * Pitch control setScale, setBend, setStep, step, bend, lower, higher, low, high, @@ -29,7 +33,7 @@ -- | Denotes @lower 1-2@ and @higher 1-2@. l', ll', hh', h', -- * Time stretching - r, dot, ddot, tri, bpm,+ r, dot, ddot, trn, bpm, -- ** Shortcuts -- | Naming conventions : @@ -91,6 +95,14 @@ temp :: a -> Score a temp = M.temp +-- | Creates a single event.+--+-- > event dur a +--+-- Event lasts for some time and contains a value @a@.+event :: Dur -> a -> Score a+event = M.event+ -- | Empty 'Score' that lasts for some time. rest :: Dur -> Score a rest = M.rest@@ -141,12 +153,31 @@ chordT :: [Score a] -> Score a chordT = M.chordT +-- | A line of one events. Each of them lasts for one second.+lineTemp :: [a] -> Score a+lineTemp = M.lineTemp++-- | A chord of one events. Each of them lasts for one second.+chordTemp :: [a] -> Score a+chordTemp = M.chordTemp++-- | Transforms a sequence and then applies a line.+lineMap :: (a -> Score b) -> [a] -> Score b+lineMap = M.lineMap++-- | Transforms a sequence and then applies a chord.+chordMap :: (a -> Score b) -> [a] -> Score b+chordMap = M.chordMap++-- | Transforms a sequence and then applies a chordT.+chordTMap :: (a -> Score b) -> [a] -> Score b+chordTMap = M.chordTMap+ -- | Analog of 'replicate' function for scores. Replicated -- scores are played sequentially. loop :: Int -> Score a -> Score a loop = M.loop - -- | After this transformation events last longer -- by some constant amount of time. sustain :: Dur -> Score a -> Score a@@ -213,7 +244,7 @@ -- -- | Sets diapason to specified value.-setDiap :: VolumeLike a => (Amp, Amp) -> Score a -> Score a+setDiap :: VolumeLike a => (Double, Double) -> Score a -> Score a setDiap a = fmap $ mapVolume $ \v -> let d = volumeDiap v in v{ volumeDiap = d{ diapRange = a } }@@ -265,17 +296,17 @@ -- | Accent that depends on time of note, time is relative, -- so 'Score' starts at 't = 0' and ends at 't = 1'.-envelope :: (VolumeLike a) => (Dur -> Accent) -> Score a -> Score a-envelope f = tmapRel $ \(Event s d c) -> accent' c (f s)+withAccent :: (VolumeLike a) => (Dur -> Accent) -> Score a -> Score a+withAccent f = tmapRel $ \(Event s d c) -> accent' c (f s) where accent' v a = mapVolume (\v -> v{ volumeAccent = a }) v --- | 'envelopeSeg' lifts function 'lines' to dynamics level-envelopeSeg :: (VolumeLike a) => [Double] -> Score a -> Score a-envelopeSeg xs = envelope $ (linfun xs)+-- | 'envelopeSeg' lifts function 'linfun' to dynamics level+withAccentSeg :: (VolumeLike a) => [Double] -> Score a -> Score a+withAccentSeg xs = withAccent $ (linfun xs) --- | 'envelopeRel' lifts function 'linesRel' to dynamics level-envelopeRel :: (VolumeLike a) => [Accent] -> Score a -> Score a-envelopeRel xs a = envelope (linfunRel 1 xs) a+-- | 'envelopeRel' lifts function 'linfunRel' to dynamics level+withAccentRel :: (VolumeLike a) => [Accent] -> Score a -> Score a+withAccentRel xs a = withAccent (linfunRel 1 xs) a ---------------------------------------------------------@@ -364,9 +395,9 @@ r :: Dur -> Score a r = rest --- | Means 'triolet'. Plays three notes as fast as two.-tri :: Score a -> Score a-tri = stretch (2/3)+-- | Means 'three notes'. Plays three notes as fast as two.+trn :: Score a -> Score a+trn = stretch (2/3) -- | Sets tempo in beats per minute,
src/Temporal/Music/Volume.hs view
@@ -1,24 +1,21 @@ -- | This module defines the notion of volume. module Temporal.Music.Volume( -- * Types- Amp, Diap(..), Volume(..), Level, Accent,+ Diap(..), Volume(..), Level, Accent, -- * VolumeLike VolumeLike(..), mapVolume, -- * Rendering- amp, volumeAsDouble, diapAt) + absVolume, volumeAsDouble, diapAt) where import Data.Default --- | Amplitude.-type Amp = Double- -- | Diapason defines minimum and maximum bound for 'Volume' level. -- Field 'diapLim' specifies volume limit. Value 'diapLim' is -- rendered to highest amplitude and @-diapLim@ is rendered to -- the lowest amplitude. All values that go beyond the limit are clipped. data Diap = Diap- { diapRange :: (Amp, Amp)+ { diapRange :: (Double, Double) , diapLim :: Int } deriving (Show, Eq) @@ -33,10 +30,10 @@ -- | Volume levels. type Level = Int --- | 'Volume' denotes 'Amp' value. It's not a 'Double' +-- | 'Volume' denotes amplitude. It's not a 'Double' -- for ease of performing some musical transformations, such as -- making notes louder or using accents. 'Volume' can be converted--- to 'Amp' with function 'amp'.+-- to 'Double' with function 'amp'. data Volume = Volume { volumeDiap :: Diap, volumeAccent :: Accent,@@ -73,12 +70,12 @@ -- rendering -- -absVolume :: Volume -> Amp-absVolume v = diapAt (volumeDiap v) (volumeAsDouble v)+renderVolume :: Volume -> Double+renderVolume v = diapAt (volumeDiap v) (volumeAsDouble v) -- | Calculates amplitude for a 'Volume' -like value.-amp :: (VolumeLike a) => a -> Amp-amp = absVolume . getVolume+absVolume :: (VolumeLike a) => a -> Double+absVolume = renderVolume . getVolume -- | Calculates value of type 'Volume' as coordinate -- within specidfied diapason. 1 corresponds to maximum bound
temporal-music-notation.cabal view
@@ -1,5 +1,5 @@ Name: temporal-music-notation-Version: 0.2.2+Version: 0.2.3 Cabal-Version: >= 1.6 License-file: LICENSE License: BSD3@@ -23,7 +23,7 @@ Build-Depends: base >= 4, base < 5, vector >= 0.7, data-default >= 0.3,- temporal-media >= 0.3.1+ temporal-media >= 0.3.3 Hs-Source-Dirs: src/ Exposed-Modules: Temporal.Music