Safe Haskell | Safe-Inferred |
---|
Work with rulers and meters. A meter is a marklist on a ruler named
meter
, and is used by Cmd.TimeStep to align things. By
convention the meter has regular subdivisions, with Rank
s that
correspond roughly to timestep durations (e.g. whole, half, quarter notes).
The ruler marks are numbered, and this module, with the support of
Cmd.RulerUtil, lets you modify the meter in a higher level way and takes
care of renumbering the labels so e.g. measure numbers always count up even
if you double the length of the meter.
Ultimately this is necessary because I want to manipulate rulers as a high
level Meter.Meter
or LabeledMeter
, but Marklist
has lost
the meter's structure. That in turn is because different kinds of meters,
talams, gong cycles, etc. have different structures and I didn't think
I could come up with a single high level data structure that fit them all
and still allowed generic manipulation.
Many functions emit a Modify
. If defaults to RulerUtil.Section
scope,
but you can change it to work on selected tracks with tracks
or all
rulers in the block with block
. Then, the modify
function will
destructively modify selected rulers, while the local
function will
modify via copy-on-write, so that other blocks or tracks are unaffected.
Examples:
Start at a different measure number:
LRuler.modify $ LRuler.set_start_measure 4
Bali: 8 gongs with 4 jegogans per gong. Since counts are on calung, and there are 2 calung per jegogan, this is basically an 8 beat cycle:
LRuler.modify $ LRuler.gongs 8 4
Give the current block 6 sections of standard 4/4 meter, with 4 measures per section, where each measure gets 1t:
LRuler.modify $ LRuler.measures Meters.m44 6 4
- TODO make a middle measure 5/4?
Set a block to 8 avartanams of adi talam:
LRuler.local $ LRuler.ruler $ Tala.adi 8
Change the selected tracks to 8 avartanams of tisram:
LRuler.local $ LRuler.tracks $ LRuler.ruler $ Tala.simple Tala.adi_tala 3 8
Slow and fast rupaka, chatusra nadai:
LRuler.local $ LRuler.ruler $ Tala.simple Tala.rupaka_tala 4 8 LRuler.local $ LRuler.ruler $ Tala.simple Tala.rupaka_fast 4 8
Set a block to 8 avartanams of adi talam, then select tracks and set them to chatusram-tisram:
LRuler.modify $ LRuler.ruler $ Tala.adi 8 LRuler.local $ LRuler.tracks $ LRuler.ruler $ LTala.chatis 8 4
Synopsis
- rename :: Id.RulerId -> Id.RulerId -> Cmd.CmdL ()
- listn :: Cmd.CmdL [(Id.RulerId, Int)]
- list :: Ui.M m => m [(Id.RulerId, [Id.BlockId])]
- gc :: Ui.M m => m [Id.RulerId]
- unify :: Ui.M m => m [[Id.RulerId]]
- sync_ids :: Ui.M m => m Text
- list_misnamed :: Ui.M m => m [(Id.RulerId, Id.BlockId)]
- blocks_of :: Ui.M m => Id.RulerId -> m [Id.BlockId]
- set_ruler_id :: Ui.M m => Id.RulerId -> Id.BlockId -> m ()
- copy :: Cmd.M m => Id.BlockId -> m ()
- set :: Ui.M m => Id.RulerId -> Id.BlockId -> RulerUtil.Scope -> m ()
- ruler :: Cmd.M m => Meter.Meter -> m Modify
- lruler :: Cmd.M m => Meter.Meter -> m [Id.RulerId]
- modify_rulers :: Cmd.M m => (Ruler.Ruler -> Ruler.Ruler) -> m ()
- replace_ruler_id :: Ui.M m => Id.RulerId -> Id.RulerId -> m ()
- get_meter :: Ui.M m => Id.BlockId -> m Meter.Meter
- get_sections :: Ui.M m => Id.BlockId -> m [Meter.MSection]
- get_marks :: Ui.M m => Id.BlockId -> m [(TrackTime, Mark.Mark)]
- selected_marks :: Cmd.M m => Meter.Rank -> m [(TrackTime, Mark.Mark)]
- selected :: Cmd.M m => m Id.RulerId
- upgrade_infer :: Meter.AbstractMeter -> Upgrade
- infer_measure_dur :: Mark.Marklist -> TrackTime
- upgrade_gong :: Upgrade
- type Upgrade = Mark.Marklist -> (Meter.Meter, String)
- replace_meters :: Ui.M m => Bool -> Upgrade -> m String
- replace_meter :: Ui.M m => Bool -> Upgrade -> Id.RulerId -> m String
- append :: Cmd.M m => m Modify
- append_ruler_id :: Cmd.M m => Id.RulerId -> m Modify
- delete :: Cmd.M m => m Modify
- insert :: Cmd.M m => TrackTime -> m Modify
- replace_range :: TrackTime -> TrackTime -> [Meter.MSection] -> Meter.Meter -> Meter.Meter
- type Sections = Int
- type Measures = Int
- measures :: Cmd.M m => Meter.AbstractMeter -> Sections -> Measures -> m Modify
- gongs :: Cmd.M m => Gong.Gongs -> Gong.Jegogans -> m Modify
- java :: Cmd.M m => Int -> m Modify
- concat :: Cmd.M m => [Id.BlockId] -> m Modify
- pull_up :: Cmd.M m => m Modify
- push_down :: Cmd.M m => Bool -> m ()
- tracks :: Cmd.M m => m Modify -> m Modify
- block :: Cmd.M m => m Modify -> m Modify
- data Modify = Modify {}
- modify_sections :: Cmd.M m => ([Meter.MSection] -> [Meter.MSection]) -> m Modify
- set_start_measure :: Cmd.M m => Meter.Measures -> m Modify
- modify_selected :: Cmd.M m => (Meter.Meter -> Meter.Meter) -> m Modify
- make_modify :: Id.BlockId -> TrackNum -> RulerUtil.ModifyRuler -> Modify
- get_block_track :: Cmd.M m => m (Id.BlockId, TrackNum)
- local :: Cmd.M m => m Modify -> m [Id.RulerId]
- modify :: Cmd.M m => m Modify -> m ()
- local_m :: Cmd.M m => Modify -> m [Id.RulerId]
- modify_m :: Cmd.M m => Modify -> m ()
- local_ruler :: Ui.M m => Id.BlockId -> (Ruler.Ruler -> Ruler.Ruler) -> m Id.RulerId
- set_start :: Cmd.M m => m Id.RulerId
- set_end :: Cmd.M m => m Id.RulerId
- add_cue :: Text -> Cmd.CmdL Id.RulerId
- remove_cues :: Cmd.CmdL ()
- add_cue_at :: Id.BlockId -> TrackNum -> ScoreTime -> Text -> Cmd.CmdL Id.RulerId
- cue_mark :: Text -> Mark.Mark
- cue_name :: Ruler.Name
- selection_range :: Cmd.M m => m (TrackTime, TrackTime)
general purpose
rename :: Id.RulerId -> Id.RulerId -> Cmd.CmdL () Source #
listn :: Cmd.CmdL [(Id.RulerId, Int)] Source #
List all rulers, along with the number of blocks each one appears in.
list :: Ui.M m => m [(Id.RulerId, [Id.BlockId])] Source #
gc :: Ui.M m => m [Id.RulerId] Source #
Destroy all unrefereced rulers, and return their now-invalid RulerIds.
unify :: Ui.M m => m [[Id.RulerId]] Source #
Group together rulers that are the same, replace all the duplicates with the first ruler in each group, then gc away the duplicates. Return the duplicates.
sync_ids :: Ui.M m => m Text Source #
After copying blocks around and fiddling with rulers, the RulerIds can wind up with names from other blocks. Synchronize RulerIds along with their owning BlockIds. A RulerId only on one BlockId is assumed to be local to that block, and will get its name.
list_misnamed :: Ui.M m => m [(Id.RulerId, Id.BlockId)] Source #
blocks_of :: Ui.M m => Id.RulerId -> m [Id.BlockId] Source #
Blocks that contain the given ruler.
set_ruler_id :: Ui.M m => Id.RulerId -> Id.BlockId -> m () Source #
Set the rulers on a block to the given RulerId.
copy :: Cmd.M m => Id.BlockId -> m () Source #
Copy the ruler of the given block to the current one.
set :: Ui.M m => Id.RulerId -> Id.BlockId -> RulerUtil.Scope -> m () Source #
Set the ruler of the tracks in the given scope.
lruler :: Cmd.M m => Meter.Meter -> m [Id.RulerId] Source #
modify_rulers :: Cmd.M m => (Ruler.Ruler -> Ruler.Ruler) -> m () Source #
Modify all rulers.
replace_ruler_id :: Ui.M m => Id.RulerId -> Id.RulerId -> m () Source #
Replace all occurrences of one RulerId with another.
query
get_meter :: Ui.M m => Id.BlockId -> m Meter.Meter Source #
get_sections :: Ui.M m => Id.BlockId -> m [Meter.MSection] Source #
selected_marks :: Cmd.M m => Meter.Rank -> m [(TrackTime, Mark.Mark)] Source #
Ruler under the selection having at least the given rank.
selected :: Cmd.M m => m Id.RulerId Source #
Ruler of the track under the selection.
upgrade to Meter.Meter
type Upgrade = Mark.Marklist -> (Meter.Meter, String) Source #
replace_meters :: Ui.M m => Bool -> Upgrade -> m String Source #
LRuler.replace_meters LRuler.upgrade_gong LRuler.replace_meters (LRuler.upgrade_infer Meters.m44)
replace_meter :: Ui.M m => Bool -> Upgrade -> Id.RulerId -> m String Source #
Add a Meter for the ruler if not already present.
Modify
append :: Cmd.M m => m Modify Source #
Copy the meter under the selection and append it to the end of the ruler.
append_ruler_id :: Cmd.M m => Id.RulerId -> m Modify Source #
Append another ruler to this one.
insert :: Cmd.M m => TrackTime -> m Modify Source #
Insert the selected meter range at the given time.
replace_range :: TrackTime -> TrackTime -> [Meter.MSection] -> Meter.Meter -> Meter.Meter Source #
measures :: Cmd.M m => Meter.AbstractMeter -> Sections -> Measures -> m Modify Source #
Set the ruler to a number of measures of the given meter, where each measure gets 1t:
LRuler.local $ LRuler.measures Meters.m44 4 4 LRuler.modify $ LRuler.measures Meters.m34 4 8
gongs :: Cmd.M m => Gong.Gongs -> Gong.Jegogans -> m Modify Source #
Create gongs with gongs
.
concat :: Cmd.M m => [Id.BlockId] -> m Modify Source #
Replace the meter with the concatenation of the rulers of the given
blocks. This is like extract
except it doesn't infer the blocks from the
calls and doesn't scale the extracted rulers.
pull_up, push_down
pull_up :: Cmd.M m => m Modify Source #
Extract the meter marklists from the sub-blocks called on the given track, concatenate them, and replace the current meter with it.
modify
tracks :: Cmd.M m => m Modify -> m Modify Source #
Change a Modify so it modifies only the selected tracks.
block :: Cmd.M m => m Modify -> m Modify Source #
Change a Modify so it modifies all rulers on the block.
Enough information to modify a ruler.
TODO I could also include entire block, and then add_cue etc. could use it, in addition to being able to clip the entire block.
modify_sections :: Cmd.M m => ([Meter.MSection] -> [Meter.MSection]) -> m Modify Source #
set_start_measure :: Cmd.M m => Meter.Measures -> m Modify Source #
modify_selected :: Cmd.M m => (Meter.Meter -> Meter.Meter) -> m Modify Source #
make_modify :: Id.BlockId -> TrackNum -> RulerUtil.ModifyRuler -> Modify Source #
get_block_track :: Cmd.M m => m (Id.BlockId, TrackNum) Source #
local_m :: Cmd.M m => Modify -> m [Id.RulerId] Source #
Modify a ruler or rulers, making a copy if they're shared with another block.
modify_m :: Cmd.M m => Modify -> m () Source #
Modify the ruler on the focused block. Other blocks with the same ruler will also be modified.
local_ruler :: Ui.M m => Id.BlockId -> (Ruler.Ruler -> Ruler.Ruler) -> m Id.RulerId Source #
Modify a local copy of the main block ruler.
bounds
set_start :: Cmd.M m => m Id.RulerId Source #
Set the block's logical start time to the selection. Notes before this will play before the start of the calling event.
set_end :: Cmd.M m => m Id.RulerId Source #
Set the block's logical end time to the selection. Notes after this will play after the end of the calling event.
cue
add_cue :: Text -> Cmd.CmdL Id.RulerId Source #
Drop a mark at the selected point in the "cue" ruler.
remove_cues :: Cmd.CmdL () Source #
add_cue_at :: Id.BlockId -> TrackNum -> ScoreTime -> Text -> Cmd.CmdL Id.RulerId Source #