Copperbox revision 3064.
I've updated OpenVGRaw and OpenVG so they work with GHC 7.6.3 and Haskell Platform 2013.2.0.0 - whatever code had got "lost" in the missing OpenVGRaw-0.3.0 release evidently hasn't been significant.
It's nice that Tensor and StateVar have been folded back into the OpenGL package so now OpenVG is compatible with the OpenGL release in the Platform.
A downside - the demo TestVgu.hs works via runhaskell but I can't seem to compile it with GHC.
I'll look towards making a release tomorrow (digging through OpenVG wasn't what I planned to do on New Years Eve).
Tuesday, December 31, 2013
OpenVGRaw
Copperbox revision 3063.
Possibly I've updated OpenVGRaw to work with the latest GHC, but I'm a bit concerned that the code has got out of sync. It doesn't help that I have to compile OpenVGRaw with MinGW/MSYS when mostly I use Cygwin, or that I seem to have two working directories for the code...
... or that it seems like I never released 0.3.0 (made in 2012) to Hackage.
Clearly I've messed up somewhere.
Possibly I've updated OpenVGRaw to work with the latest GHC, but I'm a bit concerned that the code has got out of sync. It doesn't help that I have to compile OpenVGRaw with MinGW/MSYS when mostly I use Cygwin, or that I seem to have two working directories for the code...
... or that it seems like I never released 0.3.0 (made in 2012) to Hackage.
Clearly I've messed up somewhere.
zmidi-core-0.7.0
Copperbox revision 3062.
New release of zmidi-core for Hackage - 0.7.0. Salient features:
Support for SysEx escape and SysEx continuation data.
Alternative pretty printers - csv and ASCII in the style of the Beyond MIDI book.
Minor improvements - (cough) apparently one of the demos didn't work in the last release. ChannelPrefix constructor now takes a single argument (channel).
New release of zmidi-core for Hackage - 0.7.0. Salient features:
Support for SysEx escape and SysEx continuation data.
Alternative pretty printers - csv and ASCII in the style of the Beyond MIDI book.
Minor improvements - (cough) apparently one of the demos didn't work in the last release. ChannelPrefix constructor now takes a single argument (channel).
Monday, December 30, 2013
zmidi-core
Copperbox revision 3061.
I've completed Haddock docs for all the exposed modules - coverage is 100%.
Tomorrow I'll make a new release for Hackage.
I've completed Haddock docs for all the exposed modules - coverage is 100%.
Tomorrow I'll make a new release for Hackage.
zmidi-core
Copperbox revision 3060.
I've implemented the ASCII pretty printer based on the output listings in the Beyond MIDI book. The handling of Elapsed Time is simpler (though less satisfying).
Also I've corrected the ChannelPrefix constructor of MidiMetaEvent to only have a single field - channel number.
I think the code is nearly ready for a Hackage release but it needs some more Haddock docs and testing.
I've implemented the ASCII pretty printer based on the output listings in the Beyond MIDI book. The handling of Elapsed Time is simpler (though less satisfying).
Also I've corrected the ChannelPrefix constructor of MidiMetaEvent to only have a single field - channel number.
I think the code is nearly ready for a Hackage release but it needs some more Haddock docs and testing.
Sunday, December 29, 2013
zmidi-core
Copperbox revision 3059.
I've implemented the CSV pretty printer, plus I've extended the MidiPrint sample application to use GetOpt so it can choose between CSV, "original" and "ascii" (based on Beyond MIDI). "Ascii" is not yet implemented.
I've implemented the CSV pretty printer, plus I've extended the MidiPrint sample application to use GetOpt so it can choose between CSV, "original" and "ascii" (based on Beyond MIDI). "Ascii" is not yet implemented.
Saturday, December 28, 2013
zmidi-core
Copperbox revision 3058.
I've changed the table monad adding tracking for delta time and track number, plus I've removed the transformer version.
I've also added initial work on a Csv printer (inspired by midicsv) and a more user-friendly Ascii pretty printer (inspired by sample output in the Beyond MIDI book).
I've changed the table monad adding tracking for delta time and track number, plus I've removed the transformer version.
I've also added initial work on a Csv printer (inspired by midicsv) and a more user-friendly Ascii pretty printer (inspired by sample output in the Beyond MIDI book).
Friday, December 27, 2013
zmidi-core
Copperbox revision 3057.
I've moved the utility code from ZMidi.Core.Pretty into a new module ZMidi.Core.Pretty.Internal so it can be used by other pretty-printers. Also I've added a module ZMidi.Core.Pretty.Interp to symbolically interpret MIDI codes (e.g. decode time signatures, key signatures, note names).
I've moved the utility code from ZMidi.Core.Pretty into a new module ZMidi.Core.Pretty.Internal so it can be used by other pretty-printers. Also I've added a module ZMidi.Core.Pretty.Interp to symbolically interpret MIDI codes (e.g. decode time signatures, key signatures, note names).
Thursday, December 26, 2013
zmidi-core
Copperbox revision 3056.
I've removed the MidiSysExDecoded datatype as I've decided against interpreting SysEx data for the time being.
I've tidied up the code in Pretty as a prelude to improving the output of the pretty printer. Tomorrow I'll look towards "symbolically" printing values rather than printing their Hex representation.
Also I've added missing Haddock docs so now the coverage for each module is 100%.
I've removed the MidiSysExDecoded datatype as I've decided against interpreting SysEx data for the time being.
I've tidied up the code in Pretty as a prelude to improving the output of the pretty printer. Tomorrow I'll look towards "symbolically" printing values rather than printing their Hex representation.
Also I've added missing Haddock docs so now the coverage for each module is 100%.
Tuesday, December 24, 2013
zmidi-core
Copperbox revision 3055.
Work on improving the internals of the MIDI file pretty printer. I've changed the internal formatter to build "tables" rather than lines - this will make it easier to improve the pretty printer as column formatting is now implicit.
The intention of this work is to overhaul the pretty printer so it produces much better results.
Temporarily I've added a datatype MidiSysExDecoded, however I think this adds unwarranted complication for a use-case I have. I expect to remove this datatype once I've improved the pretty printer output.
Work on improving the internals of the MIDI file pretty printer. I've changed the internal formatter to build "tables" rather than lines - this will make it easier to improve the pretty printer as column formatting is now implicit.
The intention of this work is to overhaul the pretty printer so it produces much better results.
Temporarily I've added a datatype MidiSysExDecoded, however I think this adds unwarranted complication for a use-case I have. I expect to remove this datatype once I've improved the pretty printer output.
Monday, December 23, 2013
zmidi-core
Copperbox revision 3054.
I've extended ReadFile to handle escaped SysEx events and continuation SysEx events that are spaced over several packets. I still need to look towards adding a post-processing step that decodes "musically useful" SysEx events - currently ZMidi does not interpret SysEx data.
I've extended ReadFile to handle escaped SysEx events and continuation SysEx events that are spaced over several packets. I still need to look towards adding a post-processing step that decodes "musically useful" SysEx events - currently ZMidi does not interpret SysEx data.
Sunday, December 22, 2013
zmidi-core
Copperbox revision 3053.
I've had a rethink about SysEx messages and zmidi-core is back to parsing them as raw data.
Previously zmidi missed SysEx messages encoded as mutli-packet messages or escape sequences - datatypes for these have been added, though parsing with ReadFile is incomplete (output with WriteFile is complete - the implementation is simpler).
It looks like the best option to extract "musically useful" SysEx messages will be to run a post-processor on the AST. I'll look at this tomorrow.
I've had a rethink about SysEx messages and zmidi-core is back to parsing them as raw data.
Previously zmidi missed SysEx messages encoded as mutli-packet messages or escape sequences - datatypes for these have been added, though parsing with ReadFile is incomplete (output with WriteFile is complete - the implementation is simpler).
It looks like the best option to extract "musically useful" SysEx messages will be to run a post-processor on the AST. I'll look at this tomorrow.
Saturday, December 21, 2013
zmidi-core
Copperbox revision 3052.
I've corrected an error in the decoding and encoding of SysEx events. ZMidi used a wrong representation for SysEx (varlen, payload) - it should be (identifier, payload) where payload is a sequence of Word8s with the MSB set to 0 (i.e. in the range 0-127).
It turns out there are some SysEx messages that I should be decoding, I'm looking to adding them next.
I've corrected an error in the decoding and encoding of SysEx events. ZMidi used a wrong representation for SysEx (varlen, payload) - it should be (identifier, payload) where payload is a sequence of Word8s with the MSB set to 0 (i.e. in the range 0-127).
It turns out there are some SysEx messages that I should be decoding, I'm looking to adding them next.
Tuesday, December 17, 2013
majalan
Copperbox revision 3051.
I've implemented grace note for SoloPart. Because notes, chords etc. are like Writer's tell (monadic commands rather than functions producing tangible syntax), prefixing with a grace note is a transformer (SoloPart -> SoloPart). This makes for an odd API - notes, chords are commands but adding a grace is a transformer.
On the plus side, duration stealing works - a grace should steal an eighth (or whatever) from the note it precedes so that the music stays on the beat.
I've implemented grace note for SoloPart. Because notes, chords etc. are like Writer's tell (monadic commands rather than functions producing tangible syntax), prefixing with a grace note is a transformer (SoloPart -> SoloPart). This makes for an odd API - notes, chords are commands but adding a grace is a transformer.
On the plus side, duration stealing works - a grace should steal an eighth (or whatever) from the note it precedes so that the music stays on the beat.
Monday, December 16, 2013
majalan
Copperbox revision 3050.
More work on concatenation.
Vertical concatenation is more challenging than horizontal concatenation some objects (e.g. EventLists) must accommodate different instruments and hence have differently typed ImpulseMaps. This means the uniform set of classes for horizontal concat cannot be replicated for vertical concat.
There is no notion of spacing (sep) for vertical concatenation so we don't need analogues to HSep and HConcatSep.
More work on concatenation.
Vertical concatenation is more challenging than horizontal concatenation some objects (e.g. EventLists) must accommodate different instruments and hence have differently typed ImpulseMaps. This means the uniform set of classes for horizontal concat cannot be replicated for vertical concat.
There is no notion of spacing (sep) for vertical concatenation so we don't need analogues to HSep and HConcatSep.
Sunday, December 15, 2013
majalan
Copperbox revision 3049.
I've added classes and instances for horizontal concatenation.
After changes to Event to accommodate event-width for sostenuto, concatenation became a lot simpler and using classes for HCat, HSep etc. makes sense again (as it did for the original Majalan).
That said, vertical concatenation isn't properly thought out yet - hence types implement their own ad-hoc variations.
I've added classes and instances for horizontal concatenation.
After changes to Event to accommodate event-width for sostenuto, concatenation became a lot simpler and using classes for HCat, HSep etc. makes sense again (as it did for the original Majalan).
That said, vertical concatenation isn't properly thought out yet - hence types implement their own ad-hoc variations.
Saturday, December 14, 2013
Thursday, December 12, 2013
Wednesday, December 11, 2013
majalan
Copperbox revision 3046.
Work on Event concatenation, which is more subtle than I had anticipated.
One principle is that an Event should only generate one impulse regardless of how many sub-events it is made of. This means avoiding Monoid's mconcat and instead only taking the leftmost answer.
Another issue is that horizontal concatenation (for trills, tremolos, ...) should probably not use the timespan of the left event to place subsequent events. Timespan suffers from the already recognized problem that it doesn't represent staccato and legato / sostenuto notes.
Work on Event concatenation, which is more subtle than I had anticipated.
One principle is that an Event should only generate one impulse regardless of how many sub-events it is made of. This means avoiding Monoid's mconcat and instead only taking the leftmost answer.
Another issue is that horizontal concatenation (for trills, tremolos, ...) should probably not use the timespan of the left event to place subsequent events. Timespan suffers from the already recognized problem that it doesn't represent staccato and legato / sostenuto notes.
Tuesday, December 10, 2013
majalan
Copperbox revision 3045.
Work towards a symbolic note list rather than an event list. A symbolic note list should more directly use notes than the current Event List. Event List uses an instrument to instantiate an Event - if I limit the note list to a single, solo instrument then events can be replaced by notes (or chords or trills etc.).
The code so far is just a sketch.
Work towards a symbolic note list rather than an event list. A symbolic note list should more directly use notes than the current Event List. Event List uses an instrument to instantiate an Event - if I limit the note list to a single, solo instrument then events can be replaced by notes (or chords or trills etc.).
The code so far is just a sketch.
majalan
Copperbox revision 3044.
I've changed PhraseMonad so that answers from Events are logged as impulses at the position (onset) they occur. This seems a more intuitive way of creating ImpulseMaps that the previous scheme which required manual impulse calls before an Event was instantiated.
I've changed PhraseMonad so that answers from Events are logged as impulses at the position (onset) they occur. This seems a more intuitive way of creating ImpulseMaps that the previous scheme which required manual impulse calls before an Event was instantiated.
Sunday, December 8, 2013
Saturday, December 7, 2013
majalan
Copperbox revision 3041.
I've added cursor position to the EventList representation via a State monad. This should be better for "symbolic concatenation" than using the bounding box-like time span. Time span would suffer from the staccato / legato problem that I recently solved in PhraseMonad: concatenation that makes musical sense wants to be based on symbolic note lengths (so the music stays in time) rather than actually note lengths which may be shorter (staccato) or longer (sostenuto / legato) than their "beat".
Intriguingly, having cursor position in the representation might open the possibility of improving the API for behaviors over time.
I've added cursor position to the EventList representation via a State monad. This should be better for "symbolic concatenation" than using the bounding box-like time span. Time span would suffer from the staccato / legato problem that I recently solved in PhraseMonad: concatenation that makes musical sense wants to be based on symbolic note lengths (so the music stays in time) rather than actually note lengths which may be shorter (staccato) or longer (sostenuto / legato) than their "beat".
Intriguingly, having cursor position in the representation might open the possibility of improving the API for behaviors over time.
Thursday, December 5, 2013
majalan
Copperbox revision 3040.
Work on adding Impulses to Phrases and EventLists.
Unfortunately, Impulses cannot work as Event transformers (turning the answer of an Event into an Impulse at the instant it is called). Instead Impulses (probably) need to be seen as a kind of "in-band annotation" with privileged access to the current cursor position that is otherwise opaque to the caller.
Work on adding Impulses to Phrases and EventLists.
Unfortunately, Impulses cannot work as Event transformers (turning the answer of an Event into an Impulse at the instant it is called). Instead Impulses (probably) need to be seen as a kind of "in-band annotation" with privileged access to the current cursor position that is otherwise opaque to the caller.
Wednesday, December 4, 2013
majalan
Copperbox revision 3039.
I've changed PhraseMonad to use Writer+State rather than State, thus it accumulates an answer rather than passes it through (as it did a couple of revisions ago). At the cost of some efficiency, it is much easier to think about concatenation in the Writer+State formulation.
I've changed PhraseMonad to use Writer+State rather than State, thus it accumulates an answer rather than passes it through (as it did a couple of revisions ago). At the cost of some efficiency, it is much easier to think about concatenation in the Writer+State formulation.
Tuesday, December 3, 2013
majalan
Copperbox revision 3038.
I've removed the WriterState monad module and clean up the code where it was used.
Where it was used I've switched to using just a Writer monad. It turns out it is a lot easier to think about concatenation when I'm using (inefficient) Writer rather than a more efficient State monad.
I've removed the WriterState monad module and clean up the code where it was used.
Where it was used I've switched to using just a Writer monad. It turns out it is a lot easier to think about concatenation when I'm using (inefficient) Writer rather than a more efficient State monad.
Monday, December 2, 2013
Sunday, December 1, 2013
majalan
Copperbox revision 3035.
I've added PhraseMonad which unifies the Phrase, Advance and Legato note list objects. The key insight is to represent current position (strictly speaking a delta, not a position) independently of accumulated time-span. Phrase events don't update the current position, Advance events update the position with there exact length (i.e. end-to-end placement) and Legato events update the position by an independent symbolic duration so sustain can continue as the next note starts.
At the moment I've got the API of the new Phrase object to work out, so it isn't integrated into the EventList module.
I've added PhraseMonad which unifies the Phrase, Advance and Legato note list objects. The key insight is to represent current position (strictly speaking a delta, not a position) independently of accumulated time-span. Phrase events don't update the current position, Advance events update the position with there exact length (i.e. end-to-end placement) and Legato events update the position by an independent symbolic duration so sustain can continue as the next note starts.
At the moment I've got the API of the new Phrase object to work out, so it isn't integrated into the EventList module.
Subscribe to:
Posts (Atom)
Blog Archive
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.