Sunday, November 30, 2008

HNotate

Copperbox revision 361.

I've added support for handling nplets i.e. n-ary tuplets. Also, I realized that you can run ghci with -Wall so I've corrected a lot of warnings (generally I only run the code in Copperbox with ghci and never actually compile it).

HNotate

Copperbox revision 360.

I've changed the names of the data types Tile and Glyph to Grouping and Atom.

Saturday, November 29, 2008

HNotate

Copperbox revision 359.

Removed the function putBack from ParserBase - it was replicating the Parsec function lookAhead.

Also minor tidying up in BuildNoteList - added a function to number sequences and took out the folds that were doing this.

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.

Thursday, November 27, 2008

Bala

Copperbox revision 357.

Tidy up of the Bala examples as Samba Baiao was unwittingly broken.

Bala

Copperbox revision 356.

I've tidied up the drum notation output code, and added support for another LilyPond percussion style - #timbales-style.

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.

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.

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).

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.

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.

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).

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.

Saturday, November 22, 2008

Bala

Copperbox revision 348.

I've reworked some of the code for time signature and meter handling, taking it out of the Duration module and putting it in a new module Metrical.

Friday, November 21, 2008

Bala

Copperbox revision 347.

I've added a new module Motivic to Bala that includes the retrograde traversal I commented on yesterday, and a couple of others for motivic / melodic development.

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:


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.

Bala

Copperbox revisions 344 & 345.

I've renamed Structural2 to Structural (and so replaced the original Structural module). Also I've deleted some out-of-date files, and got the Scales demo to work again.

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.

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...

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:

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.

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

Copperbox revision 338.

I've moved the RhythmicValue typeclass into the Duration module, so it can be seen in Bala.

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.

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.

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.

Sunday, November 16, 2008

ZMidi

Copperbox revision 334.

I've now included Construction in ZMidi module interface - it seems to have proved its worth. Also I've added a couple of output commands.

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.

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.

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.

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...

HNotate

Copperbox revision 328.

I've revised the anacrusis handling code in BuilNoteList to make it more straightforward.

HNotate

Copperbox revision 327.

The partitionGVO function in HNotate now uses the new sectioning functions.

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.

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.

Wednesday, November 12, 2008

HNotate

Copperbox revision 324.

More work on the output combinators for Abc and LilyPond.

Tuesday, November 11, 2008

HNotate

Copperbox revision 323.

I've added initial Abc output via document combinators and fixed a bug in the Document pretty printer where it got the indent level wrong after a line break.

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.

HNotate

Copperbox revision 320.

I've now implemented a working indent combinator for the internal pretty print library.

Sunday, November 9, 2008

HNotate

Copperbox revision 319.

I've added a tempo field to HNotate's rendering environment. This is used by the Midi backend to control the tempo field in the generated Midi file.

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.

Saturday, November 8, 2008

Bala

Copperbox revision 317.

More work to simplify the Pitch module. Sorted out simple pitch relabelling, so now the scales in the DemoScales example should generate sensible note names.

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.

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.

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...

Thursday, November 6, 2008

HNotate

Copperbox revision 312.

I've implemented a more general top-level function to generate Midi. You can specify which event lists in a system to render, and whether you want the played in parallel (polyphony) or sequentially.

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.

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.

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.

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).

HNotate

Copperbox revision 307.

HNotate can now output LilyPond drum scores.

I'm pleased about this - it seems like a long time since I was adding features rather than debugging and reworking.

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.

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.

Bala

Copperbox revision 304.

Some changes to the directory structure to put the Bala modules into a better hierarchy. Helper files to get Haddock 2.2.2 to work. Minor changes to Bala - the Num instance for pitch has been reimplemented.

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.

Blog Archive

About Me

My photo
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.