Copperbox revision 389.
Added Consts.hsc which all the incorporates all the enums in the OpenVG standard.
Wednesday, December 31, 2008
Sunday, December 28, 2008
OpenVG and ZParse
Copperbox revision 388.
I'm taking a break for HNotate for a bit. I've worked out how to simplify the document building code (principally the TemplateDatatypes module), but that means redoing the parsers again so they handle island parsing better (and don't build the parse tree with continuations). I got rather frustrated with Parsec's lexer handling - not that it isn't capable just that I was probably trying to solve my problem in the wrong way - so I started another parser combinator library ZParse. Applicative and Alternative now encompass much of the work need for basic parsing, so writing the usual combinators was easy, but handling tokens is tricky so maybe I'll go back to Parsec.
For a change I've started on a Haskell binding to OpenVG - the vector graphics API. I've spent the whole day defining constants and I've still got half of the marshallers to do, never mind unmarshalling. As this is a baby step compared to the involved stuff of calling functions through the FFI, it looks like the binding will be a much bigger job than I thought.
I'm taking a break for HNotate for a bit. I've worked out how to simplify the document building code (principally the TemplateDatatypes module), but that means redoing the parsers again so they handle island parsing better (and don't build the parse tree with continuations). I got rather frustrated with Parsec's lexer handling - not that it isn't capable just that I was probably trying to solve my problem in the wrong way - so I started another parser combinator library ZParse. Applicative and Alternative now encompass much of the work need for basic parsing, so writing the usual combinators was easy, but handling tokens is tricky so maybe I'll go back to Parsec.
For a change I've started on a Haskell binding to OpenVG - the vector graphics API. I've spent the whole day defining constants and I've still got half of the marshallers to do, never mind unmarshalling. As this is a baby step compared to the involved stuff of calling functions through the FFI, it looks like the binding will be a much bigger job than I thought.
Tuesday, December 23, 2008
HNotate, Bala and TabApp
Copperbox revision 385.
HNotate - I've changed the debug interface to have just DebugOn or DebugOff rather than levels. The early versions of the BuildNoteList module were so complicated that I needed a large amount of logging just to check they were working. Now with the Fits module and segmenting functions, I'm much more confident in BuildNoteList so no longer need so to deal with so much logging.
Changes have been cascaded to Bala and TabApp as HNotate's interface has changed.
HNotate - I've changed the debug interface to have just DebugOn or DebugOff rather than levels. The early versions of the BuildNoteList module were so complicated that I needed a large amount of logging just to check they were working. Now with the Fits module and segmenting functions, I'm much more confident in BuildNoteList so no longer need so to deal with so much logging.
Changes have been cascaded to Bala and TabApp as HNotate's interface has changed.
Monday, December 22, 2008
HNotate
Copperbox revision 384.
I've associated AnnoEval with a named element within a system, rather than a single global AnnoEval. This means that we can have different annotation schemes within the same output document. The StringNumberScale example takes advantage of this to output both staff and tab notation.
I've associated AnnoEval with a named element within a system, rather than a single global AnnoEval. This means that we can have different annotation schemes within the same output document. The StringNumberScale example takes advantage of this to output both staff and tab notation.
HNotate
Copperbox revision 383.
Added a worked example of annotation - string numbering for LilyPond output. Also I've implemented a proper defaultMeterPattern function, that calculates a meter pattern for a given time signature. Previously this function was a stub.
Added a worked example of annotation - string numbering for LilyPond output. Also I've implemented a proper defaultMeterPattern function, that calculates a meter pattern for a given time signature. Previously this function was a stub.
HNotate
Copperbox revision 382.
HNotate has a new annotation mechanism. Annotations were previously just transfomers applied the pretty printed elements and atoms (i.e. they were functions of type ODoc -> ODoc). This had a serious problem - when adding multiple annotations you had to be very careful about the order of application of the transformer functions.
Now annotations are fully typed values (albeit wrapped up into a generic list with Data.Typeable). To print them, the user must supply a AnnoEval structure which contains three functions for applying annotations at three different levels in the syntax tree.
With revision 382 the mechanism to do this is in place but there aren't any example annotations and the interface to run HNotate in OutputMain hasn't been changed to be parameteric on AnnoEval.
HNotate has a new annotation mechanism. Annotations were previously just transfomers applied the pretty printed elements and atoms (i.e. they were functions of type ODoc -> ODoc). This had a serious problem - when adding multiple annotations you had to be very careful about the order of application of the transformer functions.
Now annotations are fully typed values (albeit wrapped up into a generic list with Data.Typeable). To print them, the user must supply a AnnoEval structure which contains three functions for applying annotations at three different levels in the syntax tree.
With revision 382 the mechanism to do this is in place but there aren't any example annotations and the interface to run HNotate in OutputMain hasn't been changed to be parameteric on AnnoEval.
Sunday, December 21, 2008
HNotate, Bala and ZMidi
Copperbox revision 381.
I've had not internet connection since Wednesday so this is a bigger update than usual.
HNotate - I've added a beam grouping level in the abstract syntax tree. Adding beam grouping into the AST has made the beam handling code better - previously beaming was essentially lexical - when the outputting functions saw beam_start or beam_end in the sequence of notes, rests and mark, the functions changed their behaviour accordingly (they were stateful). Now that beam grouping is in the AST the outputting functions are simpler as they can use normal top-down traversal strategies.
Bala and ZMidi - I've added -Wall annotations to the files.
I've had not internet connection since Wednesday so this is a bigger update than usual.
HNotate - I've added a beam grouping level in the abstract syntax tree. Adding beam grouping into the AST has made the beam handling code better - previously beaming was essentially lexical - when the outputting functions saw beam_start or beam_end in the sequence of notes, rests and mark, the functions changed their behaviour accordingly (they were stateful). Now that beam grouping is in the AST the outputting functions are simpler as they can use normal top-down traversal strategies.
Bala and ZMidi - I've added -Wall annotations to the files.
Wednesday, December 17, 2008
GreyFold
Copperbox revision 380.
I've added another module to GreyFold - SynthethicFolds. These are the folds that can be defined in terms of foldl or foldr - countfold, statefold, double accumulator fold - all they actually do is partition the summary value in some way, so they can be defined on Foldable types.
Also, I've added mergesort to the Data.Sequence compatibility functions.
I've added another module to GreyFold - SynthethicFolds. These are the folds that can be defined in terms of foldl or foldr - countfold, statefold, double accumulator fold - all they actually do is partition the summary value in some way, so they can be defined on Foldable types.
Also, I've added mergesort to the Data.Sequence compatibility functions.
Tuesday, December 16, 2008
GreyFold
Copperbox revision 379.
I've added a new library GreyFold which collects together all the folds, recursion schemes and utility functions for Data.Sequence from HNotate. I called it GreyFold because a lot of the functions seemed to be in the grey area between utility and curios.
(Note to me - I still need to add the mergesort for Data.Sequence from ZMidi).
I've added a new library GreyFold which collects together all the folds, recursion schemes and utility functions for Data.Sequence from HNotate. I called it GreyFold because a lot of the functions seemed to be in the grey area between utility and curios.
(Note to me - I still need to add the mergesort for Data.Sequence from ZMidi).
Sunday, December 14, 2008
HNotate
Copperbox revision 378.
Midi output is dropped (again) from HNotate. As noted in my last post, I think trying to do Midi inside HNotate has been lead to some dubious generalizations of code that was satisfactory for Abc and LilyPond. Also, I've tidied up OutputMain quite a bit as it is now has to do less do.
Midi output is dropped (again) from HNotate. As noted in my last post, I think trying to do Midi inside HNotate has been lead to some dubious generalizations of code that was satisfactory for Abc and LilyPond. Also, I've tidied up OutputMain quite a bit as it is now has to do less do.
HNotate
Copperbox revision 377.
Work to add templates for Midi output, so Midi would work like LilyPond or Abc...
However, its probably Midi's swan song as far as HNotate goes. I think I can say that having HNotate work with both Abc and LilyPond has improved HNotate. While there is still plenty of convoluted code in HNotate, targeting both Abc and LilyPond has made me look for better solutions than I think I would have found just targeting LilyPond. But, I believe that adding Midi support has made HNotate worse - to support Midi it feels like I've dubiously generalized some parts of HNotate that supported Abc and HNotate well. So after this revision I think Midi's time is up.
I'd like to add a notelist backend at some point that can easily be parsed and turned into Midi (something like one of the Humdrum representations), but a representation that is still textual so better matches what HNotate is good at.
Work to add templates for Midi output, so Midi would work like LilyPond or Abc...
However, its probably Midi's swan song as far as HNotate goes. I think I can say that having HNotate work with both Abc and LilyPond has improved HNotate. While there is still plenty of convoluted code in HNotate, targeting both Abc and LilyPond has made me look for better solutions than I think I would have found just targeting LilyPond. But, I believe that adding Midi support has made HNotate worse - to support Midi it feels like I've dubiously generalized some parts of HNotate that supported Abc and HNotate well. So after this revision I think Midi's time is up.
I'd like to add a notelist backend at some point that can easily be parsed and turned into Midi (something like one of the Humdrum representations), but a representation that is still textual so better matches what HNotate is good at.
Saturday, December 13, 2008
HNotate and Bala
Copperbox revision 376.
A lot of changes to the hand-built document parts of HNotate. I'm trying to make them use more of the machinery that the documents parsed with island parses use.
The doc combinators - in DocLilyPond and DocAbc - are now quite a bit simpler and the operation of plugging documents is better defined. There is still quite a lot of work to simplify OutputMain though, and I've disabled HNotate's Midi output for the time being.
Changes have been cascaded to Bala so that the examples will compile.
A lot of changes to the hand-built document parts of HNotate. I'm trying to make them use more of the machinery that the documents parsed with island parses use.
The doc combinators - in DocLilyPond and DocAbc - are now quite a bit simpler and the operation of plugging documents is better defined. There is still quite a lot of work to simplify OutputMain though, and I've disabled HNotate's Midi output for the time being.
Changes have been cascaded to Bala so that the examples will compile.
Thursday, December 11, 2008
HNotate
Copperbox revision 375.
I've changed the update functions in the RhythmicValue and PitchValue type classes so they are of the form b -> a -> a rather than a -> b -> a.
I ended up changing the function name from modifyValue to updateValue as well. Changes have been cascaded to Bala.
I've changed the update functions in the RhythmicValue and PitchValue type classes so they are of the form b -> a -> a rather than a -> b -> a.
I ended up changing the function name from modifyValue to updateValue as well. Changes have been cascaded to Bala.
Wednesday, December 10, 2008
Sunday, December 7, 2008
HNotate, Bala and TabApp
Copperbox revision 372.
Some rework on TabApp and minor changes to Bala and HNotate.
I thought I'd look at getting TabApp to work, as it will be something to stretch HNotate with. It has already show a limitation in HNotate - individual notes within chords should have annotations so they can have string-numbers (the same goes for tuplets).
I've split TabApp into two parts, one LpTab is a simple tab to LilyPond converter, the other is new code but still called TabApp. There is a rationale for having two versions. LpTab has a very strict parser, it will abort on a parse error. Guitar tab files only have a loose specification as they're intended for human reading - with LpTab I'm trying to find out a good subset that corresponds to LilyPond's tab capabilities. For TabApp I want the parser to be a bit looser, it should be able to at least run on tabs from the wild whether or not it can turn them into good output.
Some rework on TabApp and minor changes to Bala and HNotate.
I thought I'd look at getting TabApp to work, as it will be something to stretch HNotate with. It has already show a limitation in HNotate - individual notes within chords should have annotations so they can have string-numbers (the same goes for tuplets).
I've split TabApp into two parts, one LpTab is a simple tab to LilyPond converter, the other is new code but still called TabApp. There is a rationale for having two versions. LpTab has a very strict parser, it will abort on a parse error. Guitar tab files only have a loose specification as they're intended for human reading - with LpTab I'm trying to find out a good subset that corresponds to LilyPond's tab capabilities. For TabApp I want the parser to be a bit looser, it should be able to at least run on tabs from the wild whether or not it can turn them into good output.
Saturday, December 6, 2008
HNotate
Copperbox revision 371.
I've simplified the code for beam grouping - rather than an unfold with various case distinctions, it is much shorter as a groupBy: all notes and chords under a quarter get groupedBy within their metrical cell. Then a simple fold joins the metrical cells back together to reform the bar.
I've simplified the code for beam grouping - rather than an unfold with various case distinctions, it is much shorter as a groupBy: all notes and chords under a quarter get groupedBy within their metrical cell. Then a simple fold joins the metrical cells back together to reform the bar.
Friday, December 5, 2008
HNotate
Copperbox revision 370.
I've reimplemented beam segmentation with a function regiment that's based on Fits.
Whereas the the function segment breaks elements to pack them exactly into the division, regiment doesn't break elements instead they go into the next segment but the 'remaining width' is correctly tracked. This is exactly what beam grouping needs.
I've reimplemented beam segmentation with a function regiment that's based on Fits.
Whereas the the function segment breaks elements to pack them exactly into the division, regiment doesn't break elements instead they go into the next segment but the 'remaining width' is correctly tracked. This is exactly what beam grouping needs.
HNotate and Bala
Copperbox revision 369.
I've tidied up the Fits type class and made it handle hyphenation better. Previously any split element of type Atom would be hyphenated with a tie. This meant rests and spacer rests were being tied as well as notes, also chords weren't tied as their type is Grouping (this data type still needs a better name) not Atom. Looking at Conal Elliott's nice Segment type class I realized I could get rid of the Fit data type within the Fits module and just use the Fits type class. Actually I could have used Conal's class, but for HNotate its convenient to have the hyphenate function in the same place as the split function.
Bala has also been updated to take the changes to Fits.
I've tidied up the Fits type class and made it handle hyphenation better. Previously any split element of type Atom would be hyphenated with a tie. This meant rests and spacer rests were being tied as well as notes, also chords weren't tied as their type is Grouping (this data type still needs a better name) not Atom. Looking at Conal Elliott's nice Segment type class I realized I could get rid of the Fit data type within the Fits module and just use the Fits type class. Actually I could have used Conal's class, but for HNotate its convenient to have the hyphenate function in the same place as the split function.
Bala has also been updated to take the changes to Fits.
Thursday, December 4, 2008
HNotate and Bala
Copperbox revision 367.
In HNotate, I've sorted out the typeclass PitchContent and put all the functions on Data.Sequence in one module (stranspose, sfilter, recursion schemes...). This has cascaded quite a few changes to Bala, which has been updated and the demos run again.
In HNotate, I've sorted out the typeclass PitchContent and put all the functions on Data.Sequence in one module (stranspose, sfilter, recursion schemes...). This has cascaded quite a few changes to Bala, which has been updated and the demos run again.
HNotate
Copperbox revision 366.
I've updated the Haskore interface to HNotate so that it compiles at least. As Haskore takes quite a different view of music to HNotate (i.e. the information it carries around in its data structures is quite different) I'm still not sure if HNotate will ever be able to generate reasonable scores from Haskore.
I've updated the Haskore interface to HNotate so that it compiles at least. As Haskore takes quite a different view of music to HNotate (i.e. the information it carries around in its data structures is quite different) I'm still not sure if HNotate will ever be able to generate reasonable scores from Haskore.
HNotate
Copperbox revision 365.
I've redone the BuildNoteList module. It's now much simpler - there aren't the special datatypes that the previous version had to track position. The only complicated bit is a recursive step inside the function defork that uses to accumulators rather than one.
I've redone the BuildNoteList module. It's now much simpler - there aren't the special datatypes that the previous version had to track position. The only complicated bit is a recursive step inside the function defork that uses to accumulators rather than one.
Tuesday, December 2, 2008
HNotate
Copperbox revision 364.
I've implemented the LilyPond relative traversal* as a focused shape-contents traversal. The code size is about the same as the WrappedMonad version of this traversal. The code seems an improvement (in terms of clarity, readability, ...). However this may solely be 'second attempt advantage' - if I had done another WrappedMonad version that would no doubt be an improvement. So for the time being both versions are in the code base.
Traversals are still HNotate's weak point, as the last post and commit fixing a tuplet bug highlighted. A large part of this is due to the main containers / data structures not being directly functorial - where list [a] is a one layer container over its element type, HNotate often has two layer containers Seq (Seq a) and also carries around extra information (e.g. bar numbers) that can't be accessed functorially (i.e. bar numbers are invisible to fmap, foldable or traverse).
* The traversal changes both pitch and duration to be relative to the preceding note
I've implemented the LilyPond relative traversal* as a focused shape-contents traversal. The code size is about the same as the WrappedMonad version of this traversal. The code seems an improvement (in terms of clarity, readability, ...). However this may solely be 'second attempt advantage' - if I had done another WrappedMonad version that would no doubt be an improvement. So for the time being both versions are in the code base.
Traversals are still HNotate's weak point, as the last post and commit fixing a tuplet bug highlighted. A large part of this is due to the main containers / data structures not being directly functorial - where list [a] is a one layer container over its element type, HNotate often has two layer containers Seq (Seq a) and also carries around extra information (e.g. bar numbers) that can't be accessed functorially (i.e. bar numbers are invisible to fmap, foldable or traverse).
* The traversal changes both pitch and duration to be relative to the preceding note
HNotate
Copperbox revision 363.
I've fixed a bug where tuplets were getting assigned zero_duration if they had the same total duration as the preceding note. LilyPond uses a scheme where if a note has the same duration as the last one then the duration can be omitted - HNotate can normally use this, but because triplets have synthesized durations it was causing problems. Now tuplets always print the unit duration with the first member tuplet.
I've fixed a bug where tuplets were getting assigned zero_duration if they had the same total duration as the preceding note. LilyPond uses a scheme where if a note has the same duration as the last one then the duration can be omitted - HNotate can normally use this, but because triplets have synthesized durations it was causing problems. Now tuplets always print the unit duration with the first member tuplet.
Monday, December 1, 2008
Sunday, November 30, 2008
Saturday, November 29, 2008
Friday, November 28, 2008
Bala
Copperbox revision 358.
I've added a new module to Bala for handling guitar notation. More than once, I've dabbled at trying to get something useful for guitar notation, but never got very far. Hopefully as HNotate and Bala have progressed pretty well in the last couple of months, the new module has better prospects.
I've added a new module to Bala for handling guitar notation. More than once, I've dabbled at trying to get something useful for guitar notation, but never got very far. Hopefully as HNotate and Bala have progressed pretty well in the last couple of months, the new module has better prospects.
Thursday, November 27, 2008
HNotate and Bala
Copperbox revision 355.
A substantial number of changes to the NoteList datatypes in HNotate and the modules that depend on them. The NoteList data types have generally been made more uniform, and I've got rid of the (|#) combinator due to a better way of handling annotations.
Pleasingly, Bala can now output LilyPond percussion scores.
A substantial number of changes to the NoteList datatypes in HNotate and the modules that depend on them. The NoteList data types have generally been made more uniform, and I've got rid of the (|#) combinator due to a better way of handling annotations.
Pleasingly, Bala can now output LilyPond percussion scores.
Wednesday, November 26, 2008
Bala, HNotate and ZMidi
Copperbox revision 354.
Work towards printing drum rhythms.
The work here gets Bala closer to being able to output drum rhythms in LilyPond, but unfortunately I've reached a sticking point. I need to be able to represent 'drum chords' with HNotate's Tile datatype (specifically the Mark constructor), however I can't see how to do this at the moment, as marks have always been singletons and not collections. It looks like I'll have to rethink Tile.
Work towards printing drum rhythms.
The work here gets Bala closer to being able to output drum rhythms in LilyPond, but unfortunately I've reached a sticking point. I need to be able to represent 'drum chords' with HNotate's Tile datatype (specifically the Mark constructor), however I can't see how to do this at the moment, as marks have always been singletons and not collections. It looks like I'll have to rethink Tile.
Bala
Copperbox revision 353.
Work towards generating LilyPond output for rhythms. This turns out to be trickier than I'd imagined, even after had-editing the generated file, the LilyPond output is poor.
More positively, I've improved the Midi output. A section now outputs a single tracks, so there is less chance of interference (different Midi signals trying to use the same channel).
Work towards generating LilyPond output for rhythms. This turns out to be trickier than I'd imagined, even after had-editing the generated file, the LilyPond output is poor.
More positively, I've improved the Midi output. A section now outputs a single tracks, so there is less chance of interference (different Midi signals trying to use the same channel).
Tuesday, November 25, 2008
Bala and ZMidi
Copperbox revision 352.
I've made quite a lot of changes to get SambaBaiao to work better. Clave patterns now build - MotifF Event - rather than MotifF Clave, which makes things more uniform. The Midi output has been improved to handle percussion output.
Also Pitch in HNotate now derives Data and Typeable in case I feel the need to scrap some bolierplate later on.
I've made quite a lot of changes to get SambaBaiao to work better. Clave patterns now build - MotifF Event - rather than MotifF Clave, which makes things more uniform. The Midi output has been improved to handle percussion output.
Also Pitch in HNotate now derives Data and Typeable in case I feel the need to scrap some bolierplate later on.
Monday, November 24, 2008
Bala
Copperbox revision 351.
I've reduced layering in type Event - Note Rest and Spacer now have their own construtors, previously they were grouped in the DEvt - durational event - type (Event itself is a new name previously it was called Elt). Mark is still a compound type within event, it is likely I will add more marks than Tie and also marks generally aren't interpreted - at least until they are passed to HNotate - so there is little need for nested pattern matching on them.
I've reduced layering in type Event - Note Rest and Spacer now have their own construtors, previously they were grouped in the DEvt - durational event - type (Event itself is a new name previously it was called Elt). Mark is still a compound type within event, it is likely I will add more marks than Tie and also marks generally aren't interpreted - at least until they are passed to HNotate - so there is little need for nested pattern matching on them.
Bala
Copperbox revision 350.
The latest set of changes for Bala - which are notable for commenting out most of Saturday's work.
I haven't really worked out the composition mechanisms for Bala. Obviously I'd like to build bigger pieces from smaller ones - sections from phrases, phrases from motifs, but I'm missing something to do this. The example SambaBaiao is illustrative - ideally I'd like the tap pattern to play a different pitch or even a chord to the foot pattern that it overlays. Does this mean I should transform both patterns before I overlay them, or preferably, can I transform a complete structure once it is built?
At the moment I really just have fmap / functor transformation so every element within a container is similarly transformed - what I would need is traversal control to change say just the top motif in an overlay (the focused shape-contents traversals have capabilities above fmap but I need something else here).
The latest set of changes for Bala - which are notable for commenting out most of Saturday's work.
I haven't really worked out the composition mechanisms for Bala. Obviously I'd like to build bigger pieces from smaller ones - sections from phrases, phrases from motifs, but I'm missing something to do this. The example SambaBaiao is illustrative - ideally I'd like the tap pattern to play a different pitch or even a chord to the foot pattern that it overlays. Does this mean I should transform both patterns before I overlay them, or preferably, can I transform a complete structure once it is built?
At the moment I really just have fmap / functor transformation so every element within a container is similarly transformed - what I would need is traversal control to change say just the top motif in an overlay (the focused shape-contents traversals have capabilities above fmap but I need something else here).
Sunday, November 23, 2008
Bala
Copperbox revision 349.
I've added a new module Pulse for working with clave patterns, inspired by Godfried Toussaint's papers:
http://cgm.cs.mcgill.ca/~godfried/publications/banff.pdf
http://cgm.cs.mcgill.ca/~godfried/publications/clave.pdf
The new module is quite preliminary, particularly clave patterns are bit patterns - all attacks have the same unit duration. I haven't yet worked out how I'm going to build rhythm patterns with 'prolongation' from clave patterns, though there is some work in the Pulse module for building patterns where tap (the onset function) has a length.
I've added a new module Pulse for working with clave patterns, inspired by Godfried Toussaint's papers:
http://cgm.cs.mcgill.ca/~godfried/publications/banff.pdf
http://cgm.cs.mcgill.ca/~godfried/publications/clave.pdf
The new module is quite preliminary, particularly clave patterns are bit patterns - all attacks have the same unit duration. I haven't yet worked out how I'm going to build rhythm patterns with 'prolongation' from clave patterns, though there is some work in the Pulse module for building patterns where tap (the onset function) has a length.
Saturday, November 22, 2008
Friday, November 21, 2008
Thursday, November 20, 2008
Bala
Copperbox revision 346.
I've added a new module to Bala for 'focused' shape and contents traversals.
It allows quite sophisticated operations like this:
Here retrograde reverses just the pitch content of a motif, and not the rhythmic content. If you had a motif like this one (where qn is a quarter note and hn as a half note):
The result would be
The functions separate and rejoin work like decompose and reassemble from the paper 'The Essence of the Iterator Pattern' [Gibbons & Oliveira], but they have a special focusing mechanism that in this case extracts pitches as the content rather than the 'outer' datatype. In this case the outer datatype is a sum type that holds notes, chords and rests, etc. not all of which actually have a pitch attribute.
I've added a new module to Bala for 'focused' shape and contents traversals.
It allows quite sophisticated operations like this:
retrograde :: Motif -> Motif
retrograde = rejoin pitchFocus . second reverse . separate pitchFocus
Here retrograde reverses just the pitch content of a motif, and not the rhythmic content. If you had a motif like this one (where qn is a quarter note and hn as a half note):
C qn, rest qn, D hn, E hn
The result would be
E qn, rest qn, D hn, C hn
The functions separate and rejoin work like decompose and reassemble from the paper 'The Essence of the Iterator Pattern' [Gibbons & Oliveira], but they have a special focusing mechanism that in this case extracts pitches as the content rather than the 'outer' datatype. In this case the outer datatype is a sum type that holds notes, chords and rests, etc. not all of which actually have a pitch attribute.
Wednesday, November 19, 2008
Bala and HNotate
Copperbox revision 343.
MeterDemo2 in Bala now produces valid LilyPond output through HNotate, using HNotate's document combinators rather than a template file.
Altogether that means quite a lot of parts are now working at least to a reasonable prototype level, and its certainly going to be easier to make them robust from working versions than partially working versions.
MeterDemo2 in Bala now produces valid LilyPond output through HNotate, using HNotate's document combinators rather than a template file.
Altogether that means quite a lot of parts are now working at least to a reasonable prototype level, and its certainly going to be easier to make them robust from working versions than partially working versions.
Bala and HNotate
Copperbox revision 342.
Most of the work is now done to get the new Bala EDSL to output LilyPond. The output looks okay, but HNotate's DocLilyPond module is not yet complete enough to generate a proper LilyPond score. Of course, I could write a score template which would work, but DocLilyPond needs the work...
Most of the work is now done to get the new Bala EDSL to output LilyPond. The output looks okay, but HNotate's DocLilyPond module is not yet complete enough to generate a proper LilyPond score. Of course, I could write a score template which would work, but DocLilyPond needs the work...
Bala and HNotate
Copperbox revision 341.
Bala - I've added a new 'structural' music EDSL - Structural2. I will replace Structural with this module once I've added HNotate output to Structural2 - currently it just has Midi and ascii output. Also I'll probably rename it as well. The treatment of 'ragged overlays' is sharper in Structural2 than Structural. A ragged overlay is something like this, where line-b extends past line-a:
Structural was a bit adhoc about handling these. Structural2 has better defined 'packing' - line-a will be packed to line-b, and both will be packed to the end of the bar if necessary:
HNotate - I've moved the function divModR into Duration so it is visible to Bala. Also it didn't work properly so I've sorted that out.
Bala - I've added a new 'structural' music EDSL - Structural2. I will replace Structural with this module once I've added HNotate output to Structural2 - currently it just has Midi and ascii output. Also I'll probably rename it as well. The treatment of 'ragged overlays' is sharper in Structural2 than Structural. A ragged overlay is something like this, where line-b extends past line-a:
aaaaaaa
bbbbbbbb
Structural was a bit adhoc about handling these. Structural2 has better defined 'packing' - line-a will be packed to line-b, and both will be packed to the end of the bar if necessary:
aaaa|aaa.|....|
...b|bbbb|bbb.|
HNotate - I've moved the function divModR into Duration so it is visible to Bala. Also it didn't work properly so I've sorted that out.
Tuesday, November 18, 2008
HNotate and Bala
Copperbox revision 240.
Another minor update. I've renamed the section functions in HNotate's Fits module to segment. Section was too good a noun to waste on a verb.
Another minor update. I've renamed the section functions in HNotate's Fits module to segment. Section was too good a noun to waste on a verb.
HNotate, Bala and ZMidi
Copperbox revision 339.
HNotate - I've changed the type signature of the sectioning functions in Fits so that the divisor is before the sequence. I should have spotted that the previous signature (sequence before divisor) wasn't idiomatic when I wrote it. The idiomatic style is characterized by replicate in Data.List:
replicate :: Int -> a -> [a]
Bala and ZMidi - minor tidy ups.
HNotate - I've changed the type signature of the sectioning functions in Fits so that the divisor is before the sequence. I should have spotted that the previous signature (sequence before divisor) wasn't idiomatic when I wrote it. The idiomatic style is characterized by replicate in Data.List:
replicate :: Int -> a -> [a]
Bala and ZMidi - minor tidy ups.
Monday, November 17, 2008
ZMidi
Copperbox revision 337.
I've improved the error reporting when parsing fails in ZMidi and the sample app MidiPrint.
MidiPrint will print a log of all the parsed Midi events up to the failure. Unfortunately ZMidi isn't so robust when parsing Midi files that are created by 'synthesizers' rather than programs like abc2midi or LilyPond. Files created by synthesizers can often have events that aren't accounted for in descriptions of the Midi file format that I've seen on the web.
I've improved the error reporting when parsing fails in ZMidi and the sample app MidiPrint.
MidiPrint will print a log of all the parsed Midi events up to the failure. Unfortunately ZMidi isn't so robust when parsing Midi files that are created by 'synthesizers' rather than programs like abc2midi or LilyPond. Files created by synthesizers can often have events that aren't accounted for in descriptions of the Midi file format that I've seen on the web.
ZMidi
Copperbox revision 336.
I've replaced Parsec with a handmade parser monad (actually a combination of ErrorT WriterT State) in ReadMidi. I wasn't using anything adventurous from Parsec as reading Midi only doesn't require lookahead, and I wanted to add a WriterT for logging. As Parsec 2 is not a monad transformer I was getting the wrong type for logging - Either ParseError (a,String) - this isn't useful as I only want the logging if the parse fails. The new monad has the type - (Either ParseErr a, String) - so the log is accessible on success or failure, but the run function throws out the log on success.
I've replaced Parsec with a handmade parser monad (actually a combination of ErrorT WriterT State) in ReadMidi. I wasn't using anything adventurous from Parsec as reading Midi only doesn't require lookahead, and I wanted to add a WriterT for logging. As Parsec 2 is not a monad transformer I was getting the wrong type for logging - Either ParseError (a,String) - this isn't useful as I only want the logging if the parse fails. The new monad has the type - (Either ParseErr a, String) - so the log is accessible on success or failure, but the run function throws out the log on success.
Bala
Copperbox revision 335.
I've restructured the Bala directories. The music representation modules (Chord, Interval, etc.) were cluttering up Bala.Base, so I've put them in a new folder MusicRep.
These modules are the first to go rusty whenever I change something in Bala, so it seems preferable to park them out in a separate folder where they can rust in peace until Bala.Base is stable and useful enough to need them. I want Bala.Base to handle just the mechanics of music - i.e. outputting Midi and scores and the most primitive types (Pitch, Duration...), and not higher level representations.
I've restructured the Bala directories. The music representation modules (Chord, Interval, etc.) were cluttering up Bala.Base, so I've put them in a new folder MusicRep.
These modules are the first to go rusty whenever I change something in Bala, so it seems preferable to park them out in a separate folder where they can rust in peace until Bala.Base is stable and useful enough to need them. I want Bala.Base to handle just the mechanics of music - i.e. outputting Midi and scores and the most primitive types (Pitch, Duration...), and not higher level representations.
Sunday, November 16, 2008
Bala, HNotate and ZMidi
Copperbox revision 333.
I've added a Midi output module for the Bala DSL in the Bala.Base libraries. I had been using HNotate's Midi output, but I couldn't see an easy way to rejoin long notes that had been split and tied (tied notes play twice with HNotate's Midi output).
Bala and HNotate seem to have agreed upon a maxim - "keep exactly as much structure as you need". As soon as I've translated a music structure into a different form there is always some data that gets lost, appears essential, and is a real headache to recover.
I've added a Midi output module for the Bala DSL in the Bala.Base libraries. I had been using HNotate's Midi output, but I couldn't see an easy way to rejoin long notes that had been split and tied (tied notes play twice with HNotate's Midi output).
Bala and HNotate seem to have agreed upon a maxim - "keep exactly as much structure as you need". As soon as I've translated a music structure into a different form there is always some data that gets lost, appears essential, and is a real headache to recover.
ZMidi
Copperbox revisions 331 & 332.
(331 - I missed adding the new files, added in 332).
I've added an new module Construction to ZMidi. This will probably replace SyntaxElements when it has more features and has been tested some more.
I realized yesterday, that SyntaxElements is next to useless for constructing Midi. Wrapping up the syntax tree in shorthand constructors misses a big point - constructing Midi is tedious because the syntax tree holds a lot of state (channel number, delta time) rather than tedious due to the syntax itself.
The Construction module has a rather odd interface - its basically a writer monad, although implemented as a state monad. The syntax tree is built with commands (i.e. functions that return unit - () ), rather than functions that return the partial tree as it is created. While this is hardly idiomatic for a Haskell library, it does mean that client programs can be pretty concise.
(331 - I missed adding the new files, added in 332).
I've added an new module Construction to ZMidi. This will probably replace SyntaxElements when it has more features and has been tested some more.
I realized yesterday, that SyntaxElements is next to useless for constructing Midi. Wrapping up the syntax tree in shorthand constructors misses a big point - constructing Midi is tedious because the syntax tree holds a lot of state (channel number, delta time) rather than tedious due to the syntax itself.
The Construction module has a rather odd interface - its basically a writer monad, although implemented as a state monad. The syntax tree is built with commands (i.e. functions that return unit - () ), rather than functions that return the partial tree as it is created. While this is hardly idiomatic for a Haskell library, it does mean that client programs can be pretty concise.
Saturday, November 15, 2008
Bala and HNotate
Copperbox revision 330.
Changes to HNotate to get the Bala 'MeterDemo' to work.
I've changed the construction of event lists - the append operator (|#) - so that the first line in a set of overlays continues the 'primary' line of music, rather all the lines in an overlay forking. Also I've redone the fit function for sequences so that it will accumulate zeros with the left-hand result. To illustrate, sectioning the sequence:
(| 5,0,0,4,1,0,0,0,3 |)
by 5 will, should now result in this:
(| (| 5,0,0 |), (| 4,1,0,0,0 |), (| 3 |) |)
Previously the zeros were accumulated to the right, prefixing the next section. This is the wrong behaviour for hyphenating sections, and cause problems for ties. That said, I don't yet account for ties in the midi output module in HNotate so a tied note wrongly sounds twice.
Changes to HNotate to get the Bala 'MeterDemo' to work.
I've changed the construction of event lists - the append operator (|#) - so that the first line in a set of overlays continues the 'primary' line of music, rather all the lines in an overlay forking. Also I've redone the fit function for sequences so that it will accumulate zeros with the left-hand result. To illustrate, sectioning the sequence:
(| 5,0,0,4,1,0,0,0,3 |)
by 5 will, should now result in this:
(| (| 5,0,0 |), (| 4,1,0,0,0 |), (| 3 |) |)
Previously the zeros were accumulated to the right, prefixing the next section. This is the wrong behaviour for hyphenating sections, and cause problems for ties. That said, I don't yet account for ties in the midi output module in HNotate so a tied note wrongly sounds twice.
Friday, November 14, 2008
Bala and HNotate
Copperbox revision 329.
I've coded most for the translation from the Bala DSL to HNotate. It works up to overlays (i.e. parallel bars - voice overlays in Abc). It looks like I'll have to change HNotate a bit to get Bala's overlays working though.
Overlays in HNotate branch the event list making it a tree, I think the best option will be to give the first line in an overlay a distinguished position - it continues the music line forward (rightwards). Overlays can branch but there should always be a distinguished line as in 'railroad' syntax diagrams. Pity I don't have a picture handy...
I've coded most for the translation from the Bala DSL to HNotate. It works up to overlays (i.e. parallel bars - voice overlays in Abc). It looks like I'll have to change HNotate a bit to get Bala's overlays working though.
Overlays in HNotate branch the event list making it a tree, I think the best option will be to give the first line in an overlay a distinguished position - it continues the music line forward (rightwards). Overlays can branch but there should always be a distinguished line as in 'railroad' syntax diagrams. Pity I don't have a picture handy...
HNotate
Copperbox revision 326.
I've made a separate module for the 'fitting' functions and typeclass, and added a very general sectioning function that can split sequences into measured lengths and optionally hyphenate them when an element has been split across two sections (for music this would mean putting a tie at the end of the left bar).
I haven't yet replaced partitionGVO the HNotate function that currently does bar division with a complex stateful fold, but once I do, I should be able to handle notes with duration greater than the bar length. Currently HNotate's behaviour for extra long notes is unknown.
I've made a separate module for the 'fitting' functions and typeclass, and added a very general sectioning function that can split sequences into measured lengths and optionally hyphenate them when an element has been split across two sections (for music this would mean putting a tie at the end of the left bar).
I haven't yet replaced partitionGVO the HNotate function that currently does bar division with a complex stateful fold, but once I do, I should be able to handle notes with duration greater than the bar length. Currently HNotate's behaviour for extra long notes is unknown.
Thursday, November 13, 2008
Bala and HNotate
Copperbox revision 325.
Some work on an interface between Haskore and HNotate and some work on my own embedded music DSL.
The attempts I've made at interfacing Haskore and HNotate have been tough going. Haskore models a lot of musical structure through functions - for example there is no chord datatype, chords are made by folding the parallel composition operator (:=:). While this does make Haskore pleasantly uniform both users and its developers, it does make it hard work for me to 'recover' musical structure in the interface to HNotate. Chords themselves aren't particularly hard to recover but its hard to turn trills into grace notes (I would probably have to scan the event list for notes with irregular durations). Similarly an instrument can change mid score, whereas HNotate represents different instruments as separate lines within a system.
As I found the last days work on a Haskore / HNotate interface so tough, I've restarted work on an embedded music DSL within Bala. Unlike Haskore, I'm using datatypes to store quite a bit of structural information - for instance I have bars, chords and two types of grace notes. Also I'm using Data.Sequence like I did HNotate, Data.Sequence has the particularly attractive property that its easy to add to the right, but traverse from the left.
Some work on an interface between Haskore and HNotate and some work on my own embedded music DSL.
The attempts I've made at interfacing Haskore and HNotate have been tough going. Haskore models a lot of musical structure through functions - for example there is no chord datatype, chords are made by folding the parallel composition operator (:=:). While this does make Haskore pleasantly uniform both users and its developers, it does make it hard work for me to 'recover' musical structure in the interface to HNotate. Chords themselves aren't particularly hard to recover but its hard to turn trills into grace notes (I would probably have to scan the event list for notes with irregular durations). Similarly an instrument can change mid score, whereas HNotate represents different instruments as separate lines within a system.
As I found the last days work on a Haskore / HNotate interface so tough, I've restarted work on an embedded music DSL within Bala. Unlike Haskore, I'm using datatypes to store quite a bit of structural information - for instance I have bars, chords and two types of grace notes. Also I'm using Data.Sequence like I did HNotate, Data.Sequence has the particularly attractive property that its easy to add to the right, but traverse from the left.
Wednesday, November 12, 2008
Tuesday, November 11, 2008
HNotate
Copperbox revisions 321 & 322.
Revision 321 missing a file and won't build, added in revision 322.
The new revision includes a rough provisional implementation of outputting from PPrint style document combinators rather than template files (again).
I've made a lot of progress since I decided to abandon document combinators for template files, but doing the Scales example with Bala I realized that templates have a significant limitation: for each scale I wanted to render, I need a pluggable hole in the template file. I couldn't dynamically decide how many scales to output.
Document combinators don't have this problem and also the new ones can work pretty well with the 'evaluation machinery' already in place for templates. Although I don't intend making it as large as the last attempt (see here), the current version will need quite a lot of work - there are only enough combinators to get a test to work and no support for Abc.
Revision 321 missing a file and won't build, added in revision 322.
The new revision includes a rough provisional implementation of outputting from PPrint style document combinators rather than template files (again).
I've made a lot of progress since I decided to abandon document combinators for template files, but doing the Scales example with Bala I realized that templates have a significant limitation: for each scale I wanted to render, I need a pluggable hole in the template file. I couldn't dynamically decide how many scales to output.
Document combinators don't have this problem and also the new ones can work pretty well with the 'evaluation machinery' already in place for templates. Although I don't intend making it as large as the last attempt (see here), the current version will need quite a lot of work - there are only enough combinators to get a test to work and no support for Abc.
Sunday, November 9, 2008
Bala and HNotate
Copperbox revision 318.
I've added a new example in Bala - MeterDemo - for experiments with meter patterns. Working through a samba rhythm pattern show up quite a few problems with HNotate's Midi output, so that has been revised as well.
I've added a new example in Bala - MeterDemo - for experiments with meter patterns. Working through a samba rhythm pattern show up quite a few problems with HNotate's Midi output, so that has been revised as well.
Saturday, November 8, 2008
Bala
Copperbox revision 316.
I've removed quite a lot of rusty code from Bala especially from the Pitch module. I'm trying to get to a small core of types and operations for pitches, intervals, chords, scales etc. - and as pitch is the fundamental one, it needed working first. Pitch has a fairly obvious type - or the requirements for a Pitch type are fairly obvious (octave, pitch letter, accidental or not). The others aren't so obvious, so I've left the rough code for Scale and Chord as it is for the time being.
The Affi & Deco instances for all types have gone into a separate module - I'm not sure if I'll continue with them, they would be nice if I had a custom read-eval-print-loop but they increase the code size of the modules which I'm trying to keep minimized.
I've removed quite a lot of rusty code from Bala especially from the Pitch module. I'm trying to get to a small core of types and operations for pitches, intervals, chords, scales etc. - and as pitch is the fundamental one, it needed working first. Pitch has a fairly obvious type - or the requirements for a Pitch type are fairly obvious (octave, pitch letter, accidental or not). The others aren't so obvious, so I've left the rough code for Scale and Chord as it is for the time being.
The Affi & Deco instances for all types have gone into a separate module - I'm not sure if I'll continue with them, they would be nice if I had a custom read-eval-print-loop but they increase the code size of the modules which I'm trying to keep minimized.
Friday, November 7, 2008
Bala and HNotate
Copperbox revision 315.
I've change the type signatures of the named elements in HNotate.Pitch so that they show up in Haddock. Also I've moved the named pitch labels (c_nat, c_sharp etc.) from HNotate.Data into HNotate.Pitch so that the get imported into Bala.Base.Pitch.
I've change the type signatures of the named elements in HNotate.Pitch so that they show up in Haddock. Also I've moved the named pitch labels (c_nat, c_sharp etc.) from HNotate.Data into HNotate.Pitch so that the get imported into Bala.Base.Pitch.
Bala
Copperbox revisions 313 & 314.
I've made some changes to Bala's directory layout and removed some old examples that no longer worked and weren't worth updating (they are duplicated for HNotate).
I've added one Bala example DemoScale to output scales. This one uses the Bala libraries to compute output, unlike the deleted examples were actually static note lists and didn't really uses the Bala libraries at all. Lots of the Bala code has got very rusty since I split off the output generation into HNotate, and while DemoScale runs it produces incorrect output. There's a lot of work to do on Bala...
I've made some changes to Bala's directory layout and removed some old examples that no longer worked and weren't worth updating (they are duplicated for HNotate).
I've added one Bala example DemoScale to output scales. This one uses the Bala libraries to compute output, unlike the deleted examples were actually static note lists and didn't really uses the Bala libraries at all. Lots of the Bala code has got very rusty since I split off the output generation into HNotate, and while DemoScale runs it produces incorrect output. There's a lot of work to do on Bala...
Thursday, November 6, 2008
HNotate
Copperbox revision 311.
I've improved the Midi output from HNotate. Grace notes, chords an polyphony are now accommodated i.e. they are implemented but I haven't tested them yet. Because it doesn't make sense for Midi output to have a template file, I haven't yet implemented a proper top-level function to generate Midi (so I haven't done much testing).
The current top-level function outputMidi outputs only one eventlist in a system, this needs generalizing, plus I need to be able to change some of the properties in the environment.
I've improved the Midi output from HNotate. Grace notes, chords an polyphony are now accommodated i.e. they are implemented but I haven't tested them yet. Because it doesn't make sense for Midi output to have a template file, I haven't yet implemented a proper top-level function to generate Midi (so I haven't done much testing).
The current top-level function outputMidi outputs only one eventlist in a system, this needs generalizing, plus I need to be able to change some of the properties in the environment.
Wednesday, November 5, 2008
ZMidi
Copperbox revision 310.
Some tidy up work on the Parsec Midi file parser, there are still some rough edges and at some point I must put in decent error reporting / error recovery.
Also I've removed the Data.Binary based parser, it removes a dependency and removes the work of keeping two modules up-to-date.
Some tidy up work on the Parsec Midi file parser, there are still some rough edges and at some point I must put in decent error reporting / error recovery.
Also I've removed the Data.Binary based parser, it removes a dependency and removes the work of keeping two modules up-to-date.
ZMidi
Copperbox revision 309.
WriteMidi in ZMidi now uses ShowS style output like HNotate's MiniMidi. The function definitions are much more concise, but funnily enough the file size is about the same.
Also I've moved the MidiPrint example into ZMidi from the Bala directory.
WriteMidi in ZMidi now uses ShowS style output like HNotate's MiniMidi. The function definitions are much more concise, but funnily enough the file size is about the same.
Also I've moved the MidiPrint example into ZMidi from the Bala directory.
Tuesday, November 4, 2008
HNotate
Copperbox revision 308.
I've decided to put Midi support back in HNotate. As both LilyPond and Abc can generate Midi it wasn't a priority and it got dropped a while ago when I wanted to remove external dependencies, however I felt that I wanted it back.
The re-implementation is self-contained, it doesn't have a dependency on ZMidi. At the moment the code is pretty ragged but can output monophonic music (chords, graces and polyphony fail).
I've decided to put Midi support back in HNotate. As both LilyPond and Abc can generate Midi it wasn't a priority and it got dropped a while ago when I wanted to remove external dependencies, however I felt that I wanted it back.
The re-implementation is self-contained, it doesn't have a dependency on ZMidi. At the moment the code is pretty ragged but can output monophonic music (chords, graces and polyphony fail).
Monday, November 3, 2008
HNotate
Copperbox revision 306.
Major change of the note list / event list data types. The glyph type is now an open type, hopefully this will allow user defined glyphs (e.g drum pitches for LilyPond). Previously any new type had to be another constructor on the glyph type, mandating changes both to the type definition and functions that pattern match on it.
Major change of the note list / event list data types. The glyph type is now an open type, hopefully this will allow user defined glyphs (e.g drum pitches for LilyPond). Previously any new type had to be another constructor on the glyph type, mandating changes both to the type definition and functions that pattern match on it.
Saturday, November 1, 2008
HNotate and Bala
Copperbox revision 305.
More directory layout changes. Added a new directory Variant for 'doodles'.
One of the doodles is a interface for Haskore to HNotate. I haven't run this for quite some time and unfortunately even after the all the recent reworking on HNotate it still produces very bad output. One of the demos sends GHC into orbit, another has problems with pitch labelling - the output keeps rising up the staff adding ledger lines.
More directory layout changes. Added a new directory Variant for 'doodles'.
One of the doodles is a interface for Haskore to HNotate. I haven't run this for quite some time and unfortunately even after the all the recent reworking on HNotate it still produces very bad output. One of the demos sends GHC into orbit, another has problems with pitch labelling - the output keeps rising up the staff adding ledger lines.
HNotate and Bala
Copperbox revision 303.
I've changed Bala to use the Pitch and Duration modules from HNotate. Currently quite quite a lot is stubbed out in Bala and none of the examples have been updated.
Most of the Bala examples were redone for HNotate and put in the HNotate/Examples directory. These still work - the changes to HNotate were pretty minor and anything that worked before this change still works.
I've changed Bala to use the Pitch and Duration modules from HNotate. Currently quite quite a lot is stubbed out in Bala and none of the examples have been updated.
Most of the Bala examples were redone for HNotate and put in the HNotate/Examples directory. These still work - the changes to HNotate were pretty minor and anything that worked before this change still works.
Friday, October 31, 2008
HNotate
Copperbox revision 300.
I've added ErrorT into the NotateMonadT monad stack. During the work to get absolute pitch working for LilyPond output, I've felt that some of the functions really need to return failure rather use a default. Defaulting to middle C for relative output is one - if a score file doesn't have a relative pitch set and it has a directive for relative output, then it seems like a problem to signal to the user for correction rather than do the output regardless.
As for Copperbox being 300, well the code is looking much better as of the last month, maybe by revision 400 HNotate will be ready for release.
I've added ErrorT into the NotateMonadT monad stack. During the work to get absolute pitch working for LilyPond output, I've felt that some of the functions really need to return failure rather use a default. Defaulting to middle C for relative output is one - if a score file doesn't have a relative pitch set and it has a directive for relative output, then it seems like a problem to signal to the user for correction rather than do the output regardless.
As for Copperbox being 300, well the code is looking much better as of the last month, maybe by revision 400 HNotate will be ready for release.
Thursday, October 30, 2008
HNotate
Copperbox revision 298.
I've improved the datatype (and parsers) for parsing the input file as templates. The new datatype guarantees that water and islands alternate (i.e. text source that needs to be preserved - water - must be followed by an output directive - an island - or the end of file). Previously, islands were wrapped in a Maybe type which didn't guarantee anything.
I've improved the datatype (and parsers) for parsing the input file as templates. The new datatype guarantees that water and islands alternate (i.e. text source that needs to be preserved - water - must be followed by an output directive - an island - or the end of file). Previously, islands were wrapped in a Maybe type which didn't guarantee anything.
Wednesday, October 29, 2008
HNotate
Copperbox revision 297.
I've cleaned up the BuildNoteList module - the last one rather complicated, I wrote in a fit of enthusiasm after discovering apomorphisms. The latest one uses a nice new typeclass Fits which might suffer the terrible fate of being used for only one type. If I had of written Fits before the new pretty printer I might have used it in that, but the 'fitting' there is much simpler than for the note list (where none-fitting notes must be split across bars with ties) - putting it in the pretty printer now might actually complicate things.
Thinking about yesterdays comment, I'm changing my opinion and I think I was wrong to 'add context' to the annotations and might remove the Abc / LilyPond differentiation rather than extend it. Apropos the 'canonical notelist' I mentioned, it is quite possible that annotation will be best done as a traversal / transformation over the canonical notelist, with different transformer functions for Abc and LilyPond.
I've cleaned up the BuildNoteList module - the last one rather complicated, I wrote in a fit of enthusiasm after discovering apomorphisms. The latest one uses a nice new typeclass Fits which might suffer the terrible fate of being used for only one type. If I had of written Fits before the new pretty printer I might have used it in that, but the 'fitting' there is much simpler than for the note list (where none-fitting notes must be split across bars with ties) - putting it in the pretty printer now might actually complicate things.
Thinking about yesterdays comment, I'm changing my opinion and I think I was wrong to 'add context' to the annotations and might remove the Abc / LilyPond differentiation rather than extend it. Apropos the 'canonical notelist' I mentioned, it is quite possible that annotation will be best done as a traversal / transformation over the canonical notelist, with different transformer functions for Abc and LilyPond.
Tuesday, October 28, 2008
HNotate
Copperbox revision 296.
Some work on annotations. I've put in a mechanism where Abc annotations are dropped for LilyPond output and vice versa.
This fits with a principle I have for HNotate where you have a canonical notelist but might choose to render it differently (i.e. as Abc or LilyPond), but it needs some more thought. The important thing about annotations is that they let you get to the 'good stuff' in LilyPond (e.g. dynamic markings, string numbering for tablature output etc.). One of the things I want to be able to do is render a tune both as staff notation and guitar tablature, and I don't want the same annotations in both. The annotation mechanism in HNotate will need a finer grained notion of context than just Abc/LilyPond.
Some work on annotations. I've put in a mechanism where Abc annotations are dropped for LilyPond output and vice versa.
This fits with a principle I have for HNotate where you have a canonical notelist but might choose to render it differently (i.e. as Abc or LilyPond), but it needs some more thought. The important thing about annotations is that they let you get to the 'good stuff' in LilyPond (e.g. dynamic markings, string numbering for tablature output etc.). One of the things I want to be able to do is render a tune both as staff notation and guitar tablature, and I don't want the same annotations in both. The annotation mechanism in HNotate will need a finer grained notion of context than just Abc/LilyPond.
HNotate
Copperbox revision 293.
Again another instance of deja vu as I've redone the Abc backend. It now uses the new ODoc / Document mini pretty printer and doesn't use the print monad or PPrint.
Importantly, it allows annotations such as up-bow and down-bow markings for Abc. This has never really been working before. The 'combinator' version of the Abc and LilyPond back-ends from a couple of months ago could ouput annotations, but there was no mechanism to specify them in the input notelist.
Adding them to the input notelist was simple in the end - they are just another glyph. But whereas note and rest have obvious, first-order properties (pitch and duration for note, duration for rest), annotations have a single higher-order property - a function of type ODoc -> ODoc that transforms the output of the the preceeding glyph which it annotates during rendering.
Again another instance of deja vu as I've redone the Abc backend. It now uses the new ODoc / Document mini pretty printer and doesn't use the print monad or PPrint.
Importantly, it allows annotations such as up-bow and down-bow markings for Abc. This has never really been working before. The 'combinator' version of the Abc and LilyPond back-ends from a couple of months ago could ouput annotations, but there was no mechanism to specify them in the input notelist.
Adding them to the input notelist was simple in the end - they are just another glyph. But whereas note and rest have obvious, first-order properties (pitch and duration for note, duration for rest), annotations have a single higher-order property - a function of type ODoc -> ODoc that transforms the output of the the preceeding glyph which it annotates during rendering.
Monday, October 27, 2008
HNotate
Copperbox revision 292.
I've added a new module Document which is a limited mini pretty print module. Its salient feature is that it treats concatenation on the empty doc differently to PPrint or HughesPJ - concatenating two empty docs with <+> results in the empty doc - with PPrint it results in a space.
I expect that the print monad will be replaced by simple outputter that uses this module.
I've added a new module Document which is a limited mini pretty print module. Its salient feature is that it treats concatenation on the empty doc differently to PPrint or HughesPJ - concatenating two empty docs with <+> results in the empty doc - with PPrint it results in a space.
I expect that the print monad will be replaced by simple outputter that uses this module.
Sunday, October 26, 2008
Saturday, October 25, 2008
HNotate
Copperbox revision 287.
I've cleaned up the logging interface for HNotate monad - resemblance to Hood and the Observe type class are not exactly coincidental.
Outputting unmetered music is working again. Problems still remain with Abc parsing and initial partial bar lengths.
I've cleaned up the logging interface for HNotate monad - resemblance to Hood and the Observe type class are not exactly coincidental.
Outputting unmetered music is working again. Problems still remain with Abc parsing and initial partial bar lengths.
Friday, October 24, 2008
HNotate
Copperbox revision 285.
Deja vu! Another rewrite of the LilyPond and Abc island parsers.
Again the rewrite fells more idiomatic and slightly simpler, the Abc preprocessor is now just 7 lines and building nested expression from the parse result is easier. Unfortunately there is a bad bug in the new Abc parser where I didn't account for line endings terminating fields. The example below parses the key as C M and fails on 2/4 because it has already consumed the meter field designator:
K:C
M:2/4
Deja vu! Another rewrite of the LilyPond and Abc island parsers.
Again the rewrite fells more idiomatic and slightly simpler, the Abc preprocessor is now just 7 lines and building nested expression from the parse result is easier. Unfortunately there is a bad bug in the new Abc parser where I didn't account for line endings terminating fields. The example below parses the key as C M and fails on 2/4 because it has already consumed the meter field designator:
K:C
M:2/4
Wednesday, October 22, 2008
HNotate
Copperbox revision 285.
The Notate monad (WriterT (ReaderT (ReaderT))) is now used everywhere that accesses values in the env (e.g. the default note length, the bar length, or the relative pitch).
I should have done this sometime ago - for one thing it makes the HNotate modules more uniform. Some e.g. the Traversals module, no longer access the env directly as a passed in parameter. Secondly it makes all the non-pure functions log-able - this would have been a big help in the recent debugging.
I've found out (but not yet fixed) why properties properties like partial start are being dropped - the Expression datatype should not allow lists of let bindings - only single let bindings and lists of output directives. Output directives must be inside the right-hand side of a let binding to have effect - with lists of let-bindings they were getting misplaced.
The Notate monad (WriterT (ReaderT (ReaderT))) is now used everywhere that accesses values in the env (e.g. the default note length, the bar length, or the relative pitch).
I should have done this sometime ago - for one thing it makes the HNotate modules more uniform. Some e.g. the Traversals module, no longer access the env directly as a passed in parameter. Secondly it makes all the non-pure functions log-able - this would have been a big help in the recent debugging.
I've found out (but not yet fixed) why properties properties like partial start are being dropped - the Expression datatype should not allow lists of let bindings - only single let bindings and lists of output directives. Output directives must be inside the right-hand side of a let binding to have effect - with lists of let-bindings they were getting misplaced.
Tuesday, October 21, 2008
HNotate
Copperbox revision 284.
I've re-instated handling of un-metered music in the front end (the \cadenzaOn command in LilyPond, or 'missing' meter field for Abc tunes). The back end needs revision to make it work.
I've added a new set of tests - hopefully these should make it easier to track whether or not features like starting with a partial bar or un-metered music work. As the code is unfortuantely still quite unstable these features have a habit of falling out.
I've re-instated handling of un-metered music in the front end (the \cadenzaOn command in LilyPond, or 'missing' meter field for Abc tunes). The back end needs revision to make it work.
I've added a new set of tests - hopefully these should make it easier to track whether or not features like starting with a partial bar or un-metered music work. As the code is unfortuantely still quite unstable these features have a habit of falling out.
Monday, October 20, 2008
Sunday, October 19, 2008
HNotate
Copperbox revision 281.
LilyPond preprocessing should now be fixed and partial bars work again in LilyPond (though the bar count is wrong in the output).
Abc still has problems with partial measures and there is a newly discovered bug where files with two output directives together don't parse.
LilyPond preprocessing should now be fixed and partial bars work again in LilyPond (though the bar count is wrong in the output).
Abc still has problems with partial measures and there is a newly discovered bug where files with two output directives together don't parse.
Saturday, October 18, 2008
HNotate
Copperbox revision 281.
I've put logging around the most important processing functions in HNotate - and added alternative top-level functions outputAbc_debug and outputLilyPond_debug that do the processing with logging on.
The problems I've seen where Trees.hs doesn't produce any output for LilyPond and other examples drop directives (e.g. partial measures) look like they stem from the preprocessing stage producing bad output. To fix...
I've put logging around the most important processing functions in HNotate - and added alternative top-level functions outputAbc_debug and outputLilyPond_debug that do the processing with logging on.
The problems I've seen where Trees.hs doesn't produce any output for LilyPond and other examples drop directives (e.g. partial measures) look like they stem from the preprocessing stage producing bad output. To fix...
HNotate
Copperbox revision 280.
I've put the monads from the OutputMain and DebugWriter modules into the new module Monads and turned them into newtypes adding Reader and Writer instances where appropriate.
This should make them more useful to find out why the main evaluation in OutputMain is losing 'partial measure' information.
I've put the monads from the OutputMain and DebugWriter modules into the new module Monads and turned them into newtypes adding Reader and Writer instances where appropriate.
This should make them more useful to find out why the main evaluation in OutputMain is losing 'partial measure' information.
Thursday, October 16, 2008
HNotate
Copperbox revision 278.
Work towards fixing the bug where partial measure directives are missed (adding Pretty print instances for debugging, tidying up code), though no fix yet.
I think I will have to change the monad in OutputMain to be a transformer over writer then I can log what's going on, so I've committed this code now as check-pointed.
Work towards fixing the bug where partial measure directives are missed (adding Pretty print instances for debugging, tidying up code), though no fix yet.
I think I will have to change the monad in OutputMain to be a transformer over writer then I can log what's going on, so I've committed this code now as check-pointed.
Wednesday, October 15, 2008
HNotate
Copperbox revision 275.
Apropos the last commit, I've rewritten the other parsers now as well. Again they are more idiomatic - they look like other Parsec parsers and don't carry around extra state.
The conversion to HOAS is now done after parsing - this means that the parsed syntax will be available for printing out (debugging). Because so much has been changed a lot of the debugging has been dropped but the useful stuff will be put back in soon. Also a few off the examples don't currently work.
Apropos the last commit, I've rewritten the other parsers now as well. Again they are more idiomatic - they look like other Parsec parsers and don't carry around extra state.
The conversion to HOAS is now done after parsing - this means that the parsed syntax will be available for printing out (debugging). Because so much has been changed a lot of the debugging has been dropped but the useful stuff will be put back in soon. Also a few off the examples don't currently work.
Tuesday, October 14, 2008
Sunday, October 12, 2008
HNotate
Copperbox revision 272.
Changes to the Ratio to Duration conversion functions.
The function approximateDuration should now always produce a result (which may be an approximation - hence its name). The function it replaced representableDuration wasn't guaranteed to.
However I now think that HNotate duration representation should simply be the library Rational type. Previously HNotate was a trying to be a library for building for building music (like PPrint is for Docs). When it was a library, I thought it was important to have a dot function that would add half a duration to a duration. With the current type dot is composable
dot $ dot quarter gives a double dotted quarter (7%16).
This isn't possible if I change to using Rational - dot $ dot quarter would be dot $ (3%8) = (9%16) for an obvious definition of dot.
I'll change to Rational on the next commit, the advantages are no expensive conversion routines just to perform Num functions and a properly debugged base type - but will I miss dot?
Changes to the Ratio to Duration conversion functions.
The function approximateDuration should now always produce a result (which may be an approximation - hence its name). The function it replaced representableDuration wasn't guaranteed to.
However I now think that HNotate duration representation should simply be the library Rational type. Previously HNotate was a trying to be a library for building for building music (like PPrint is for Docs). When it was a library, I thought it was important to have a dot function that would add half a duration to a duration. With the current type dot is composable
dot $ dot quarter gives a double dotted quarter (7%16).
This isn't possible if I change to using Rational - dot $ dot quarter would be dot $ (3%8) = (9%16) for an obvious definition of dot.
I'll change to Rational on the next commit, the advantages are no expensive conversion routines just to perform Num functions and a properly debugged base type - but will I miss dot?
HNotate
Copperbox revision 271.
Beaming has been re-implemented for Abc. After my two weeks practice with recursion schemes beam grouping can be done quite nicely with an unfold - if you unfold a list to a list you effectively have lookahead (just like pattern matching and direct recursion of course).
Bar splitting - to get metric subdivisions - is done with an apomorphism which makes it quite short though I can't say the code is very clear.
Beaming has been re-implemented for Abc. After my two weeks practice with recursion schemes beam grouping can be done quite nicely with an unfold - if you unfold a list to a list you effectively have lookahead (just like pattern matching and direct recursion of course).
Bar splitting - to get metric subdivisions - is done with an apomorphism which makes it quite short though I can't say the code is very clear.
Saturday, October 11, 2008
HNotate
Copperbox revision 270.
I've added a general mechanism to handle pitch renaming for Abc output. Pitch spellings for all the modes are handled, but supplementary accidentals are still to do.
Supplementary accidentals permit modes with sharps and flats like Klezmer (Ahavoh Rabboh).
I've added a general mechanism to handle pitch renaming for Abc output. Pitch spellings for all the modes are handled, but supplementary accidentals are still to do.
Supplementary accidentals permit modes with sharps and flats like Klezmer (Ahavoh Rabboh).
Friday, October 10, 2008
HNotate
Copperbox revision 268.
A new revision after some time...
I've been trying to simplify the translation from EventList (the external format) to NoteList (the internal format) using recursion schemes. Well, unfortunately the new version isn't much simpler but I think its more robust - I spotted that the old version wouldn't handle note lengths greater than a bar length very well.
A new revision after some time...
I've been trying to simplify the translation from EventList (the external format) to NoteList (the internal format) using recursion schemes. Well, unfortunately the new version isn't much simpler but I think its more robust - I spotted that the old version wouldn't handle note lengths greater than a bar length very well.
Saturday, September 27, 2008
HNotate
Copperbox revision 267.
Some tidying up - I've moved the enharmonic spelling functions out of the pitch module and deleted the 'builder' modules for LilyPond and Abc.
The two builder modules were probably bigger than the rest of HNotate - I'm almost sad to see them go as they had so much work put into them. I probably had to do all that work to come up with the ah-ha that showed me they were unnecessary, but it would have been nice to have gone down a fruitful path from the beginning.
Some tidying up - I've moved the enharmonic spelling functions out of the pitch module and deleted the 'builder' modules for LilyPond and Abc.
The two builder modules were probably bigger than the rest of HNotate - I'm almost sad to see them go as they had so much work put into them. I probably had to do all that work to come up with the ah-ha that showed me they were unnecessary, but it would have been nice to have gone down a fruitful path from the beginning.
Friday, September 26, 2008
Thursday, September 25, 2008
HNotate
Copperbox revision 264.
A major update - I've now made both the Abc and LilyPond parsers do the 'island parsing' in a preprocessing step. This has made them much simpler - and both can use the exprView parser which parses the shape of a post-processed view .
Also the evaluation of a post-processed view has been simplified in OutputMain. Post-processed LilyPond and Abc are both represented as a very simple datatype Expr which has a handy use of higher-order abstract syntax to modify the environment as Expr is being traversed.
A major update - I've now made both the Abc and LilyPond parsers do the 'island parsing' in a preprocessing step. This has made them much simpler - and both can use the exprView parser which parses the shape of a post-processed view .
Also the evaluation of a post-processed view has been simplified in OutputMain. Post-processed LilyPond and Abc are both represented as a very simple datatype Expr which has a handy use of higher-order abstract syntax to modify the environment as Expr is being traversed.
Wednesday, September 24, 2008
Saturday, September 20, 2008
HNotate
Copperbox revision 261.
The Abc backend now uses a new output scheme which allows it do beaming.
Previously the output built a pretty printed Doc that was wrapped up with a phantom type layer. With the change to using score file templates there is not so much need for this phantom typed doc - HNotate doesn't export the phantom typed doc to users so the responsibility to generate correct output is entirely internal. And it had always felt very heavyweight, as my struggles to get it to do what I wanted showed.
So now its being replaced by a State monad that works like the Writer monad, but with some quirks - the output can't be an instance of Monoid because the append operation has to be controllable on the fly. This is how Abc beaming works - at the start of the beam group the append operator is changed from (<+>) spaced, to (<>) no space then reverted to spaced at the end of the beam.
The next step is to change the LilyPond backend, which will hopefully corroborate the advantages of the new scheme.
The Abc backend now uses a new output scheme which allows it do beaming.
Previously the output built a pretty printed Doc that was wrapped up with a phantom type layer. With the change to using score file templates there is not so much need for this phantom typed doc - HNotate doesn't export the phantom typed doc to users so the responsibility to generate correct output is entirely internal. And it had always felt very heavyweight, as my struggles to get it to do what I wanted showed.
So now its being replaced by a State monad that works like the Writer monad, but with some quirks - the output can't be an instance of Monoid because the append operation has to be controllable on the fly. This is how Abc beaming works - at the start of the beam group the append operator is changed from (<+>) spaced, to (<>) no space then reverted to spaced at the end of the beam.
The next step is to change the LilyPond backend, which will hopefully corroborate the advantages of the new scheme.
Friday, September 19, 2008
HNotate
Copperbox revision 260.
I've revised the ToNoteList module of HNotate and it now brackets notes into groups when the consecutive durations are less than a quarter - then they can be beamed in the output.
Unfortunately, neither the Abc or LilyPond backends support beaming yet. LilyPond brackets a beam group after the first note so a triplet would be c [e g], whereas HNotate has them [c e g] - clearly a translation would be quite easy for this one. Abc is more tricky - beaming is indicated by the absence of a space separator between notes. To get this right I will probably have to change the Abc pretty print combinators.
I've revised the ToNoteList module of HNotate and it now brackets notes into groups when the consecutive durations are less than a quarter - then they can be beamed in the output.
Unfortunately, neither the Abc or LilyPond backends support beaming yet. LilyPond brackets a beam group after the first note so a triplet would be c [e g], whereas HNotate has them [c e g] - clearly a translation would be quite easy for this one. Abc is more tricky - beaming is indicated by the absence of a space separator between notes. To get this right I will probably have to change the Abc pretty print combinators.
Wednesday, September 17, 2008
HNotate
Copperbox revision 258.
I've added an initial mechanism for pitch name naturalization to the Abc output so that accidentals aren't printed when they are already accounted for by the key signature. So far this is only done for two keys as I'm not sure whether to enumerate all the keys 'by hand' or take some of the interval code from Bala and construct the pitch spellings from interval patterns.
The Abc output still doesn't calculate durations properly as this is more involved than with LilyPond, that looks like the next thing to do.
I've added an initial mechanism for pitch name naturalization to the Abc output so that accidentals aren't printed when they are already accounted for by the key signature. So far this is only done for two keys as I'm not sure whether to enumerate all the keys 'by hand' or take some of the interval code from Bala and construct the pitch spellings from interval patterns.
The Abc output still doesn't calculate durations properly as this is more involved than with LilyPond, that looks like the next thing to do.
Tuesday, September 16, 2008
Monday, September 15, 2008
HNotate
Copperbox revision 256.
I've started work on sorting out the traversals. I've tidied up the existing ones, but haven't yet composed them together (currently each traversal is run in a separate pass). Ideally there should be a LilyPond pass or an Abc pass that fuses all the appropriate traversals together.
I've started work on sorting out the traversals. I've tidied up the existing ones, but haven't yet composed them together (currently each traversal is run in a separate pass). Ideally there should be a LilyPond pass or an Abc pass that fuses all the appropriate traversals together.
Sunday, September 14, 2008
HNotate
Copperbox revision 255.
Major changes to the internal note list representation and the EventList interface.
The external event list and internal note list were previously parametric - the internal note list ScNoteList which is really a tree that could have the type of its leaves changed (as Abc glyphs seemed different to LilyPond ones). The external event list was parametric through the type class Event - anything that implemented Event could be rendered.
I've now changed this - the new version is more like the pretty printing libraries PPrint and Text.PrettyPrint.HughesPJ. There is a simple internal format (ScNoteList) plus a functional interface to build it (note, chord, gracenotes etc).
Unfortunately some of the new code is quite messy and not all of the examples that used to work still do (the LilyPond Bulgarian6 example works properly). While the changes have simplified HNotate's internals, there is more work to do to unify the traversals and add metrical grouping so that notes that should be beamed will get beamed.
Major changes to the internal note list representation and the EventList interface.
The external event list and internal note list were previously parametric - the internal note list ScNoteList which is really a tree that could have the type of its leaves changed (as Abc glyphs seemed different to LilyPond ones). The external event list was parametric through the type class Event - anything that implemented Event could be rendered.
I've now changed this - the new version is more like the pretty printing libraries PPrint and Text.PrettyPrint.HughesPJ. There is a simple internal format (ScNoteList) plus a functional interface to build it (note, chord, gracenotes etc).
Unfortunately some of the new code is quite messy and not all of the examples that used to work still do (the LilyPond Bulgarian6 example works properly). While the changes have simplified HNotate's internals, there is more work to do to unify the traversals and add metrical grouping so that notes that should be beamed will get beamed.
Friday, September 12, 2008
HNotate
Copperbox revision 253.
Some work towards implementing unmetered music (aka LilyPond's \cadenzaOn and \cadenzaOff). But it is incomplete as I'm thinking that the intermediate score format might be better of tracking some 'inline marks' like barnumber check (currently they are generated in the final render process). If I do add a mechanism for inline marks they should be able to handle ties and beam grouping as well.
Some work towards implementing unmetered music (aka LilyPond's \cadenzaOn and \cadenzaOff). But it is incomplete as I'm thinking that the intermediate score format might be better of tracking some 'inline marks' like barnumber check (currently they are generated in the final render process). If I do add a mechanism for inline marks they should be able to handle ties and beam grouping as well.
Thursday, September 11, 2008
HNotate
Copperbox revision 252.
I've added a rudimentary interface to Haskore. One of the simplest examples in Haskore produces equivalent output (t251), but more complex examples produce musical gibberish (Children's Song 6, Stars and Stripes Forever).
Working with Haskore's trills is going to be difficult as they are rendered directly to notes (with short durations). In Abc and LilyPond grace notes, which would accommodate trills, are a special case in that they aren't counted in a bars duration.
I've added a rudimentary interface to Haskore. One of the simplest examples in Haskore produces equivalent output (t251), but more complex examples produce musical gibberish (Children's Song 6, Stars and Stripes Forever).
Working with Haskore's trills is going to be difficult as they are rendered directly to notes (with short durations). In Abc and LilyPond grace notes, which would accommodate trills, are a special case in that they aren't counted in a bars duration.
Tuesday, September 9, 2008
HNotate
Copperbox revision 251.
I've added bar number checking to the LilyPond and Abc output.
This certainly makes the generated scores much more readable, but currently the check is printed every bar. It would be better to make this configurable, but this would mean putting the back ends back into a reader monad.
I've added bar number checking to the LilyPond and Abc output.
This certainly makes the generated scores much more readable, but currently the check is printed every bar. It would be better to make this configurable, but this would mean putting the back ends back into a reader monad.
HNotate
Copperbox revision 250.
The intermediate note list (before it is translated to LilyPond) can now be printed for debugging.
This is making the type signatures in OutputMain rather overgrown, but I'll probably try to add support for generating 'spacer lists' first (see the LilyPond manual section 9.2.2 Creating contexts - the music / arts example). If I tidy up OutputMain first I'll only have to change it again to support spacer lists.
Monday, September 8, 2008
HNotate
Copperbox revision 249.
Some tidying up of OutputMain the score generation module.
It's still deficient - the evaluation that builds 'plugs' (indexed documents to fill holes in templates) has the generation strategy hard-wired. The generation performs two steps - render to a common format (the score data types) then output to a either LilyPond or Abc. I want it to be able to just render to the common score format for debugging purposes, but to do that will mean so rethinking of the code.
Some tidying up of OutputMain the score generation module.
It's still deficient - the evaluation that builds 'plugs' (indexed documents to fill holes in templates) has the generation strategy hard-wired. The generation performs two steps - render to a common format (the score data types) then output to a either LilyPond or Abc. I want it to be able to just render to the common score format for debugging purposes, but to do that will mean so rethinking of the code.
Saturday, September 6, 2008
HNotate
Copperbox revision 248.
Significant improvements to the LilyPond and Abc rendering.
Bulgarian6 now outputs valid LilyPond producing the same score as the hand coded version. The Abc output still has some flaws - one is that accidentals are printed when they shouldn't be. Another obvious one is that the beaming is wrong, I'm not sure how to get round this - maybe beaming information will need to be supplied in the input note lists.
There are some other problems for both Abc and LilyPond - principally that the generated output is not as nice as it could be making it hard to read. Both formats should only render a fixed number of measures on one line (possibly just one) and LilyPond should output barlines even though they aren't necessary.
Significant improvements to the LilyPond and Abc rendering.
Bulgarian6 now outputs valid LilyPond producing the same score as the hand coded version. The Abc output still has some flaws - one is that accidentals are printed when they shouldn't be. Another obvious one is that the beaming is wrong, I'm not sure how to get round this - maybe beaming information will need to be supplied in the input note lists.
There are some other problems for both Abc and LilyPond - principally that the generated output is not as nice as it could be making it hard to read. Both formats should only render a fixed number of measures on one line (possibly just one) and LilyPond should output barlines even though they aren't necessary.
Thursday, September 4, 2008
HNotate
Copperbox revision 245.
More reworking on the HNotate code. I've changed the some of the data types (and their names) now that HNotate doesn't try to represent full scores[1]. The Trees.hs example now runs but generates errors in the LilyPond output, clearly I've still a lot do do for LilyPond, alongside restoring Midi and Abc output.
[1] Scores are defined in the LilyPond template files HNotate just injects note lists into the template holes.
More reworking on the HNotate code. I've changed the some of the data types (and their names) now that HNotate doesn't try to represent full scores[1]. The Trees.hs example now runs but generates errors in the LilyPond output, clearly I've still a lot do do for LilyPond, alongside restoring Midi and Abc output.
[1] Scores are defined in the LilyPond template files HNotate just injects note lists into the template holes.
Wednesday, September 3, 2008
HNotate
Copperbox revisions 242 & 243.
Major restructure of HNotate - with revision 242 I deleted both the HNotate and HNotateAlt directories. With revision 243 I added the latest HNotate code which has is the HNotateAlt code but has substantially different file structure.
The LilyPond 'bulgarian6' example in HNotate/Examples runs, which is promising but there are an awful lot of hacks to make it work. A lot of the data structures have been changed to work with new template based generation scheme, but they really need rethinking.
Major restructure of HNotate - with revision 242 I deleted both the HNotate and HNotateAlt directories. With revision 243 I added the latest HNotate code which has is the HNotateAlt code but has substantially different file structure.
The LilyPond 'bulgarian6' example in HNotate/Examples runs, which is promising but there are an awful lot of hacks to make it work. A lot of the data structures have been changed to work with new template based generation scheme, but they really need rethinking.
Monday, September 1, 2008
HNotate
Copperbox revision 241.
HNotate alt - I've added extracting parsers for LilyPond and Abc.
Extracting parsers are island parsers that parse a file and extract some facts but leave much of the content uninterpreted. As they are much simpler than a full parser, hopefully they will always succeed rather than throw a parse error.
My current thinking is that output from HNotate should be limited to just note sequences (after all the input is a just a note list). Larger structure - multiple staffs, headers, and the like - should be specified in LilyPond or Abc files where it can be done more conveniently. Meta-comments in the LilyPond or Abc files can indicate template holes where HNotate will output note sequences.
HNotate alt - I've added extracting parsers for LilyPond and Abc.
Extracting parsers are island parsers that parse a file and extract some facts but leave much of the content uninterpreted. As they are much simpler than a full parser, hopefully they will always succeed rather than throw a parse error.
My current thinking is that output from HNotate should be limited to just note sequences (after all the input is a just a note list). Larger structure - multiple staffs, headers, and the like - should be specified in LilyPond or Abc files where it can be done more conveniently. Meta-comments in the LilyPond or Abc files can indicate template holes where HNotate will output note sequences.
Tuesday, August 26, 2008
HNotate
Copperbox revision 239.
The LilyPond backend in HNotate-alt now uses traversals.
Like the Abc backend, the code seems shorter and neater - some of this might be attributable to it being a rewrite, but it does seem as though traversals are making things easier
The LilyPond backend in HNotate-alt now uses traversals.
Like the Abc backend, the code seems shorter and neater - some of this might be attributable to it being a rewrite, but it does seem as though traversals are making things easier
Monday, August 25, 2008
HNotate
Copperbox revision 236.
HNotate alt - more work on the Score datatypes to support traversals and I've added a new module Bifunctor to abstract over Glyphs which have two type arguments - pitch and duration.
Outputting LilyPond and Abc score files from note lists has been far tougher than I expected. When I started I imagined the only big problem would be adding extra information - for instance score files generally need time and key signatures which aren't in note lists.
This is still a problem which I haven't really resolved (although the pretty print combinators let you overcome it in a rough and ready way), but there have been other significant ones that have made the project work rather than fun. The big one has been a good representation of sheet music, which seems so simple on the face of it - essentially lines (staves) and glyphs (notes, rests, chords, grace notes...). This has been particularly dispiriting as each revision of the score representation over the last couple of months has allowed me to get a little bit further, but then derailed leaving the LilyPond and Abc backends with duplicated copy-paste-edit code that impervious to factoring.
Maybe the new revision will work better - it's nice that it can support fmap, Foldable and Traversable on the structure of the score and bimap (analogous to fmap) on the glyphs. The glyphs are terminals if you envisage the score as a grammar. If it doesn't then its time to abandon Bala and HNotate and go onto something else.
HNotate alt - more work on the Score datatypes to support traversals and I've added a new module Bifunctor to abstract over Glyphs which have two type arguments - pitch and duration.
Outputting LilyPond and Abc score files from note lists has been far tougher than I expected. When I started I imagined the only big problem would be adding extra information - for instance score files generally need time and key signatures which aren't in note lists.
This is still a problem which I haven't really resolved (although the pretty print combinators let you overcome it in a rough and ready way), but there have been other significant ones that have made the project work rather than fun. The big one has been a good representation of sheet music, which seems so simple on the face of it - essentially lines (staves) and glyphs (notes, rests, chords, grace notes...). This has been particularly dispiriting as each revision of the score representation over the last couple of months has allowed me to get a little bit further, but then derailed leaving the LilyPond and Abc backends with duplicated copy-paste-edit code that impervious to factoring.
Maybe the new revision will work better - it's nice that it can support fmap, Foldable and Traversable on the structure of the score and bimap (analogous to fmap) on the glyphs. The glyphs are terminals if you envisage the score as a grammar. If it doesn't then its time to abandon Bala and HNotate and go onto something else.
Friday, August 22, 2008
Thursday, August 21, 2008
HNotate
Copperbox revision 233.
I've changed the score datatypes so they can be Functor instances (and Foldable and Traversable instances). They should really have been in this form in the first place (ah hindsight!), but I had wanted to make duration handling easier for chords and graces and had the datatypes parametrized with two holes - glyph and duration, rather than just glyph.
I've changed the score datatypes so they can be Functor instances (and Foldable and Traversable instances). They should really have been in this form in the first place (ah hindsight!), but I had wanted to make duration handling easier for chords and graces and had the datatypes parametrized with two holes - glyph and duration, rather than just glyph.
Wednesday, August 20, 2008
HNotate
Copperbox revision 232.
More work on HNotate - I spent a long time trying to replace the monad transformer with composed applicative functors within the `toScore` renderer. In the end I simply stopped using the state monad as I'm tracking all the necessary state in the the accumulator that builds the measures as they are rendered.
Currently, only the score renderer is working. The backends look set for a change as I could do most of the processing on them with traversals rather than the folds and directly recursive functions that I currently use. To help the move to traversals I've parameterized the score types so that the `terminal` types - notes, rests - are open and can be changed for the respective backend while the structure types - lines, measures - stay the same (so the traversals can be common across backends).
More work on HNotate - I spent a long time trying to replace the monad transformer with composed applicative functors within the `toScore` renderer. In the end I simply stopped using the state monad as I'm tracking all the necessary state in the the accumulator that builds the measures as they are rendered.
Currently, only the score renderer is working. The backends look set for a change as I could do most of the processing on them with traversals rather than the folds and directly recursive functions that I currently use. To help the move to traversals I've parameterized the score types so that the `terminal` types - notes, rests - are open and can be changed for the respective backend while the structure types - lines, measures - stay the same (so the traversals can be common across backends).
Wednesday, August 13, 2008
HNotate
Copperbox revision 230.
I've started and alternative implementation of HNotate - it was already was too complicated and some of the early design decisions seemed wrong (e.g. having different syntax tree data types for each backend was supposed to make the code simpler but didn't).
At the moment the alt-version is smaller and simpler (but doesn't have the features of the original). I'll have to see if I can keep it smaller and simpler as I get it to work.
I've started and alternative implementation of HNotate - it was already was too complicated and some of the early design decisions seemed wrong (e.g. having different syntax tree data types for each backend was supposed to make the code simpler but didn't).
At the moment the alt-version is smaller and simpler (but doesn't have the features of the original). I'll have to see if I can keep it smaller and simpler as I get it to work.
Tuesday, August 12, 2008
HNotate
Copperbox revisions 227 & 228.
Revision 227 - some tidying up of HNotate. Moved the Utils.hs files out of the Abc, LilyPond and Midi backends.
Revision 228 - added a file to track the LilyPond version that HNotate targets. This should have gone in with revision 227.
Revision 227 - some tidying up of HNotate. Moved the Utils.hs files out of the Abc, LilyPond and Midi backends.
Revision 228 - added a file to track the LilyPond version that HNotate targets. This should have gone in with revision 227.
Monday, August 11, 2008
HNotate and Bala
Copperbox revisions 224 and 225.
Revision 224 - the LilyPond renderer is now working to a degree. There is some problem with chords changing the octave step, and a lot of the code is now very messy having been ripped out of Bala.Perform and hacked to work in HNotate.
Revision 225 - set the executable flag on the repository version of runtests.sh
Revision 224 - the LilyPond renderer is now working to a degree. There is some problem with chords changing the octave step, and a lot of the code is now very messy having been ripped out of Bala.Perform and hacked to work in HNotate.
Revision 225 - set the executable flag on the repository version of runtests.sh
Sunday, August 10, 2008
HNotate
Copperbox revision 222.
I've changed the Midi renderer to return parts of a Midi file rather than a completely rendered file.
However the parts are merged together to make a track is now under user control - the user supplies a function of type MidiSystem (i.e. PartMidiFile -> MidiFile) that gets called at the end of the rendering process knitting the parts together.
The LilyPond and Abc renderers will be changed to use this mechanism.
I've changed the Midi renderer to return parts of a Midi file rather than a completely rendered file.
However the parts are merged together to make a track is now under user control - the user supplies a function of type MidiSystem (i.e. PartMidiFile -> MidiFile) that gets called at the end of the rendering process knitting the parts together.
The LilyPond and Abc renderers will be changed to use this mechanism.
HNotate
Copperbox revision 221.
I've added a new operator to the print representations in HNotate - (<+<).
It's a type restricted version of mappend and it allows parameterized sequences to be built. Previously holes in sequences had to be one element because they could only be built with the addto operator (+++), now holes can themselves be sequences. This will allow HNotate LilyPond to append the notelist it produces to a user supplied initial block that contains key signature, time signature etc.
Disappointingly, these four lines of code (one for the type class, one for the fixity declaration, one for the type signature and one for the implementation) have taken four days work. I convinced myself early on that the current representation wasn't suitable and I'd have to go to something more directly compositional like the Wash HTML representation, then spent a lot of time getting lost.
I've added a new operator to the print representations in HNotate - (<+<).
It's a type restricted version of mappend and it allows parameterized sequences to be built. Previously holes in sequences had to be one element because they could only be built with the addto operator (+++), now holes can themselves be sequences. This will allow HNotate LilyPond to append the notelist it produces to a user supplied initial block that contains key signature, time signature etc.
Disappointingly, these four lines of code (one for the type class, one for the fixity declaration, one for the type signature and one for the implementation) have taken four days work. I convinced myself early on that the current representation wasn't suitable and I'd have to go to something more directly compositional like the Wash HTML representation, then spent a lot of time getting lost.
Tuesday, August 5, 2008
HNotate
Copperbox revision 220.
I've tidied up the phantom type layer for the Abc and LilyPond pretty printers. The 'Skeleton Doc' has gone and both libs now share the same code for appending and attributing elements.
This removes one of the 'sore thumbs' of HNotate, there are plenty of others as the code has been written quickly and revised often so is particularly ragged (and there are some holes where I haven't re-implemented features that were 'revised-out').
There are also some stumbling blocks that stop it being generally usefully, big ones are:
- What to do about 'systems' i.e. multiple staves - really the renderers should be open so the user can control this.
- What to do about glyphs that aren't notes or rests - currently there is no way to get say, expression marks, into the score output.
I've tidied up the phantom type layer for the Abc and LilyPond pretty printers. The 'Skeleton Doc' has gone and both libs now share the same code for appending and attributing elements.
This removes one of the 'sore thumbs' of HNotate, there are plenty of others as the code has been written quickly and revised often so is particularly ragged (and there are some holes where I haven't re-implemented features that were 'revised-out').
There are also some stumbling blocks that stop it being generally usefully, big ones are:
- What to do about 'systems' i.e. multiple staves - really the renderers should be open so the user can control this.
- What to do about glyphs that aren't notes or rests - currently there is no way to get say, expression marks, into the score output.
Bala
Copperbox revision 219.
Moved some of the dependencies from Bala to HNotate and ZMidi. I removed the original Midi library from Bala.Format.Midi, but there is still clutter there that needs removing once HNotate is properly capable of outputting LilyPond and Abc.
Moved some of the dependencies from Bala to HNotate and ZMidi. I removed the original Midi library from Bala.Format.Midi, but there is still clutter there that needs removing once HNotate is properly capable of outputting LilyPond and Abc.
Monday, August 4, 2008
ZMidi
Copperbox revision 217.
I've created a new package with the Midi library in Bala.Format - ZMidi. The code is essentially the same (some small clean ups) but it is no longer in the Bala.Format.Midi namespace - instead its plain ZMidi. This should ease making 'Perform' a standalone library.
Dependencies still reach into the BalaFormat.Midi library, so I won't be removing the original just yet.
I've created a new package with the Midi library in Bala.Format - ZMidi. The code is essentially the same (some small clean ups) but it is no longer in the Bala.Format.Midi namespace - instead its plain ZMidi. This should ease making 'Perform' a standalone library.
Dependencies still reach into the BalaFormat.Midi library, so I won't be removing the original just yet.
Sunday, August 3, 2008
Bala
Copperbox revisions 215 & 216.
Revision 215 - a substantial amount of changes as I'm working towards making the Perform modules a standalone library. Particular I've added minimal data types for pitch and duration - this has simplified the internals of the library quite a lot as it is no longer trying to be polymorphic on external pitch and duration representations.
Also I've move the Score representation from Format into Perform, at some point I'll do the same with the pretty printers for Abc and LilyPond in Format/Output. The Midi library should probably be made into a separate package too.
Revision 216 - deletes some of the files that that revision 215 made redundant. For the time being there is still a copy of the Score library in Format but this will go when I've checked there are no references to it.
Revision 215 - a substantial amount of changes as I'm working towards making the Perform modules a standalone library. Particular I've added minimal data types for pitch and duration - this has simplified the internals of the library quite a lot as it is no longer trying to be polymorphic on external pitch and duration representations.
Also I've move the Score representation from Format into Perform, at some point I'll do the same with the pretty printers for Abc and LilyPond in Format/Output. The Midi library should probably be made into a separate package too.
Revision 216 - deletes some of the files that that revision 215 made redundant. For the time being there is still a copy of the Score library in Format but this will go when I've checked there are no references to it.
Bala
Copperbox revision 214.
I've now added a Midi backend, it is as capable as the original renderer (grace notes are still to do), but I think the design is better.
All the new backends have been written quickly to have something working, there's plenty of room for improvement.
I've now added a Midi backend, it is as capable as the original renderer (grace notes are still to do), but I think the design is better.
All the new backends have been written quickly to have something working, there's plenty of room for improvement.
Saturday, August 2, 2008
Bala
Copperbox revision 213.
I've resolved the problems with the Abc pretty printer that I let slip in in the last couple of commits. In short I changed the tune element to be header+body rather than a it being misnamed body within AbcInternals.hs, but didn't cascade the updates that this introduced properly.
I've resolved the problems with the Abc pretty printer that I let slip in in the last couple of commits. In short I changed the tune element to be header+body rather than a it being misnamed body within AbcInternals.hs, but didn't cascade the updates that this introduced properly.
Friday, August 1, 2008
Bala
Copperbox revision 211.
Some work on the Abc backend.
This is essentially a checkpoint commit - now that there are sets of datatypes for the different backends there is no need to have beaming elements in the ScScore datatypes (beaming is only relevant to Abc). So I'll remove them next.
Some work on the Abc backend.
This is essentially a checkpoint commit - now that there are sets of datatypes for the different backends there is no need to have beaming elements in the ScScore datatypes (beaming is only relevant to Abc). So I'll remove them next.
Bala
Copperbox revision 210.
Rather than use the 'Poly' Score datatypes, I've decided to define individual sets of data types for each backend (LyScoreDatatype.hs contains the LilyPond ones). This is to make some things more explicit - especially the type of a polyphonic segment - at the expense of generality.
Rather than use the 'Poly' Score datatypes, I've decided to define individual sets of data types for each backend (LyScoreDatatype.hs contains the LilyPond ones). This is to make some things more explicit - especially the type of a polyphonic segment - at the expense of generality.
Thursday, July 31, 2008
Wednesday, July 30, 2008
Bala
Copperbox revisions 207 & 208.
Revision 207 - more work towards viable support for polyphony. My current thinking is to sequence all the measures in a pending worklist (represented by the new ADT OnsetQueue) then regroup them into PolyUnits - polyphonic lines that are printed together on the same staff.
In Abc, a PolyUnit has to be a measure long and are represented by voice overlays. In LilyPond, a unit can be of variable length and a separated with the (\\) operator.
Revision 208 - all translation steps for scores now implemented in ToPolyScore. Currently it only translates into measure length 'PolyUnits'.
Revision 207 - more work towards viable support for polyphony. My current thinking is to sequence all the measures in a pending worklist (represented by the new ADT OnsetQueue) then regroup them into PolyUnits - polyphonic lines that are printed together on the same staff.
In Abc, a PolyUnit has to be a measure long and are represented by voice overlays. In LilyPond, a unit can be of variable length and a separated with the (\\) operator.
Revision 208 - all translation steps for scores now implemented in ToPolyScore. Currently it only translates into measure length 'PolyUnits'.
Tuesday, July 29, 2008
Bala
Copperbox revision 206.
There were problems with polyphony in the last commit that I didn't spot at the time - I've now improved things in the Score rendered but disabled polyphony in the LilyPond renderer.
I've added a LilyPond sample - polyphony.ly - which illustrates what the design choices are for the renderers.
There were problems with polyphony in the last commit that I didn't spot at the time - I've now improved things in the Score rendered but disabled polyphony in the LilyPond renderer.
I've added a LilyPond sample - polyphony.ly - which illustrates what the design choices are for the renderers.
Monday, July 28, 2008
Sunday, July 27, 2008
Bala
Copperbox revisions 202 & 203.
I've reorganized the Perform directory. The original code that worked in one step (EventTree -> Midi, EventTree -> LilyPond, ...) is now in the Original folder. The new code that will supersede it at some point is split into various folders.
I've reorganized the Perform directory. The original code that worked in one step (EventTree -> Midi, EventTree -> LilyPond, ...) is now in the Original folder. The new code that will supersede it at some point is split into various folders.
Saturday, July 26, 2008
Bala
Copperbox revision 201.
I've added the new LilyPond backend. It takes an ScScore syntax tree and outputs it as LilyPond.
Although it is incomplete at present - it doesn't yet render polyphony, I think it does live up to the expectation that generating LilyPond in two steps (EventTree -> Score, Score -> LilyPond) is more comprehensible than EventTree -> LilyPond.
I've added the new LilyPond backend. It takes an ScScore syntax tree and outputs it as LilyPond.
Although it is incomplete at present - it doesn't yet render polyphony, I think it does live up to the expectation that generating LilyPond in two steps (EventTree -> Score, Score -> LilyPond) is more comprehensible than EventTree -> LilyPond.
Copperbox at 200
Copperbox revision 200.
I've closed down Cil Pickle my other Google project and moved the code into Copperbox.
It's a dead end as far as I'm concerned, but the code might as well 'live on' - if it cautions someone else about going down that particular dead-end that it will have had a useful afterlife.
I've closed down Cil Pickle my other Google project and moved the code into Copperbox.
It's a dead end as far as I'm concerned, but the code might as well 'live on' - if it cautions someone else about going down that particular dead-end that it will have had a useful afterlife.
Bala
Copperbox revision 199.
Major renaming in the Output modules LilyPondInternals and AbcInternals. I was getting frustrated with qualified imports and name clashes so I've given the types in both modules rather long winded names. The naming should now be more systematic as well.
Major renaming in the Output modules LilyPondInternals and AbcInternals. I was getting frustrated with qualified imports and name clashes so I've given the types in both modules rather long winded names. The naming should now be more systematic as well.
Friday, July 25, 2008
Bala
Copperbox revision 197.
Small changes - added a new smart constructor to Duration that builds a Duration from a Ratio (accounting for dotting if it can).
Some changes to the Score representation - this will probably change quite a bit with the next round of work, so I am check-pointing it now.
Small changes - added a new smart constructor to Duration that builds a Duration from a Ratio (accounting for dotting if it can).
Some changes to the Score representation - this will probably change quite a bit with the next round of work, so I am check-pointing it now.
Thursday, July 24, 2008
Wednesday, July 23, 2008
Bala
Copperbox revision 194.
I've added a new representation Score. This is an experiment to see whether it makes rendering simpler.
Score is an explicit intermediate form (like GHC's core or Yhc.Core). My idea is that it will be easier to render to this - sort out things like barlines and staff grouping, then render to Abc or LilyPond as a last step hopefully without much processing.
Also added a couple more samples. One is a tab that can be read by the TabApp - TabApp works as a proof of concept unfortunately the ouput isn't pretty.
I've added a new representation Score. This is an experiment to see whether it makes rendering simpler.
Score is an explicit intermediate form (like GHC's core or Yhc.Core). My idea is that it will be easier to render to this - sort out things like barlines and staff grouping, then render to Abc or LilyPond as a last step hopefully without much processing.
Also added a couple more samples. One is a tab that can be read by the TabApp - TabApp works as a proof of concept unfortunately the ouput isn't pretty.
Tuesday, July 22, 2008
Bala
Copperbox revision 193.
The Midi, Abc and LilyPond renderers now all uses a new Monad PerformM (which is a wrapper over StateT over Reader).
This means that the state (e.g bar count in Abc as the rendering progresses) is now separate from the initial configuration supplied by the user (e.g. default note length for rendering Abc) .
The Midi, Abc and LilyPond renderers now all uses a new Monad PerformM (which is a wrapper over StateT over Reader).
This means that the state (e.g bar count in Abc as the rendering progresses) is now separate from the initial configuration supplied by the user (e.g. default note length for rendering Abc) .
Bala
Copperbox revision 192.
Various minor changes - a checkpoint commit before I do some more revision on the renderers.
Added more named elements to Pitch - PitchNames i.e. pitches without octave information. These are needed for Keys which I've added to Scale. I'm not sure that the Key datatype in Scale is the right representation, but the named elements (c_major, d_sharp_minor, etc) are very useful to have as defaults to pass to the renderers.
Various minor changes - a checkpoint commit before I do some more revision on the renderers.
Added more named elements to Pitch - PitchNames i.e. pitches without octave information. These are needed for Keys which I've added to Scale. I'm not sure that the Key datatype in Scale is the right representation, but the named elements (c_major, d_sharp_minor, etc) are very useful to have as defaults to pass to the renderers.
Monday, July 21, 2008
Bala
Copperbox revision 191.
Added new examples in the file BalaExamples/Trees.hs.
These examples should exercise all the capabilities of the EventTree and Performance (list of EventTrees) datatypes - sequential notes, chords, grace notes, mutliple staff 'parallelism' and same staff parallelism.
Quite a bit is still to be done in the renderers - Midi doesn't do grace notes, Abc doesn't do parallelism.
Also I've made the examples and runtest.sh test script generate their output in the folder BalaExamples/out - things were getting messy.
Added new examples in the file BalaExamples/Trees.hs.
These examples should exercise all the capabilities of the EventTree and Performance (list of EventTrees) datatypes - sequential notes, chords, grace notes, mutliple staff 'parallelism' and same staff parallelism.
Quite a bit is still to be done in the renderers - Midi doesn't do grace notes, Abc doesn't do parallelism.
Also I've made the examples and runtest.sh test script generate their output in the folder BalaExamples/out - things were getting messy.
Bala
Copperbox revision 190.
I've changed the renderers to use the PPrint combinator rather than <+>. I hadn't realized <+> stops line breaking and as I was folding long chains with it, I was getting very long lines.
Ideally I should print out notes in groups corresponding to bars - this is partially done (well hacked together) for Abc, but I should do it for LilyPond as well. It would make the output a lot more readable.
Also deleted the old PreformMidi module from the Midi modules - its replacement is in the Perform directory.
I've changed the renderers to use the PPrint combinator rather than <+>. I hadn't realized <+> stops line breaking and as I was folding long chains with it, I was getting very long lines.
Ideally I should print out notes in groups corresponding to bars - this is partially done (well hacked together) for Abc, but I should do it for LilyPond as well. It would make the output a lot more readable.
Also deleted the old PreformMidi module from the Midi modules - its replacement is in the Perform directory.
Sunday, July 20, 2008
Bala
Copperbox revision 187.
Big improvements to Abc and LilyPond output. Now, all three output formats Abc, LilyPond and Midi share the same typeclass 'Perform' for interpreting pitches and rests.
Abc - barline handling is now implemented in the Abc output (Abc needs manual placement of barlines which is an unfortunate complication).
LilyPond - chords now work better with relative pitch naming.
Copperbox revision 188.
Deleted the file EventQueue.hs - it should have been deleted before but it was mysteriously hanging on at the top level of the repository.
Big improvements to Abc and LilyPond output. Now, all three output formats Abc, LilyPond and Midi share the same typeclass 'Perform' for interpreting pitches and rests.
Abc - barline handling is now implemented in the Abc output (Abc needs manual placement of barlines which is an unfortunate complication).
LilyPond - chords now work better with relative pitch naming.
Copperbox revision 188.
Deleted the file EventQueue.hs - it should have been deleted before but it was mysteriously hanging on at the top level of the repository.
Saturday, July 19, 2008
Bala
Copperbox revisions 183 & 184.
More tidying - moved the import modules for Bala.Base and Format.Midi one level higher up in the folder hierarchy so they can be imported without double barrelled names. Revision 183 missed one of the cascade changes that this brought about so that was corrected in 184.
More tidying - moved the import modules for Bala.Base and Format.Midi one level higher up in the folder hierarchy so they can be imported without double barrelled names. Revision 183 missed one of the cascade changes that this brought about so that was corrected in 184.
Friday, July 18, 2008
Thursday, July 17, 2008
Bala
Copperbox revision 179.
Added a new output representation for Abc. This one is patterned after the Text.XHTML library in the hierarchical libraries - with a phantom type layer to have comparable 'typefulness' to the SymAbc representation.
Unlike SymAbc it doesn't generate abstract syntax, instead it goes almost* straight to the pretty printers Doc type. While this makes it more limited than SymAbc it does represent Abc with workable types - SymAbc's types were too big to program with.
--
* The new library has a skeleton syntax layer above the Doc type, but this seems unnecessary and may be removed in due course.
Added a new output representation for Abc. This one is patterned after the Text.XHTML library in the hierarchical libraries - with a phantom type layer to have comparable 'typefulness' to the SymAbc representation.
Unlike SymAbc it doesn't generate abstract syntax, instead it goes almost* straight to the pretty printers Doc type. While this makes it more limited than SymAbc it does represent Abc with workable types - SymAbc's types were too big to program with.
--
* The new library has a skeleton syntax layer above the Doc type, but this seems unnecessary and may be removed in due course.
Sunday, July 13, 2008
Saturday, July 12, 2008
Bala
Copperbox revision 176.
Mostly changes to the SymAbc representation. The datatypes module is now organised following the categories of the Abc standard 2.0 draft, although for my purposes I'm only interested in the parts that are readily supported - plus voice overlays which are supported in abcm2ps but note abc2ps. Voice overlays are necessary to get a equivalent to LilyPond's single staff polyphony.
The Abc renderer hasn't progressed much as Abc format needs to put in barlines (LilyPond sets the by default). I'll have to work out what to do for this.
Mostly changes to the SymAbc representation. The datatypes module is now organised following the categories of the Abc standard 2.0 draft, although for my purposes I'm only interested in the parts that are readily supported - plus voice overlays which are supported in abcm2ps but note abc2ps. Voice overlays are necessary to get a equivalent to LilyPond's single staff polyphony.
The Abc renderer hasn't progressed much as Abc format needs to put in barlines (LilyPond sets the by default). I'll have to work out what to do for this.
Friday, July 11, 2008
Thursday, July 10, 2008
Bala
Copperbox revision 174.
The example tune Bulgarian6 now outputs a LilyPond score along with a MIDI file.
The number of Field classes in SymAbc has been reduced. Having lots of classes means lots of constraints in type signatures, so reducing the number of them is worthwhile.
The example tune Bulgarian6 now outputs a LilyPond score along with a MIDI file.
The number of Field classes in SymAbc has been reduced. Having lots of classes means lots of constraints in type signatures, so reducing the number of them is worthwhile.
Bala
Copperbox revision 173.
Changed the EventTree representation from a snoc list that was counter-intuitive to traverse to a sequence with 'grammatical elements' . An explanation is probably clearest with examples:
A chord <> - this is a sequence of five elements (<) is BeginPar ('begin parallel' - chords are parallel sequences of notes, (>) is EndPar.
Similary the note c with two grace notes before it is - { e d } c. ({) is BeginPre - 'begin prefix' - grace notes are played respective to the note they precede rather than to global time, and (}) is EndPre.
Left to right traversal of this representation is much more obvious, plus because it is built on Sequence from the hierarchical libraries adding to the right end is supported.
Changed the EventTree representation from a snoc list that was counter-intuitive to traverse to a sequence with 'grammatical elements' . An explanation is probably clearest with examples:
A chord <> - this is a sequence of five elements (<) is BeginPar ('begin parallel' - chords are parallel sequences of notes, (>) is EndPar.
Similary the note c with two grace notes before it is - { e d } c. ({) is BeginPre - 'begin prefix' - grace notes are played respective to the note they precede rather than to global time, and (}) is EndPre.
Left to right traversal of this representation is much more obvious, plus because it is built on Sequence from the hierarchical libraries adding to the right end is supported.
Wednesday, July 9, 2008
Bala
Copperbox revision 172.
I've changed the Sym representations so that context is only a parameter on lists and not all the elements. This reduces some of the burden of the type signatures. Also I've done some renaming - the prefix Sym on the classes has been shortened to just C.
I've changed the Sym representations so that context is only a parameter on lists and not all the elements. This reduces some of the burden of the type signatures. Also I've done some renaming - the prefix Sym on the classes has been shortened to just C.
Tuesday, July 8, 2008
Bala
Copperbox revision 171.
The LilyPond renderer can now do durations and rests. That's the good news.
The bad news is that it needs a very silly type class - LyRenderable - to help it interpret rests on notes in the input tree. How to interpret the input tree in a satisfactory way is going to take some thought.
Also the representation of durations in Bala.Base has changed - dotting is now cached which means that double dotting works as expected:
dot $ dot quarter == dotdot quarter
The LilyPond renderer can now do durations and rests. That's the good news.
The bad news is that it needs a very silly type class - LyRenderable - to help it interpret rests on notes in the input tree. How to interpret the input tree in a satisfactory way is going to take some thought.
Also the representation of durations in Bala.Base has changed - dotting is now cached which means that double dotting works as expected:
dot $ dot quarter == dotdot quarter
Monday, July 7, 2008
Sunday, July 6, 2008
Friday, July 4, 2008
Bala
Copperbox revision 167.
Updated Duration - it is now a newtype and not a type synonym. Also there was a name clash with Meter which also defined a Duration type- Meter's has been removed. Meter itself is pretty run down and is due for some work (or removal).
The textual representation of MIDI used by MidiPrint now tracks global (cumulative) time rather than just delta time. While this information doesn't appear in MIDI files it is simple to synthesize and obviously useful.
Updated Duration - it is now a newtype and not a type synonym. Also there was a name clash with Meter which also defined a Duration type- Meter's has been removed. Meter itself is pretty run down and is due for some work (or removal).
The textual representation of MIDI used by MidiPrint now tracks global (cumulative) time rather than just delta time. While this information doesn't appear in MIDI files it is simple to synthesize and obviously useful.
Thursday, July 3, 2008
Bala
Copperbox revision 166.
Added a new module to Bala.Base - Duration.
Durations are just the `Ratio` type. The module exports named instances whole, half, quarter, etc. (American naming) and breve, minim, crochet, etc. (English naming), plus some operations dotting and calculating time values.
Added a new module to Bala.Base - Duration.
Durations are just the `Ratio` type. The module exports named instances whole, half, quarter, etc. (American naming) and breve, minim, crochet, etc. (English naming), plus some operations dotting and calculating time values.
Bala
Copperbox revision 165.
Improvements to the MIDI library. The Data.Binary parser is now essentially the same as the Parsec parser, they just use different primitives. Haddock documentation has been added to the datatypes.
From being an ugly duckling, the code in the MIDI library now at least looks polished.
Improvements to the MIDI library. The Data.Binary parser is now essentially the same as the Parsec parser, they just use different primitives. Haddock documentation has been added to the datatypes.
From being an ugly duckling, the code in the MIDI library now at least looks polished.
Wednesday, July 2, 2008
Bala
Copperbox revision 164.
Added an alternative MIDI parser written with Parsec rather than Data.Binary. It is much cleaner than the existing parser, which got rather messy as I hunted a nasty bug.
Renamed OnsetQueue to EventQueue - the queue should track 'global time' and not 'onset time' so the previous name was misleading.
Added an alternative MIDI parser written with Parsec rather than Data.Binary. It is much cleaner than the existing parser, which got rather messy as I hunted a nasty bug.
Renamed OnsetQueue to EventQueue - the queue should track 'global time' and not 'onset time' so the previous name was misleading.
Bala
Copperbox revision 163.
Added a new module OnsetQueue to Bala.Perform.
This is part of the work I've been doing on MIDI output. OnsetQueue represents events to be added to the MIDI stream at a future time. For example, if you have a high level representation of a note with a duration - if you render it to MIDI it will become a note-on at the current time onset, plus a note-off some time later. The onset queue stores these pending events to be queued later.
At present it doesn't recalibrate the onset time of the still outstanding events on a dequeue (the `upto` operation), this is most-likely wrong and no doubt will be apparent when I get more of the MIDI output code running.
Added a new module OnsetQueue to Bala.Perform.
This is part of the work I've been doing on MIDI output. OnsetQueue represents events to be added to the MIDI stream at a future time. For example, if you have a high level representation of a note with a duration - if you render it to MIDI it will become a note-on at the current time onset, plus a note-off some time later. The onset queue stores these pending events to be queued later.
At present it doesn't recalibrate the onset time of the still outstanding events on a dequeue (the `upto` operation), this is most-likely wrong and no doubt will be apparent when I get more of the MIDI output code running.
Monday, June 30, 2008
Sunday, June 29, 2008
Bala
Copperbox revisions 160 & 161.
Revision 160
More tidying up in Bala.Base especially the interval module. I'm still not happy with the interval module, but this check in does improve it.
I've started moving named elements into their respective modules (pitches in Pitch, intervals in Interval), the NamedElements module will be removed some time soon.
Revision 161
Chord was broken in revision 160 - a judicious use of undefined. It is back working now, though it needs a lot of improvement.
Revision 160
More tidying up in Bala.Base especially the interval module. I'm still not happy with the interval module, but this check in does improve it.
I've started moving named elements into their respective modules (pitches in Pitch, intervals in Interval), the NamedElements module will be removed some time soon.
Revision 161
Chord was broken in revision 160 - a judicious use of undefined. It is back working now, though it needs a lot of improvement.
Saturday, June 28, 2008
Friday, June 27, 2008
Bala
Copperbox revision 156 & 157.
Revision 156
Pitch is now an opaque type - its constructor/destructor is not exported outside the Pitch module (the Pitch module is the new name for the PitchRep module). This is so that consistency between the pitch name (pitch letter and accidental) and semitone count can be ensured.
This has caused a cascade of changes as other modules can no longer pattern match on Pitch. Although everything should compile, there will be quite a lot of tidying up still to do as I look for code that is now redundant.
Also the tests have been made to run again - they had been left in the cold while I had been working on SymLilyPond.
Revision 157
Changes to Interval - the arith_dist field label has been changed to interval_type.
Revision 156
Pitch is now an opaque type - its constructor/destructor is not exported outside the Pitch module (the Pitch module is the new name for the PitchRep module). This is so that consistency between the pitch name (pitch letter and accidental) and semitone count can be ensured.
This has caused a cascade of changes as other modules can no longer pattern match on Pitch. Although everything should compile, there will be quite a lot of tidying up still to do as I look for code that is now redundant.
Also the tests have been made to run again - they had been left in the cold while I had been working on SymLilyPond.
Revision 157
Changes to Interval - the arith_dist field label has been changed to interval_type.
Thursday, June 26, 2008
Bala
Copperbox revision 155.
A couple of changes to SymLilyPond and some restructuring in Bala.Base.
I've limited accidentals to natural, sharp, flat, double sharp and double flat. Plus I've moved some of the pitch operations inside the PitchRep module as I think making the Pitch datatype opaque would be beneficial (so it can track the invariants it has on semitone 'measure').
A couple of changes to SymLilyPond and some restructuring in Bala.Base.
I've limited accidentals to natural, sharp, flat, double sharp and double flat. Plus I've moved some of the pitch operations inside the PitchRep module as I think making the Pitch datatype opaque would be beneficial (so it can track the invariants it has on semitone 'measure').
Wednesday, June 25, 2008
Bala
Copperbox revision 154.
A rethink of attributes for SymLilyPond and SymAbc. Attributes are no longer a 'continuation' (repr (a ctx) -> repr (a ctx)) over an element, they are now just elements. To establish that one element is a attribute of another element there is a empty class:
class Attribute elt attrib
Declaring instances of Attribute will put an attribute relation on the two types, then attribution can be done with the SymAttr class or its helper (#@).
Pleasantly this is both simpler and more useful that the continuation version.
A rethink of attributes for SymLilyPond and SymAbc. Attributes are no longer a 'continuation' (repr (a ctx) -> repr (a ctx)) over an element, they are now just elements. To establish that one element is a attribute of another element there is a empty class:
class Attribute elt attrib
Declaring instances of Attribute will put an attribute relation on the two types, then attribution can be done with the SymAttr class or its helper (#@).
Pleasantly this is both simpler and more useful that the continuation version.
Tuesday, June 24, 2008
Bala
Copperbox revision 153.
Some more work on SymLilyPond - vertical placement isn't right, so this check in is all the current changes before I put some more work into it.
Vertical placement should be an attribute of an attribute, because only certain attributes can have there placement altered:
- A note's finger position could be above it or below it, it is an extra glyph (a number) printed with the note.
- A note's duration effects how the note is printed (solid, with stem...) but it prints a singular glyph so can't have its placement altered.
Currently SymLilyPond lets any attribute get a vertical placement. This is wrong - outputting a note that has been given a vertical placing for it's duration turns the duration into a fingering. I'll have to do some thinking about this.
Also with this checking I've added some handwritten LilyPond examples so I can compare them to which the output that SymLilyPond produces.
Some more work on SymLilyPond - vertical placement isn't right, so this check in is all the current changes before I put some more work into it.
Vertical placement should be an attribute of an attribute, because only certain attributes can have there placement altered:
- A note's finger position could be above it or below it, it is an extra glyph (a number) printed with the note.
- A note's duration effects how the note is printed (solid, with stem...) but it prints a singular glyph so can't have its placement altered.
Currently SymLilyPond lets any attribute get a vertical placement. This is wrong - outputting a note that has been given a vertical placing for it's duration turns the duration into a fingering. I'll have to do some thinking about this.
Also with this checking I've added some handwritten LilyPond examples so I can compare them to which the output that SymLilyPond produces.
Monday, June 23, 2008
Sunday, June 22, 2008
Bala
Copperbox revision 151.
A new implementation of concatenation as a snoc list. This should be used to replace old version in due course. I've left old version in the code for the time being as there aren't any name clashes, though it would be nice to reclaim the (+++) operator.
A useful property of the snoc list version is that the 'nil' type (cNil) is parameterized by its context (the old version had no nil representation). This puts the type checker to work for us, elementCtx and toplevelCtx are differently typed nils:
pitches_001 () = elementCtx `cSnoc` (note _g) `cSnoc` (note _c)
pitches_002 () = toplevelCtx `cSnoc` (note _g) `cSnoc` (note _c)
pitches_001 compiles because notes are at the element context, but pitches_002 fails as notes can't exist at the toplevel context.
A new implementation of concatenation as a snoc list. This should be used to replace old version in due course. I've left old version in the code for the time being as there aren't any name clashes, though it would be nice to reclaim the (+++) operator.
A useful property of the snoc list version is that the 'nil' type (cNil) is parameterized by its context (the old version had no nil representation). This puts the type checker to work for us, elementCtx and toplevelCtx are differently typed nils:
pitches_001 () = elementCtx `cSnoc` (note _g) `cSnoc` (note _c)
pitches_002 () = toplevelCtx `cSnoc` (note _g) `cSnoc` (note _c)
pitches_001 compiles because notes are at the element context, but pitches_002 fails as notes can't exist at the toplevel context.
Bala
Copperbox revision 150.
More work on the SymLilyPond parser.
Yesterdays example for parsing with attributes didn't work when I got round to testing it, chaining attributes with bind (>>=) forces them to be present when we want them to be optional:
pitchA = pPitch >>= pAccidental >>= pMicroTone >>= pOctaveSpec
The new revision uses an alternative to bind (##) that allows the parse to be optional:
pitchA = lexeme $ pPitch ## pAccidental ## pMicroTone ## pOctaveSpec
The parser currently falls down on concatenation - i.e. it cannot handle lists of notes inside a block. I suspect that I'll have to rework how concatenation is handled with in the final-tagless datatypes.
More work on the SymLilyPond parser.
Yesterdays example for parsing with attributes didn't work when I got round to testing it, chaining attributes with bind (>>=) forces them to be present when we want them to be optional:
pitchA = pPitch >>= pAccidental >>= pMicroTone >>= pOctaveSpec
The new revision uses an alternative to bind (##) that allows the parse to be optional:
pitchA = lexeme $ pPitch ## pAccidental ## pMicroTone ## pOctaveSpec
The parser currently falls down on concatenation - i.e. it cannot handle lists of notes inside a block. I suspect that I'll have to rework how concatenation is handled with in the final-tagless datatypes.
Saturday, June 21, 2008
Bala
Copperbox revision 149.
Tentative work on the SymLilyPond parser - enough to parse pitch with some attributes (accidental, octave spec).
Unlike the pretty printer which is open to adding new elements, I think the parser will have to be 'knot-tied'. For example, the parser pitchA (pitch with attributes) explicitly lists which attributes it will parse and their order:
pitchA = pPitch >>= pAccidental >>= pMicroTone >>= pOctaveSpec
Naturally, all attributes are optional - but they still need to be enumerated in one place in advance.
Tentative work on the SymLilyPond parser - enough to parse pitch with some attributes (accidental, octave spec).
Unlike the pretty printer which is open to adding new elements, I think the parser will have to be 'knot-tied'. For example, the parser pitchA (pitch with attributes) explicitly lists which attributes it will parse and their order:
pitchA = pPitch >>= pAccidental >>= pMicroTone >>= pOctaveSpec
Naturally, all attributes are optional - but they still need to be enumerated in one place in advance.
Subscribe to:
Posts (Atom)
Blog Archive
-
▼
2008
(284)
-
▼
December
(28)
- OpenVG binding
- OpenVG and ZParse
- Bala and TabApp
- ZMidi
- HNotate, Bala and TabApp
- HNotate
- HNotate
- HNotate
- HNotate, Bala and ZMidi
- GreyFold
- GreyFold
- HNotate
- HNotate
- HNotate and Bala
- HNotate
- HNotate
- HNotate
- HNotate, Bala and TabApp
- HNotate
- HNotate
- HNotate and Bala
- HNotate
- HNotate and Bala
- HNotate
- HNotate
- HNotate
- HNotate
- HNotate
-
►
November
(55)
- HNotate
- HNotate
- HNotate
- Bala
- Bala
- Bala
- HNotate and Bala
- Bala, HNotate and ZMidi
- Bala
- Bala and ZMidi
- Bala
- Bala
- Bala
- Bala
- Bala
- Bala
- Bala
- Bala and HNotate
- Bala and HNotate
- Bala and HNotate
- HNotate and Bala
- HNotate, Bala and ZMidi
- HNotate
- ZMidi
- ZMidi
- Bala
- ZMidi
- Bala, HNotate and ZMidi
- ZMidi
- Bala and HNotate
- Bala and HNotate
- HNotate
- HNotate
- HNotate
- Bala and HNotate
- HNotate
- HNotate
- HNotate
- HNotate
- HNotate
- Bala and HNotate
- Bala
- Bala
- Bala and HNotate
- Bala
- HNotate
- HNotate
- ZMidi
- ZMidi
- HNotate
- HNotate
- HNotate
- HNotate and Bala
- Bala
- HNotate and Bala
-
▼
December
(28)
About Me
- Stephen Tetley
- Disambiguating biog as there are a few Stephen Tetley's in the world. I'm neither a cage fighter or yachtsman. I studied Fine Art in the nineties (foundation Bradford 1992, degree Cheltenham 1992 - 95) then Computing part-time at Leeds Met graduating in 2003. I'm the Stephen Tetley on Haskell Cafe and Stackoverflow.