module Derive.Scale.Interpolate where
import qualified Util.Doc as Doc
import qualified Derive.Args as Args
import qualified Derive.Call.Module as Module
import qualified Derive.Derive as Derive
import qualified Derive.DeriveT as DeriveT
import qualified Derive.Env as Env
import qualified Derive.EnvKey as EnvKey
import qualified Derive.Eval as Eval
import qualified Derive.Expr as Expr
import qualified Derive.Pitches as Pitches
import qualified Derive.Scale as Scale
import qualified Derive.Scale.Scales as Scales
import qualified Derive.ScoreT as ScoreT
import qualified Derive.ShowVal as ShowVal
import qualified Derive.Sig as Sig
import qualified Perform.Pitch as Pitch
import Global
scales :: [Scale.Definition]
scales :: [Definition]
scales = (Environ -> LookupScale -> Either PitchError Scale) -> [Definition]
scale_make forall a b. (a -> b) -> a -> b
$ \Environ
env (Scale.LookupScale Environ -> ScaleId -> Maybe (Either PitchError Scale)
lookup) -> do
(ScaleId
from_id, ScaleId
to_id) <- Environ -> Either PitchError (ScaleId, ScaleId)
environ_from_to Environ
env
let find :: Key -> ScaleId -> Either PitchError Scale
find Key
msg ScaleId
scale_id = forall a. a -> Maybe a -> a
fromMaybe (forall a b. a -> Either a b
Left forall a b. (a -> b) -> a -> b
$ Key -> PitchError
DeriveT.PitchError Key
msg) forall a b. (a -> b) -> a -> b
$
Environ -> ScaleId -> Maybe (Either PitchError Scale)
lookup Environ
env2 ScaleId
scale_id
env2 :: Environ
env2 = Key -> Environ -> Environ
Env.delete Key
scale_from forall a b. (a -> b) -> a -> b
$ Key -> Environ -> Environ
Env.delete Key
scale_to Environ
env
Scale
from <- Key -> ScaleId -> Either PitchError Scale
find (Key
"from scale " forall a. Semigroup a => a -> a -> a
<> forall a. Pretty a => a -> Key
pretty ScaleId
from_id) ScaleId
from_id
Scale
to <- Key -> ScaleId -> Either PitchError Scale
find (Key
"to scale " forall a. Semigroup a => a -> a -> a
<> forall a. Pretty a => a -> Key
pretty ScaleId
to_id) ScaleId
to_id
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Scale -> Scale -> Scale
make Scale
from Scale
to
where
scale_make :: (Environ -> LookupScale -> Either PitchError Scale) -> [Definition]
scale_make = (forall a. a -> [a] -> [a]
:[]) forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScaleId
-> (Key, DocumentedCall)
-> (Environ -> LookupScale -> Either PitchError Scale)
-> Definition
Scale.Make ScaleId
scale_id (Key
"same as from scale", DocumentedCall
doc)
make :: Scale.Scale -> Scale.Scale -> Scale.Scale
make :: Scale -> Scale -> Scale
make Scale
from Scale
to = Scale.Scale
{ scale_id :: ScaleId
scale_id = ScaleId
scale_id
, scale_pattern :: Key
scale_pattern = Key
"same as `from` scale"
, scale_symbols :: [Symbol]
scale_symbols = []
, scale_transposers :: Set Control
scale_transposers =
Scale -> Set Control
Scale.scale_transposers Scale
from forall a. Semigroup a => a -> a -> a
<> Scale -> Set Control
Scale.scale_transposers Scale
to
, scale_read :: Environ -> Note -> Either PitchError Pitch
scale_read = Scale -> Environ -> Note -> Either PitchError Pitch
Scale.scale_read Scale
from
, scale_show :: Environ -> Pitch -> Either PitchError Note
scale_show = Scale -> Environ -> Pitch -> Either PitchError Note
Scale.scale_show Scale
from
, scale_bottom :: Pitch
scale_bottom = Scale -> Pitch
Scale.scale_bottom Scale
from
, scale_layout :: Layout
scale_layout = Scale -> Layout
Scale.scale_layout Scale
from
, scale_transpose :: Transpose
scale_transpose = Scale -> Transpose
Scale.scale_transpose Scale
from
, scale_enharmonics :: Enharmonics
scale_enharmonics = Scale -> Enharmonics
Scale.scale_enharmonics Scale
from
, scale_note_to_call :: Note -> Maybe ValCall
scale_note_to_call = Note -> Maybe ValCall
to_call
, scale_input_to_note :: Environ -> Input -> Either PitchError Note
scale_input_to_note = Environ -> Input -> Either PitchError Note
to_note
, scale_input_to_nn :: ScoreTime -> Input -> Deriver (Either PitchError NoteNumber)
scale_input_to_nn = (Environ -> Input -> Either PitchError Note)
-> (Note -> Maybe ValCall)
-> ScoreTime
-> Input
-> Deriver (Either PitchError NoteNumber)
Scales.computed_input_to_nn Environ -> Input -> Either PitchError Note
to_note Note -> Maybe ValCall
to_call
, scale_call_doc :: DocumentedCall
scale_call_doc = DocumentedCall
doc
}
where
to_call :: Note -> Maybe ValCall
to_call = Scale -> Scale -> Note -> Maybe ValCall
note_to_call Scale
from Scale
to
to_note :: Environ -> Input -> Either PitchError Note
to_note = Scale -> Environ -> Input -> Either PitchError Note
Scale.scale_input_to_note Scale
from
doc :: Derive.DocumentedCall
doc :: DocumentedCall
doc = ValCall -> DocumentedCall
Derive.extract_val_doc forall a b. (a -> b) -> a -> b
$ ValCall -> ValCall -> ValCall
interpolated_degree ValCall
dummy ValCall
dummy
where
dummy :: ValCall
dummy = forall a.
ToVal a =>
Module
-> CallName
-> Tags
-> Doc
-> WithArgDoc (PassedArgs Tagged -> Deriver a)
-> ValCall
Derive.val_call Module
Module.scale CallName
"dummy" forall a. Monoid a => a
mempty Doc
"" forall a b. (a -> b) -> a -> b
$
forall y d.
Taggable y =>
Generator y d -> WithArgDoc (Generator y d)
Sig.call0 forall a b. (a -> b) -> a -> b
$ \PassedArgs Tagged
_args -> forall (m :: * -> *) a. Monad m => a -> m a
return (Y
0 :: Double)
scale_id :: Pitch.ScaleId
scale_id :: ScaleId
scale_id = ScaleId
"interpolate"
scale_at :: ScoreT.Control
scale_at :: Control
scale_at = Control
"scale-at"
note_to_call :: Scale.Scale -> Scale.Scale -> Pitch.Note -> Maybe Derive.ValCall
note_to_call :: Scale -> Scale -> Note -> Maybe ValCall
note_to_call Scale
from Scale
to Note
note =
ValCall -> ValCall -> ValCall
interpolated_degree forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Scale -> Note -> Maybe ValCall
Scale.scale_note_to_call Scale
from Note
note
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Scale -> Note -> Maybe ValCall
Scale.scale_note_to_call Scale
to Note
note
interpolated_degree :: Derive.ValCall -> Derive.ValCall -> Derive.ValCall
interpolated_degree :: ValCall -> ValCall -> ValCall
interpolated_degree ValCall
from ValCall
to = forall a.
ToVal a =>
Module
-> CallName
-> Tags
-> Doc
-> WithArgDoc (PassedArgs Tagged -> Deriver a)
-> ValCall
Derive.val_call Module
Module.scale CallName
"pitch" forall a. Monoid a => a
mempty
(Doc
"Emit a pitch between two scales. The scales are in the "
forall a. Semigroup a => a -> a -> a
<> forall a. ShowVal a => a -> Doc
doc Key
scale_from forall a. Semigroup a => a -> a -> a
<> Doc
" and " forall a. Semigroup a => a -> a -> a
<> forall a. ShowVal a => a -> Doc
doc Key
scale_to
forall a. Semigroup a => a -> a -> a
<> Doc
" environ values, and keys are from " forall a. Semigroup a => a -> a -> a
<> forall a. ShowVal a => a -> Doc
doc Key
key_from forall a. Semigroup a => a -> a -> a
<> Doc
" and "
forall a. Semigroup a => a -> a -> a
<> forall a. ShowVal a => a -> Doc
doc Key
key_to forall a. Semigroup a => a -> a -> a
<> Doc
". If " forall a. Semigroup a => a -> a -> a
<> forall a. ShowVal a => a -> Doc
doc Key
scale_to forall a. Semigroup a => a -> a -> a
<> Doc
" isn't set, it defaults to "
forall a. Semigroup a => a -> a -> a
<> forall a. ShowVal a => a -> Doc
doc Key
scale_from forall a. Semigroup a => a -> a -> a
<> Doc
". The " forall a. Semigroup a => a -> a -> a
<> forall a. ShowVal a => a -> Doc
doc Control
scale_at
forall a. Semigroup a => a -> a -> a
<> Doc
" control ranges from 0 to 1\
\ and controls the interpolation between the scales. For this to work, the\
\ scales must have the same degree names, since there's no way to manually\
\ specify a correspondence between scale degrees."
) forall a b. (a -> b) -> a -> b
$ forall y a d.
Taggable y =>
Parser a -> (a -> Generator y d) -> WithArgDoc (Generator y d)
Sig.call (ArgName -> Doc -> Parser [Val]
Sig.many_vals ArgName
"arg" Doc
"passed to `from` and `to` scales") forall a b. (a -> b) -> a -> b
$
\[Val]
_vals PassedArgs Tagged
args -> do
RealTime
start <- forall a. PassedArgs a -> Deriver RealTime
Args.real_start PassedArgs Tagged
args
Y
n <- forall a. a -> Maybe a -> a
fromMaybe Y
0 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Control -> RealTime -> Deriver (Maybe Y)
Derive.untyped_control_at Control
scale_at RealTime
start
let apply :: Key -> ValCall -> Deriver (RawPitch a)
apply Key
key = forall a. Key -> Key -> Deriver a -> Deriver a
rename_environ Key
key Key
EnvKey.key
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. ScoreTime -> ValCall -> Deriver (RawPitch a)
Eval.apply_pitch (forall a. PassedArgs a -> ScoreTime
Args.start PassedArgs Tagged
args)
if Y
n forall a. Ord a => a -> a -> Bool
<= Y
0 then forall {a}. Key -> ValCall -> Deriver (RawPitch a)
apply Key
key_from ValCall
from
else if Y
n forall a. Ord a => a -> a -> Bool
>= Y
1 then forall {a}. Key -> ValCall -> Deriver (RawPitch a)
apply Key
key_to ValCall
to
else do
RawPitch Untransposed_
p1 <- forall {a}. Key -> ValCall -> Deriver (RawPitch a)
apply Key
key_from ValCall
from
RawPitch Untransposed_
p2 <- forall {a}. Key -> ValCall -> Deriver (RawPitch a)
apply Key
key_to ValCall
to
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ RawPitch Untransposed_
-> RawPitch Untransposed_ -> Y -> RawPitch Untransposed_
Pitches.interpolated RawPitch Untransposed_
p1 RawPitch Untransposed_
p2 Y
n
where
doc :: ShowVal.ShowVal a => a -> Doc.Doc
doc :: forall a. ShowVal a => a -> Doc
doc = forall a. ShowVal a => a -> Doc
ShowVal.doc
rename_environ :: Env.Key -> Env.Key -> Derive.Deriver a -> Derive.Deriver a
rename_environ :: forall a. Key -> Key -> Deriver a -> Deriver a
rename_environ Key
from Key
to Deriver a
deriver = do
Maybe Val
maybe_val :: Maybe DeriveT.Val <- forall a. Typecheck a => Key -> Deriver (Maybe a)
Derive.lookup_val Key
from
forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. a -> a
id (forall val a. ToVal val => Key -> val -> Deriver a -> Deriver a
Derive.with_val Key
to) Maybe Val
maybe_val Deriver a
deriver
environ_from_to :: Env.Environ
-> Either DeriveT.PitchError (Pitch.ScaleId, Pitch.ScaleId)
environ_from_to :: Environ -> Either PitchError (ScaleId, ScaleId)
environ_from_to Environ
env = do
ScaleId
from <- forall a val.
(Typecheck a, ShowVal a) =>
(a -> Maybe val)
-> Maybe val -> Key -> Environ -> Either PitchError val
Scales.read_environ (forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. Str -> ScaleId
Expr.str_to_scale_id) forall a. Maybe a
Nothing
Key
scale_from Environ
env
ScaleId
to <- forall a val.
(Typecheck a, ShowVal a) =>
(a -> Maybe val)
-> Maybe val -> Key -> Environ -> Either PitchError val
Scales.read_environ (forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. Str -> ScaleId
Expr.str_to_scale_id) (forall a. a -> Maybe a
Just ScaleId
from)
Key
scale_to Environ
env
forall (m :: * -> *) a. Monad m => a -> m a
return (ScaleId
from, ScaleId
to)
key_from, key_to :: Env.Key
key_from :: Key
key_from = Key
"key-from"
key_to :: Key
key_to = Key
"key-to"
scale_from, scale_to :: Env.Key
scale_from :: Key
scale_from = Key
"scale-from"
scale_to :: Key
scale_to = Key
"scale-to"