-
Notifications
You must be signed in to change notification settings - Fork 2
/
TODO
9630 lines (9491 loc) · 527 KB
/
TODO
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
LEGEND
- todo; + in progress; * done; / obsolete, do not want, or can't repro
? open question; . note; bug: marks bugs.
Use indent folding with indent=2.
current:
priorities for javanese:
better ruler
. line = 4 gatra, gatra = 4 notes (q)
. I want cmd-; to add a gatra. Then sections is, gongs? or lines?
Maybe I don't care about sections so much, because at score level
I can use w and b. So call it lines, but it shouldn't have its own
numbers?
. Or, what if I did it for gatra? In that case q is 1/2t which seems
awkward.
. But if I say w = 1t = gatra, then I have to get up to t32 for ir2
panerus, which would make ir4 below even t64.
. More convenient if 1 is gatra
record samples:
+ gender panerus
- gender barung
* slenthem
- saron
+ kenong
- gong
- gambang?
- bonang?
infer duration:
. next-note still not right for gender barung. Some notes are clearly
intended to merge, while others are counterpoint. Also gender barung
will switch to the pipilan.
. What if I go to the Score.event_min of the next note on the same hand?
It's weird because this note's duration is the whitespace.
- different infer-duration gender barung vs. panerus.
. It's two hands so can't put it on a single track title, usual problem
with transformers. In any case, it won't reach across track
boundaries. And in any case I will want to switch heuristics.
. So maybe use env var to select heuristic, and an all-purpose infer
that looks at that.
vocabulary:
. pipilan - one melody using two hands
. irama: 1/2 1 2 3 4
lancar tanggung dadi wiled rangkep
peking 1 2 4 8 16
. cengkok: aj aja ngono, ak ayu kuning, dl dualolo
. O gong ( ) gong suwukan, ^ kenong, ˇ (caron) kempul
ruler:
4t = 1 gatra = w
1t = 1 note = q
ghc:
. make core easier to read:
https://www.youtube.com/watch?v=yRVjR9XcuPU&ab_channel=Tweag
-dsuppress-module-prefixes -dsuppress-coercions
-dsuppress-type-applications
-ddump-to-file -ddump-simpl
. Open a feature request ticket with GHC API info.
. Open a ticket with info about bake's ghc build papercuts.
. ghc api memory use should get much better in 9.4
Rather than insert all ModDetails, forget them and just deserialize the
interface file.
. serialize core / stg
ask about recompilation avoidance:
. use hash instead of mtime? 9.4 ticket 1939
- how about put all the flags etc. in .hi instead of the hash, for better
reporting?
. why not -ddump-hi-diffs?
. maybe just do it?
what is the x-axis on the profile?
. CPUTime, mutator time
what about time profile?
. what about entries?
eventlog format.rst in ghc source tree
usability:
- Is there a better way to write alternate-endings:
. I would want to write variations of the same block, but the ending
depends on the next one. The unmodified parts should be shared.
. The endings may be different durations.
. A general way to do it would be make score derivations, but give a name
that indicates the next one, like a->b. Then when rendering 'a',
if the next block is 'b', look for a a->b first, and fall back on 'b'
otherwise.
. The gender piece doesn't actually use this that much, so maybe not.
But I've come across this need for alternate endings before.
I feel like the problem is representing it in the score though, e.g.
writing it as part of the block itself, rather than ending the block
and attaching another at the caller's level.
. salya-satyawati has one, I used final=t and awkward extra tracks.
- For gender, I want to set a track pattern and have all new blocks do that.
. Also the same for a meter.
. "new block from template" was supposed to do this, how is it not enough?
. Well, it's not retroactive.
. Also I'd want to do a score integrate to left hand, how to do?
- Template copy should copy score integrates.
- It really is annoying to mave to maintain the the score-level blocks,
. I really do want them automatic. TScore is almost this.
. Can I make tscore less friction? What exactly is the friction?
. I can't remember the syntax!
%meter=gong
score = %default-call "block title" [
>" | track title" a/0 b c d ...
]
. I don't want to need /0. I could have %score which is like
%default-call except always /0. Seems like a really minor
thing though.
. And for such a minor seeming thing it was incredibly hard to implement
and I failed at several ways. I need %default-call with durations for
drums anyway.
. default-0:
. What if I just generated a commented out template example the first
time?
- Undo not recording during insert causes me to lose stuff.
. Record in edit mode? Why not?
STATUS
- Biggest problem is input lag when editing, or when rerendering.
. I haven't been doing enough editing lately to know what it is. Once
I do that, I have to characterize it so it can be reproduced, and
then figure out how to fix.
- raga-janaka stalled
. infer gender damping:
- make kendang sampler instrument
. Make thru work for it, and refactor thru in general.
. refactor thru:
external:
vim:
- mark ] is set on the last yanked character. So when you move stuff
arround, after you pressed p, to indent you just need to press >'] (or <'])
and repeat (.)
- https://github.com/jeetsukumaran/vim-indentwise
- fix-imports on Derive/C/Prelude/Val.hs can't find Data.Attoparsec.Text.
Is fix-imports not getting the cabal v2 environ?
. Also no System.Random.Mersenne.Pure64
- c-\ is wrong for local refs, e.g. follow 'parse' in Check_test.hs
- find some way to integrate Shake.ImportQuery into my workflow
. At least I'd like a warning about what adding or removing an import
means. Maybe that means integrate with fix-imports?
record screencast of using karya:
. https://neilmitchell.blogspot.com/2021/01/recording-video.html
basic notes / intro:
. basic note entry, with kbd and midi
. show keycaps
. switch to twelve-r, key changes
. other scales, tuning
. write a melody, show Factor, put phrase in several spots
. refactor to a relative pitch offset
. add some random, e.g. alternates
. what if I want to change one? Show integrate?
. percussion: write drum track
. show sampler/break
. show MIDI, im, sc backends
im:
. sampler
. show faust, write a basic patch, use it
fancy notes:
. sekar, with track integration
. balinese stuff
full score:
. LState.ky
. TScore.edit, especially for score sequence
controls:
. interpolation, docs with LBlock.doc_equal "i>"
. high level pitch notation
. gamakam
. using tscore, especially standalone
UNSORTED
- remove midi modifiers? I never used them.
- What if I highlighted >1 in the waveform display?
- fltk: The dyn=6 problem is showing that track titles are pretty bad.
. Especially on the right side.
. How about they make a text field that covers the whole block, like the
block title?
. It still means you can't see anything in them, but I don't see a way
around that.
- im thru for samples is missing transpose and attr
live play:
. What would it take for karya to be able to do live performance?
. I'd want to be able to script such that it loops until forward or
backward, then can transition out, and go to the next section.
. Requires either MIDI or a streaming variant of im.
. I'd need a way to annotate flow control in the score.
I want this anyway, for alternate endings.
. Then script like: loop AB, transition AC, loop D.
Going back like loop D, transition E, loop AB
. Javanese scores also want this.
. Unlike loop play, I'd want to actually generate score and stream it,
so randomness works. It would be like an infinite score stream.
. Even if derive is streaming (and it should be), it can't actually be
a lazy list, not without unsafePerformIO, due to user input. But,
I can generate chunks, right? I would need to be able to resume
derive, which should be possible if I keep the state.
. UI would have to change to stream too, if I want to show the score as it
plays. Probably also want to scroll in realtime? This is just nice to
have, but at minimum I'd want to show the script and where I am in it.
. But, there won't be a single strict Warp out of it. I think what I do
is derive it without loops, so I get Warp and track signals. Then
splice together the warps for playback, even as I'm streaming new
Ui.Events. This is accurate, because if the UI display position it's
a fake up based on the logical score position.
. So this is like loop play, only instead of looping the MIDI or audio,
I loop the UI events.
what about tap for tempo?
. Or maybe easier to use a knob or a button to step tempo.
. This would dynamically stretch the streamed UI events.
. Of course tempo tracks are in there too, but they would get stretched
too.
- bug: LPerf.sel_sampler_events uses the local track even when using
LPerf.Root
. Also it should default to Root, and have a _local option?
- sampler slenthem distorted sample:
/Users/elaforge/src/seq/main/data/sampler/java/slenthem/open/22-ff-v1.wav
. The sample isn't distorted.
. The chunk is distorted. Must be happening in sampler-im.
. Happens even when volume is lower, where is the clipping happening?
. Actually looks like the sample is distorted, just hard to hear at
full volume (?)
- selections, both insert and subblock position, can be very hard to see
- subblock position only shows where there are notes
- infer-negative heuristic should be changeable dynamically
. Because even gender barung goes to pipilan sometimes.
. Or maybe go to positive durations, but only infer the last one?
. Also have a default per instrument, e.g. panerus->
- why is zero-mute not working for java samples?
. Probably because it needs a special postproc, can I build that in?
. Is working for gender wayang.
- bug: error in ky spams errors in logview
. It should suppress after too many of them? Or subsystems themselves
should suppress?
- fltk: not wrapping by char is quite annoying
I think I did this on purpose though?
- divide up App.Config
. Move stuff that shouldn't be changed, like pixels from c++, to its own
module.
. Move EventTrack.cc rank_brightness negative_duration_brightness
to color config.
- I still have the out of sync problem with ky inst allocs vs UiConfig
- upgrade to ghc 9.4:
+ fclabels doesn't like base 4.17
. Probably due to TH as usual, which I don't even use.
. easily fixable: https://github.com/sebastiaanvisser/fclabels/issues/44
. But still it's a liability compared to say microlens.
. Or optics-core, for better errors?
. Or inline my own?
. Can just bump the version bounds.
. But why did I stop Util.MicroLens? Maybe because the constructor is
different?
. Even optics-core looks crazy. What if I migrate to DotRecordSyntax
and remove lenses entirely?
+ compiling clock:
error: ld: unknown option: -no_fixup_chains
. https://github.com/haskell/zlib/issues/53
. Edit hcs2hs. This is because my OSX is too old.
- GhcRepl: GHC.Target has changed
- I may have to do GHC.loadWithCache in ReplGhc
. Cache provided by newIfaceCache
. https://downloads.haskell.org/~ghc/9.4.6/docs/users_guide/9.4.1-notes.html#ghc-library
. Enable -fworker-wrapper-cbv, usually good but not on by default.
? suddenly new instruments don't get midi, wtf?
. It was reaper "record monitoring".
. Since I forget this a lot, can I have some way to remind myself?
- mridangam-d doesn't seem to want to do sub halfsteps
. But it's now around d4 (62nn) while 4i is 62.5
(62.50, 63.00) -> 62.75
(74.57, 74.80) (62.57, 62.8)
. So I'd have to adjust it up.
ky instruments section buggy:
* LState.ky is not having new instruments I added
. Even worse it seems like this causes new allocations to not get saved!
. Either LInst.add has to edit the ky, or I have to get rid of it and
allow only ky.
. Since the source of truth is not ky, I must not privilege it.
I originally kept it so I could preserve order and comments.
I guess I can still do that, but have to regenerate it each time
insteat of the first time only.
. To go all-in on instruments in ky, I need to complete the ky-record
stuff, then remove UiConfig.config_allocations entirely. It will
exist entirely as the parsed output of ky.
- when I add kontakt/wayang-pemade, it says "send: midi inst with no
channels"
. But it's not a midi inst!
. No wait now it works, did I accidentally put loop on before?
? Anyway how does it know the corect backend?
* instruments doesn't like empty lines!
- LPerf.sel_midi gets muted tracks, but more importantly, non selected
tracks!
. Can't reproduce the latter.
- I still want a way to impose a track template across existing blocks, e.g.
add an instrument.
. It would need to be a bit clever to get the diffs and not destroy
existing tracks. I guess it should be add-only.
. Given a template block, for each other block, pair inst tracks by
title. If there is missing, insert there.
. Respect collapse and minimize.
+ wayang pemade calung 3u sample has a clunk
? is there the same in im-sampler?
. 71-65-108-calung2.ncw
- I keep looking for LBlock.doc in LDoc, should I move it there?
- ^z on vi from a repl messes up tty state
. Probably have to stty restore or something?
. If I'm making ky more central, then maybe I have a way to edit it
separately from the repl?
- why do I need UiConfig.meta_notes when I could put it in a comment in
UiConfig.config_ky?
. It would be a bit better for searching if I ever wanted to do that, but
I could also just grep ky text.
. In fact I could put all UiConfig.Config stuff in there, such as
namespace, root, lilypond, default_tempo, etc.
. Why not merge ky and tscore too?
- why do a get a short note when a track of the same instrument is muted?
. LPerf.sel_midi_events has dur .25, but midi has:
[ loop1 1.75s: chan:1 NoteOn e6(88) 64
, loop1 1.75s: chan:1 NoteOff e6(88) 100
, loop1 1.75s: chan:1 NoteOn e6(88) 64
, loop1 1.99s: chan:1 NoteOff e6(88) 64
]
. why NoteOf vel of 100? Source event has velocity = (.5, .5)
. The 100 is probably from Perform.default_velocity
. These are all duplicated notes! So the mute is not really happening!
how to make this easier to debug?
- visualization for MIDI events?
. Or analysis back into notes and durations?
. I could tag things like overlapping NoteOns, orphan NoteOffs, etc.
. Doesn't Midi.State already do that kind of thing?
Or Midi.Synth?
- A trace for how each MIDI event is generated?
. At least keep a reference to the generating perform event.
. But I want to do it so it's efficient in the usual case when I don't
want it.
- space leaks:
. https://kodimensional.dev/space-leak
. look for puts into MVar and IORef, make sure they are !
. returning a value with local refs maybe uses 'return $! ...'.
. Beware of Maybe and (,) etc. Use
https://hackage.haskell.org/package/strict-wrapper
or https://hackage.haskell.org/package/strict
. strict-wrapper requires a lot of Strict noise, wrapping each type but
also wrapping each construction and deconstruction. The significant
types are just Maybe, Either, (,).
. strict has awkward names, must be used qualified but reuses Maybe name
and all functions. So if I do that, write my own SMaybe and SEither.
. I could also try more StrictData, and put ~ on explicitly lazy fields.
semara-dana:
- '/' or '?' to play from root starts in the wrong spot in dim-g-ang1
- ugal notes still get stuck mutes
- semara-dana-im fails on ngoret and stops rendering after the 1st block
. But I don't want two scores, I want to be able to toggle instrument
sets.
. I can save and load inst config, why not use that?
. It would be more explicit to include them both in `ky` or something,
and be able to comment / uncomment.
+ inst allocation in ky: branch ky-record:
* implement Record type and parser
/ I'll probably need to parse and unparse comments too:
. commented out lines for unset config
. However, if this is really the source of truth, then whence the
generated stuff? Maybe instead I just have a function to emit
a commented out example, that I edit to suit.
. Inherited environ. I guess I can include this too, if it's for
a specific patch.
+ pretty printer to generate an initial expression with comments
. AllocRecord.from_allocation
one purpose is to provide a starting point for existing scores:
other is to provide something to edit to add new instruments:
. Take an LInst.add (name, qualified, loop, addrs) and
print an example expression full of comments.
. It seems annoynig to have to learn a special language and know all
the possible values. If I'm using haskell, I have the same problem
though... but at least I can do tab completion and I know where to
look in the source and there are medium-quality errors.
. Alternately, I could regenerate the instruments section every time,
and not store it in ky. Sort of annoying because comments go away.
. So, try to preserve comments, this is merge_instruments.
parse Record -> UiConfig.Allocation:
- integrate parsing the initial line
- implement REnv.demote
- Text -> Maybe Patch.Scale so I can save it by name, will need registry
- simplify Midi.Patch.Addr to (WriteDevice, [Channel])
cleanup:
/ maybe all '-strings into Parse.Strict
. Why though? I actually do use symbols like key = d#-maj
- merge RVal with Val, REnv with Env
. see notes below, will allow Eq Val instance
- serialize ControlFunction as an expression
- serialize Pitch as a constant pitch
* unify with TScore
. But this will make errors bad because of attoparsec. So first
implement 'attoparse' so it can be in megaparsec.
- kill threads in Cmd.Ky.update_cache?
* switch Derive.Parse.Instruments to megaparsec, and "shell out" to
attoparsec just for p_val.
. attoparse :: A.Parser a -> Parser a
- Refactor to remove the duplication by embedding an RVal in a DVal.
. type DVal RVal (* has parser, - has type)
Num * -
Attributes * -
ControlRef * -
ConstantPitch - (promote to Pitch)
Pitch -
PControlRef *
NotePitch - -
Str * -
Quoted * - (of Expr DVal and Expr RVal)
ControlFunction *
NotGiven *
Separator *
List * - (of DVals and RVals respectively)
. Quoted and List have the same problem, where they need to be
parameterized by val.
. So:
data RVal val = VList [val]
data DVal = RVal (RVal DVal) | VControlFunction
. The non-parseable thing is really just Pitch and ControlFunction.
Could I define a literal for Pitch? Basically that's what
ConstantPitch is. If it gets serialized and deserialized it would
lose its transpose, but that's ok, right?
. Then I have ControlFunction, which is a haskell function.
. The main thing is I can't serialize this, so I can't put it in an
instrument. Except, I could serialize it as the expression that
creates it, like `cf-rnd 1 2`, but deserialize would have to mean
evaluate it in the standard library context. This is the same as
the "literal" syntax for list, (list 1 2).
. If I do this, I can eliminate REnv and RVal entirely.
- Serialize Pitch. It can set it to ConstantPitch.
- Serialize ControlFunction. I can save it as name plus args.
. But maybe I can take another look at ControlFunction first,
I still don't like it at all.
- Experiment to see if megaparsec is just as fast as attoparsec now.
notes:
. Check.parse_instruments -> Parse.p_allocation
>pno pianoteq/ midi loop1 0 1 2
>tmb faust/tambura4 im
>osc sc/inst sc
>dum kontakt/sc-calung-pasang dummy
example:
instruments:
>calung kontakt/sc-calung-pasang (dummy)
{ +inst-polos: calung-p
, +inst-sangsih: calung-s
}
>calung-p kontakt/sc-calung loop1 [3]
{ -inst-bottom: (pitch 4 0)
, -inst-top: (pitch 4 6)
, +tuning: umbang
}
(scale legong umbang 49 keys)
>m-d kontakt/mridangam-d loop2 [3] {mute}
. I could have a generic records and values syntax. Like JSON but
with comments... and no "s?
. Though if I use literally json and strip comments I can reuse aeson.
. Also seems like I want tuples?
>pemade-p
{ qualified = 'kontakt/sc-pemade'
, config: -- Common.Config
{ environ = {tuning = 'umbang'}
, mute = False, solo = False
}
, backend: -- Midi Patch.Config | Im | Sc | Dummy
{ allocation = [("loop1", 6)]
, initialization = Tuning | NrpnTuning
, settings =
{ flags = {Pressure, HoldKeyswitch, ResumePlay}
, scale = "legong umbang"
, pitch_bend_range = (-12, 12)
, control_defaults = {cc1 = 42}
}
}
}
. >pemade-p kontakt/sc-pemade [ms] {"tuning": "umbang"} loop1 6
{ "initialization": "Tuning" | "NrpnTuning"
, "settings":
{ "flags": ["Pressure", "HoldKeyswitch", "ResumePlay"]
, "scale": "legong umbang"
, "pitch_bend_range": [-12, 12]
, "control_defaults": {"cc1": 42}
}
}
. The quotes on keys are annoying, since this really has nothing
to do with javascript.
. There are various quoteless json things, but no haskell parsers.
. However, I'm going to want comments anyway, and to use --.
. Probably is not that hard to write, actually:
data Val = Record (Map Text Val) | List [Val]
| Number Double | Str Text
. Even so there would be a fair amount of faffing about converting.
. Alternately, have a mini format that doesn't affect env, etc.
Just name, qualified, alloc, flags, maybe with other values in
comments?
. But I'm losing track of the original idea to switch between MIDI and
im backends. That's hardly a general purpose thing though. Why don't
I just save and load .inst?
. Also I can't move instrument declaration to ky and retain standalone
.tscore files.
. >pemade-p kontakt/sc-pemade [ms] loop1 6 {
-- common
environ: {tuning: 'umbang'},
controls: {dyn: .5},
-- midi
initialization: 'Tuning',
settings: {
flags: ['Pressure', 'HoldKeyswitch', 'ResumePlay'],
scale: 'legong umbang',
pitch_bend_range: [-12, 12],
control_defaults: {cc1: 42},
}
}
. It does seem generally useful to have a readable text version of
insts, then .inst files could be text, and I could edit in vi.
. Alternately, use a vi like a GUI to have a menu of instruments, where
I can toggle mute, solo, etc.
* parse and unparse with flags
- hook that up to LState.ky
. I'd have to move all the TScore types to Derive.Parse, which is
unappealing since megaparsec -> attoparsec and I'd need to move
all the types too.
. If I put allocs entirely in ky, it would allow me to have allocs in
imported .ky files. In fact, .inst goes away and becomes .ky.
. Taken to its logical conclusion, this then removes the various alloc
functions in LInst in favor of editing a special language in ky.
. I can still have them though, and the "generate" ones may be useful,
but they would become an unparse and insert into ky.
. The cost is a much more elaborate values syntax
. Is this good? Not sure.
+ implicit skeleton doesn't work for dyn over two tracks
. Instead, it assigns it to the note track to the left.
. How can I disambiguate?
. The only place is in the title, e.g. 'dyn >' or '^dyn'?
It's a bit weird because it has no effect on the track but is a signal
to the parse skeleton.
. I could do --> which is a nice arrow, but it's a comment... though
I guess I already have comment "pragma" in --|
. Ok, let's do it.
. Not good enough, because it doesn't preserve the end of the scope.
. Maybe I just go back to explicit skeleton then.
/ on midi kbd and pitch bend I get
. scale_input_to_nn for PianoKbd:5-1+.001: unparseable note: 5r 0
. What is the actual Pitch.Note it's trying to parse?
. Not necessarily any such thing, Scales throws it without an intermediate
Note.
. Or should it really be InvalidInput? Those are silent.
. Or it should be valid! For thru I should remap to an intermediate
pitch. This is coming from computed_input_to_nn.
. That means probably input_to_note -> note_to_call
. I seem to get it just on pitch bend, no note on.
. Because it's thru? Because it just wants to emit InputNote.PitchChange
. This means input_to_note is able to produce a note
ScaleDegree.scale_degree won't parse.
. But it can!
. note_to_call: (Note "5s 38", UnparseableNote (Note "5s 38"))
. TheoryFormat.read_relative can't parse a full expression, it's only
meant for the "4s" part.
. The type Pitch.Note here is incorrect, it shouldn't have a space.
. ScaleDegree.pitch_expr should actually return an expr!
. However, that means InputToNote and scale_input_to_note must change.
Or Pitch.Note needs to be an expr.
. The purpose of this is so that I can input note plus pitchbend as a
bent note. Or possibly continuum. But since I hardly use midi
keyboard, I haven't noticed that it's broken, and I'm not even
sure if I want it.
. The purpose of the thru part is to be able to hear pitch bend or
continuum, but it's quite inefficient because it goes through expression
and eval back to MIDI, but that's the price to pay for arbitrary pitch
mapping, and arbitrary backend too. So if I want to convert MIDI plus
pitch bend to OSC or something, then I would want this. Assuming thru
for OSC is generalized.
. Pitch.Note is messy anyway, seems like it should be a subset of
Derive.Expr Text.
- convert scale_input_to_note to return 'Expr MiniVal'
. so ScaleDgree.pitch_expr can actually return an expr
. re-enable test in NoteTrack_test.test_cmd_val_edit_advance
- test for Example.Integrate
- bug: I made a top, calling b2, then LBlock.rename @b1, top still had b2
and play still worked.
. Cache bug?
. Can I do quickcheck tests against the cache?
- extend after delete shouldn't extend if the next event doesn't go to end
of block
things that make bisecting not work:
. that rubberband ref in ShakeConfig
. fltk not version controlled
. Using nix would solve these.
. scores are not version controlled
- save/bali is all messed up apparently due to some instrument change
. add "r" for my reyong to bali.inst
. gabor has old norots?
. then put some of them into verify so it doesn't happen again!
- shouldn't Id.clean do validation and return Nothing?
- I want to do vibrato and vibrato depth, but it's a pain to add new tracks.
. But it should be in pitch, do I have vibrato settings there?
. Maybe I should use the provided ways though, or at least be able to.
This is into that problem of control tracks that generate >1 control.
. Long ago there was a splice idea to change control track titles in the
middle, but for multiple values, that's what ControlMod is for.
. What if I have a vib call that emits vib and vib-speed? This is uneasy,
like all ControlMods, since it's independent from the control track,
instead just being a generic control. If I pursued this to its
conclusion, then we would just have one kind of generic control track,
and use names for all the controls.
- Make Derive.parse_expr invertible
. I do partial parsing to modify expressions. Actually I think it's ok
to parse all the way to Expr Val, since the Vals parsed in here are all
reversible, but I need to preserve the whitespace. Or maybe I don't
even need to do that, I don't mind having a syntax "normal form".
I think the only questions are spaces around "=" and a trailing comment.
I could actually preserve spaces in the parsed form, and have an
explicit value for comments, and then I should have fully reversible
syntax, which means structural editing has access to the final parsed
form.
. This way I can get rid of Parse.split_pipeline, Parse.lex, etc. I can
also get rid of the special rules in PitchTrack.PitchCall, buggy
whitespace fiddling, and structural editing can have a fully parsed
expression.
. Maybe I can get rid of ControlTrack.Partial entirely, just use
DeriveT.Expr! Or maybe RestrictedEnviron.Val?
- include comment
. Comments are special in that they only happen at the end, so I think I
can change lexeme to be only spaces, and then do an optional comment
at the end. This should be more efficient too!
. This doesn't apply to ky though!
. Since spaces used to check for --, I now need to explicitly not match
that everywhere...
- include spaces on =.
. This pushes me toward separate Call | Equal constructors, but that
means I don't have to do the awkward special case with the operator,
so maybe it's for the best.
- Verify roundtrip for expressions.
. Maybe I could clean up parse/unparse. Unparse could be
non-overloaded, just invert Derive.parse, with the usual caveats for
Vals without literals. Then show_val is Typecheck.ToVal a => ShowVal a.
. What of MiniVal and RestrictedEnviron.Val? I guess they'd need their
own show_val... or just ToVal!
. I could maybe resolve the toplevel thing by keeping the Toplevel type.
. Also fix the quotes-or-not? Str gets them via Text, Symbol doesn't
get any.
. Do I still want Symbol/Str distinction though? Was it due to
toplevel?
- Remove duplication between PitchTrack.modify_note and PitchTrack.parse
. Do "Make Derive.parse_expr invertible" first.
- rename Pitch.Note to Pitch.Symbolic?
. Then the problem is that 'sym' or 'symbolic' variable names are generic
without the pitch qualification.
. Maybe psym or symp? Or just call it pitch.
. What about swaram? Swar?
- copy paste that understands track types
green-mold, if I replace "i " "" for "inst=b", derive takes forever
. Is it possible to get progress so I can see what it's doing?
. It was because b1 etc. were block names, so it substituted those and got
too many events.
. In this case, I wonder if I can show progress, or cancel. Play will get
stuck on derive, but be cancelled by the timeout.
- If I can show a progress bar with number of events / time derived, it
would give the clue that something is wrong.
. Also, should I abort if derive takes too long?
/ is there a Factor to glue together two blocks?
. How about split a block? Yes, Factor.split_time. But no join.
. It would have to match up tracks, which seems complicated.
. I don't really need it though.
- bug: logview: error parsing "": can't decode json
. It should say where in the file this happens.
- consider switching TrackTime to rational
. Reason why is if I multiply events by say (2/3) I easily wind up with
start+dur just barely not lining up to the start of the next event.
And then since Events are rounded but selections aren't, I get confusing
behaviour when edit wants to make a new event that nonetheless
overwrites an existing one.
. If I had a TrackTime / ScoreTime distinction I could do a conversion
there, but why not make all of ScoreTime rational? I don't know any
cases where they're truly at complicated times.
- sorted Derive.Stream:
. Implement the Sorted flag in Derive.Stream
. I could have calls that can move note starts register by flipping a flag
in Collect, then the track will set Unsorted.
. Or just sort it... The Sorted flag is only worth it if I can elide sorts
because intermediate postprocs don't care. I might not have that many
to matter, and List.sort should be efficient anyway on almost-sorted
inputs.
. Either that or check for order on each call? But at that point
shouldn't I just sort it? Maybe the most reasonable is to just sort
each track always.
. Then MergeList by track?
- have kbd entry on a control track let numbers through
. I do a fallthrough, does it get stopped?
. NoteEntry.cmds_with_input catches the keydown msg, and replaces it
with an Input.
. I would have to say if it ended with Continue, then try again with
the original key. Would that have confusing side-effects? I would
prefer if I could have ControlTrack.edit_normalized explicitly signal
to retry with the Msg.
. I think commands would fall through in addition to playing a note,
e.g. jk will do a thru and still move the cursor, which I don't want.
. I don't want this that much, so leave it be for now.
- can I tweak individual scale degrees?
. E.g. ma + 0.25nn, ri + 0.2nn.
. Maybe just an env var for scale degree would do it.
- convert save/bali/legong/semara-dana to im
. sampler-im versions of gong, jegog, calung
. notation and damping inference for gender rambat
. It would be nice to have the high level part, then double click to open
the derived parts, and possibly edit.
- do I ever get negative Score.Events?
. It would simplify to rule that out. E.g. Score.events_overlap
. Score.event_min implies I do, but only Derive.Note uses it so maybe no?
. I think the main opportunity to get them is if default note makes them.
. It does! Negative notes make negative Score.Events... then what?
. Midi perform doesn't understand them, they wind up with minimal
durations.
. I guess I rely on postproc to flip them around, but which one?
. Postproc.make_cancel seems like it should do it, but I don't see
anything about negative duration, just weak and strong cancellation.
+ rhythmic interpolation
. Match notes in two derivers, then interpolate rhythms:
'%pos=.5 | r-interpolate b1 b2'
. What to do if the notes don't match? If it's pitches I could also
interpolate the pitches.
. The use is something like chatusram -> tisram transition.
. I already have an interpolate call, but it goes by score event.
. Uses:
1. transition from rhythm to another, e.g. chatusram -> tisram
2. modified pattern as an effect, e.g. p6 evened out halfway to p5
3. consistent warp on all notes, ala microrhythm
. For 1 and 2 I think both arg form 'interp b1 b2' and parent form would
be useful.
. For 3, I would want to apply to a whole track, and loop the model
rhythm. I would also want it to work even when the source is missing
a note. So this is more of a warp, where I map each timestep of the
source to a different place, then apply that as a continuous warp.
. This is a way to make a local warp map, then apply that to a child
deriver.
. Derive the model in linear time, then how to infer its time step?
. Can I do this as a interpolation between two derivers? Then use 'tile'
or 'loop'.
. In fact, can I use the existing interpolate for this?
. Here's how it could look in tscore:
top = [
e-interpolate/6
// "loop | b1"/6
// "loop | b2"/6
]
b1 = [ k t k n o ]
b2 = [ k t _ k n o ]
=>
top = [
e-interpolate/6 // loop[k t k n o]/6 // loop[k t _ k n o]/6
]
. Can I provide (loop | b1) as an arg?
e-interpolate "(loop | b1) "(loop | b2)
. Then tscore could be:
top = [
"e-interpolate loop[k t k n o] loop[k t _ k n o]"/6
]
but it would need to look inside ""s for [] interpolation.
. The problem is that deriver is not first class, so calls with multiple
deriver arguments actually take strings. This gets back to the very
old idea of unifying 'a | b | c' with 'a (b (c))'.
. The problem I am solving is that it's redundant to make a whole track
and have to set the event duration to be the same, so subtracks are too
flexible.
. "(loop | b) works because with "() deriver does in fact become first
class? Well, only sort of... Sig.eval_quoted returns a Val, so it can't
be a deriver, but e-interpolate uses Eval.eval_quoted, which is only
derivers.
. It seems I could still put Deriver in Typecheck, since it doesn't have
to go through Val.
swam: strings
- notes get stuck on
. Midi.AllNotesOff kills it, but space doesn't emit that. Why not?
. If I always emit AllNotesOff, then im stops as soon as it starts, why?
. AllNotesOff shows up as Control 1 123.
- simulate hand position and shifts
. This won't work well because swam also wants to do that, and even with
the hand position setting I think I can't get it to use the string
I want.
techniques:
- trompong tumpuk, double strokes, noltol
- Experiment with increased or decreased pressure or position for damped
stroke.
- staccato with short stroke and bow-lift=t
+spiccato
- randomization in pitch, pressure, bow pos, open string tuning
- trill at 1.5nn?
- polyphony
. I'll need at least mono, double, and double-hold, and to set the
strings. It should be possible to infer from the score, but try it
manually first and see how it goes.
- What to do with dummy-only instruments like kontakt/wayang-pemade?
. They're confusing because kontakt/wayang-pemade is not actually
a playable instrument.
. Actually, it is, it's the version without the scale, so it would work
for any tuning.
- track integration should possibly be indexed by TrackId, so I don't have
the possibility of overlapping ones.
. I also want to be able to match on TrackId for the manual integration
in TScore. I should refactor on the integration stuff to account for
all the variants in a less ad-hoc way.
. Wait actually tscore shouldn't use TrackId.
- MemoryLeak latency:
. getting above the limit of 0.05
. I don't know what the historical values have been, maybe I should be
saving those.
? It's the first cmd only, what is it doing that's more work?
. Try with 8.0.2. Yes, still happens there.
- prettyprint:
. Check out pretty-show or pretty-simple or ghci-pretty
. https://www.reddit.com/r/haskell/comments/8ilw75/there_are_too_many_prettyprinting_libraries/
. http://teh.id.au/posts/2017/02/13/interactive-print/index.html
. https://www.reddit.com/r/haskell/comments/76fvsq/replacing_ghcis_prettyprinter/
. https://github.com/cdepillabout/pretty-simple
. Maybe I can use this to get rid of the haskell-src dep.
. Also this is maybe an up to date variant:
https://hackage.haskell.org/package/prettyprinter
. pretty-simple takes up too much vertical space, and I think I don't want
the colors.
pretty-show:
. pretty-show still takes more space than HughsPJ Pretty.pprint, but
seems ok? It's like Util.Format, but doesn't pack horizontally.
. Actually pretty-show dispatches to HughsPJ under the surface.
But it works by parsing and reifying to a Value type. It also has
a PrettyVal which is a GHC.Generic implementation to convert to Value.
. It also renders to HTML, from the Value.
It's kind of interesting, but I don't like it. Takes a lot of space,
has confusing 2d layout. Can collapse though, but you have to click
on it. I'd want to collapse everything at a certain level, like zm.
. It uses haskell-lexer instead of haskell-src, so I can remove that
dep, which seems old.
track down 8.4.1 performance regression:
. performance regression notes: http://ghc.haskell.org/trac/ghc/ticket/14964
- try with 8.0.2
- try without RTS flags
. Also it seems to really only be OS X, it's only sligtly worse on linux,
or even slightly better for cerucuk-punyah.
. It correlates with the productivity decrease, so maybe GC related.
- maybe I could help with compile time regressions by exporting shake's
report.html and noticing when files change time.
compile time mehitabel:
. 8.0.2:
RunTests 549.10s user 118.45s system 343% cpu 3:14.53 total
RunTests 548.71s user 117.10s system 347% cpu 3:11.78 total
debug/seq 284.47s user 55.95s system 345% cpu 1:38.58 total
debug/seq 283.33s user 55.27s system 343% cpu 1:38.53 total
opt/seq 732.63s user 70.86s system 338% cpu 3:57.30 total
opt/seq 735.21s user 71.48s system 327% cpu 4:06.31 total
. 8.4.2:
RunTests 450.92s user 109.63s system 343% cpu 2:43.13 total
RunTests 445.48s user 107.99s system 341% cpu 2:42.19 total
debug/seq 220.92s user 50.21s system 337% cpu 1:20.32 total
debug/seq 218.39s user 49.20s system 345% cpu 1:17.47 total
opt/seq 785.12s user 65.42s system 327% cpu 4:19.84 total
opt/seq 765.52s user 64.01s system 321% cpu 4:18.29 total
compile time tammananny:
. 8.0.2:
. RunTests 781.31s user 58.21s system 363% cpu 3:50.70 total
. debug/seq 429.44s user 31.34s system 362% cpu 2:07.03 total
. opt/seq 1277.20s user 45.85s system 358% cpu 6:08.68 total
. 8.4.1:
. RunTests 613.11s user 49.84s system 357% cpu 3:05.52 total
. debug/seq 329.67s user 23.86s system 352% cpu 1:40.38 total
. opt/seq 1339.73s user 39.87s system 341% cpu 6:43.50 total
- extend gliss so I can gliss on harmonics
. Why does eval_quoted give opposite pitches?
note = Eval.eval_one_call True $ Expr.call0 Symbols.null_note
- Since gliss uses a 'n' parameter for note transform, I should use it
consistently, e.g. in grace and roll.
. What would I actually need to have a useful TrackTime?
. TrackTimes come from Events, and they are absolute measures. Addition
and subtraction yields ScoreTimes:
(+) :: RelativeTime -> TrackTime -> ScoreTime
. Ui.Event has to be polymorphic on the time type, because I synthesize
fake Ui.Events or translate real ones (do I really do that? where?).
. An alternative is to put all calls in normalized time, and then have
some organized way to get TrackTimes for when I need them. Or rather,
make the things that require them not accept ScoreTime. I'd need to
go review why I made calls non-normalized in the first place, and see
how much those reasons still hold.
cleanup from linear:
- rename RealTime.seconds to from_seconds etc.
. I'm kind of reluctant because RealTime.seconds reads nicely and
there are a lot of places to change and they all get longer.
- Deriver.Lib.with_control_mods
- Look for TODO(polymorphic-signals) for places where a signal typeclass
would help.
- what if I added a 'default-interpolator' argument so Control.c_set and
Pitch.c_set could make curves by default?
. '*PITCH = xyz' does this for pitch calls, but this is a special
behaviour for Derive.val_to_pitch, and wouldn't work for controls.
- pnovla @pno1 32.25t mordent broken, probably too much note overlap
- string_idiom should ignore notes that already have a string.
- Let synth defs log warnings
. So e.g. MidiInst.compile_library can report shadows.
. I should be able to incorporate Faust.PatchDb.warnings too.
- Generic Show and Pretty instances for ScopesT and Scope.
- Maybe 'set' should be the default merger, not mul. It seems less
confusing.
. I could still have 'dyn' default to mul, if that's not confusing too.
- decide if the ( call is called slur or legato, not half and half.
. I already have something called slur in Rearticulate, so let's go back
to legato. Slur is just how it happens to be realized in lilypond.
- Use EnvKey.string for string selection in vsl, not attributes.
. It would be nice to be able to select by name instead of NN, but the
calls like NNs. Maybe val calls that emit the right NNs.
. I'm using pitches with e.g. '60nn' for names. g, d, a e are still
a better UI though.
- if 'roll' were a transformer I could do 'roll | some-note'. This is the
same problem as extending 'grace' to be able to put stuff on the main
note.
- Pitch bend doesn't work right on a MIDI instrument with patch scale.
. Likely because the pitch gamut is not linear, but pitch bend is.
. I would need to warp the pitch bend by the patch scale... but don't I do
that?
- It seems too complicated to set up patch scales, how can I make that
easier?
- Highlight for block calls which are 1:1, or not 1:1.
. Use event width for this? But this is a different mechanism from
highlights, which uses selections.
. Or use event color. Effectively the highlight does that though.
. How to get the highlight? Other highlights are postprocs that attach
the highlight, but I think I can get the block call itself to do that.
. But highlights go on Score.Events, and this is a UI event. I could
extend LEvent.Log with a general Metadata kind of thing, or I could
also attach a highlight to the first event from the block.
. The latter means highlight needs to support a time range, and of course
it won't work if the block produces 0 events. But in that case it
doesn't matter if it's 1:1 or not.
. The problem with LEvent.Metadata is that I don't want to rewrite all the
LEvent stuff to also deal with logs, but I don't want to pay another
indirection. But if I put UNPACK it should solve that:
data LEvent = Event a | Log {-# UNPACK #-} Log
data Log = Metadata X | Msg Log.Msg
Does that work?
. What other things could I put in Metadata?
. Highlights for one, I think a ScoreTime range is more appropriate than
taking RealTime from the events, since the latter is wrong if the note
extent doesn't match the score extent.
. What about integrate? I currently have a special spot in
Derive.Results, but I could also emit it as a meta-event.
. But for that matter, why not put highlights in Derive.Result? It
seems more elegant to favor the explicit Stream return value over
implicit Collect results, but the logical conclusion of that is to get
rid of Collect entirely. I think I don't want to do that, because
I take advantage of monoid merge to discard data. But on the other
hand, if the output stream is lazy, then it's just the same to do the
same collection while iterating over the result. This would make it
explicit that to get collected data I have to iterate over the events,
instead of how implicitly touching some fields actually implies
evaluating the score. Also I could evaluate Collect only up to
a certain point, though I don't think I ever want to do that. And
then it separates result collection from the deriver, so maybe more
modular. Could it be more efficient? I might spend a lot of time
combining memptys. and a final fold might get rid of that. Presumably
I'd use an ADT for the metadata instead of a record. On the other
hand, it's more cons cells for the stream, which maybe means more junk
to skip when sorting and merging. Maybe I could mitigate that by
collecting Metadata together into short vectors, which can be skipped
as a unit. It's only a win if they tend to clump together.
. What would the metadata be?
. Also I should profile to make sure about Collect usage and of course
to see a difference if I switch.
PLAN
- profile current status, look for Collect allocation
- enumerate the things that go in Metadata
- verify UNPACK can flatten Log event
- estimate work to switch
- sketch out where and how the collect fold would happen at the end
- ensure Streams are lazy... I think transforms might actually destroy
laziness. But would getting rid of Collect be able to restore it?
I'd have to do something about exceptions, maybe put it in as
a Metadata too. If I can make the whole derivation fully streaming
then this might be a big win.
tabuh gari:
- octaves notation for trompong
- octaves for gender rambat
- I get the wrong pitch on too-high trompong notes
. It shouldn't try to emit pitches above its range.
. I should extend the samples up a couple pitches anyway.
- how can I write angsels? E.g. same as template, but with bits replaced.
Score derive?
- It's inconvenient to have two roots, because play-from-root stops
working right as soon as I change it. But it does have a definite
single caller, so shouldn't it be able to figure out a root all the
same?
- It's really tempting to put a '>inst = %dyn=.5', but that just forces it
to always have that dyn. How can I set a per-instrument default dynamic
which I can still override?
. First define exactly what I want.
. I want to set a baseline dyn per instrument, but I want to be able to
override it.
. It should be as if I set a global %dyn, so specific ones can override
it, but only for that instrument. So each 'dyn' affects all dyn-*
signals, and then each instrument can pick out its dyn-me.
. And of course this should generalize for all controls... well, I don't
have a use for non-dyn, so I don't really need to generalize.
. If I always set dyn absolute, I could just set when the instrument comes
into scope.
. Wait, why does '>inst=...' not work? Wouldn't it set at the note track,
and then the child dyn track would be able to override?