Tuesday, December 31, 2013

OpenVG and OpenVGRaw

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

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.

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

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.

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.

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.

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

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


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

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.
 

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.

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.

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.

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.

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.

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.

Saturday, December 14, 2013

majalan

Copperbox revision 3048.

I've added a class for delaying score objects (Events, etc.). This has alerted me to the transformations on EventLists looking out-of-date and possibly buggy since CursorPos was introduced to EventList.

Thursday, December 12, 2013

majalan

Copperbox revision 3047.

I've added symbolic duration (generally I'll start calling this width or wx after the terminology in PostScript) to Events so they can represent sostenuto. This improves the concatenation API.

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.


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.

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.

Sunday, December 8, 2013

majalan

Copperbox revisions 3042 & 3043.

I've removed the original majalan and om-shell (which built on it). I've renamed majalan2 to majalan as it is now the mainline development.

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.

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.

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.

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.


Monday, December 2, 2013

majalan

Copperbox revision 3037.

... I've now integrated PhraseMonad with EventList removing the special cases in EventList for Advance and Legato note lists.

majalan

Copperbox revision 3036.

More work on the PhraseMonad - improved API naming scheme and added time-varying behavior versions of event, advance and advanceBy.

PhraseMonad is still to integrate with EventList...

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.

Thursday, November 28, 2013

majalan

Copperbox revision 3034.

I've added a new note list fragment builder (Legato) that improves on Advance.

Although Advance is conceptually fairly simple, it is not so musically useful. Because it places events end-to-end it cannot account for staccato phrases - notes sounding for shorter than their notated durations - and legato / sostenuto phrases - notes sustained for longer than their notated duration. Despite being called Legato (for want of a name) the new fragment builder enables both.

Wednesday, November 27, 2013

majalan

Copperbox revision 3033.

I've changed the representation of PchEvent to be a function : pitch x duration -> Event rather than pitch -> Event. This eliminates yesterday's worry about needing a DrnEvent (now unnecessary) and allows a fairly consistent note list style if I use the redundant note combinator.

Tuesday, November 26, 2013

majalan

Copperbox revision 3032.

I've implemented trill as a combinator rather than a so called - by me - "constructor". Also I've tidied up Demo02 a little.

I'm wondering if Majalan needs object DrnEvent (wrapping : duration -> Event) as a intermediary between PchEvent > DrnEvent > Event. The chordal and trill combinators already use an unwrapped version and the unwrapped-ness adds clutter to user code.

Monday, November 25, 2013

majalan

Copperbox revision 3031.

I've added a PchEvent object (a newtype wrapped function : pitch -> Event) and implemented chordal as a combinator. PchEvent should allow other combinators for trills, arpeggios etc. and solve the scaling problem of the previous post.

majalan

Copperbox revision 3030.

First attempt at trills.

It looks like the idiom used yesterday for chords (defining a new event constructor) isn't really going to be scalable once I start to account for chords, trills, arpeggios etc. It looks like I am going to need a special version of Event for pitched events...


Sunday, November 24, 2013

majalan

Copperbox revision 3029.

First test of chords in a score. At the moment I define an second chord version of an instrument's event constructor - as pitch is one parameter out of several for an instrument (in some cases instruments may even be unpitched) I'm not sure a can write a chord combinator that takes an event and applies it to a list of pitches.

majalan

Copperbox revision 3028.

More work filling out intervals and chords.

Friday, November 22, 2013

majalan

Copperbox revision 3027.

I've updated chord construction to use major and minor triads plus chord transformers (removing further chord constructors). My current reading of Francois Pachet's paper makes me believe I can implement the chord grammar with just the initial two constructors (M | m triads) plus a bag of transformers.

The module is still incomplete though, I need to do some research to fill out the lexicon of chord and interval names.

Thursday, November 21, 2013

majalan

Copperbox revision 3026.

I've switched Chords to use a representation that allows manipulation. This means I should be able to implement something close to Francois Pachet's chord building grammar, the stumbling block at the moment is differentiating which of Pachet's functions are chord constructors and which are chord transformers.

majalan

Copperbox revision 3025.

I've added initial work building chords. The current representation will be insufficient to represent the Pachet chord building grammar (Francois Pachet - An Object-Oriented Representation of Pitch-Classes, Intervals, Scales and Chords), so likely it will need revising.

Also, I've fixed a long-standing, unnoticed bug with adding intervals to pitches. I seems hard (for me) to keep track of octaves in an (octave x Z12) pitch representation for equal temperament - much easier to go via in integer representation that corresponds to MIDI pitch values.

Sunday, November 17, 2013

majalan

Copperbox revision 3024.

Initial work on a new example.

I intend that the new example should be somewhat musical, so I've been testing the builtin Csound instruments. I've found three from the STK collection that I think I like enough, though they could do with some tweaking. Also I'll have to establish the gamut in which they sound good enough for composition - synthesized sounds seem to have a disappointingly small range over which they sound attractive.

Also I've corrected a long standing bug in the formatting of the score output. A mix up of the pretty print combinators hcat and hsep.

Wednesday, November 13, 2013

majalan

Copperbox revision 3023.

I've added some elementary concat combinators. At the moment there is a name clash between the Event and EventList modules, though I don't know whether I want to resolve it with a typeclass or favour EventList.

I haven't tested concatenation yet, but I'm concerned ImpulseMaps won't do the right thing...

Tuesday, November 12, 2013

majalan

Copperbox revision 3022.

I've implemented time varying Behaviors a la Fran and the original Majalan.

Monday, November 11, 2013

majalan

Copperbox revision 3021.

I've properly implemented bracket and processors in Majalan2. This means processors - e.g filters, delay, etc. - can be applied to event lists without knowing the details of onset and duration in the score (Majalan calculates these).

Also I've added LICENSE, cabal and Setup files so Cabal will build the Haddock docs.

Sunday, November 10, 2013

majalan

Copperbox revision 3020.

I've added a module Shim.CSD to create Csound CSD files and to run them as a process. This means Majalan2 finally makes a sound.

At some point the Shim layer should provide a single module import for all the "user" functionality in Majalan.Core.

majalan

Copperbox revision 3019.

I've added the Symbolic modules from the original Majalan and corrected module paths in the code moved to Majalan.Core.

Saturday, November 9, 2013

majalan

Copperbox revision 3018.

I've moved all the "implementation" modules into Majalan.Core (majalan2) - this is a prelude to adding the Symbolic modules from the original Majalan.

Also, I've changed vertical concatenation of EventLists - vertical concat no longer concatenates ImpulseMaps, only the top impulse map is taken, the lower impulse map is dropped. This allows concatenation of EventLists with different typed ImpulseMaps (obviously) and avoids saturating the time line.

Wednesday, November 6, 2013

majalan

Copperbox revision 3017.

I've changed the EventList accumulator to build both a Tree and an ImpulseMap rather than just a Tree.

In practice this will need some refining as I think I will need to allow impulse labels to have different types (for different "systems").


majalan

Copperbox revision 3016.

I've extracted the TimeSpan code out of Majalan.Base into its own module. Also I've implemented retrograde on ImpulseMap.

At the moment I'm not sure where to store ImpulseMaps within the syntax tree, so although ImpulseMaps are now implemented they are unused.

Tuesday, November 5, 2013

majalan

Copperbox revision 3015.

I've redesigned ImpulseMap so it will support transformations. Scale and displacement are implemented, retrograde (reverse) is to do.

To allow a sensible retrograde, ImpulseMap needs a timespan (a frame). As the frame size isn't known until the Phrase or Advance group is built I need a separate data type ImpulseList to represent an ImpulseMap during its construction (before its frame size is known).

Monday, November 4, 2013

majalan

Copperbox revision 3014.

I've changed the monads related to EventList to use a common WriterState building block rather than the previous Answer tuple (which didn't work very well).


Sunday, November 3, 2013

majalan

Copperbox revision 3013.

I've added an accumulating impulse map to the EventList structures - this should work in a similar manner to anchors in Wumpus (which in turn took them from TikZ).

I haven't yet tidied up the Answer type - a better thing to do looks like adding a general Writer-State monad instead. This should be a better opportunity to factor some code as all the EventList monads can be built with a Writer-State monad.

Wednesday, October 30, 2013

majalan

Copperbox revision 3012.

I've added phrases with advance vectors rather than explicit onsets. Advance vectors are patterned after text in PostScript whereby the next drawing position of a character is advanced to by the width vector of the last one.

This has rather messed up the code - particularly, the Answer type wasn't as universal as I was imagining. I'll have to tidy the code up at the weekend when I've got enough time to properly concentrate on it.

Tuesday, October 29, 2013

majalan

Copperbox revision 3011.

I've finally hooked everything together so that Majalan2 generates Csound scores. In reality doing this wasn't much over and above what I had yesterday, but I was tired and didn't think to code it up.

Monday, October 28, 2013

majalan

Copperbox revision 3010.

I've changed the EventList in the Majalan2 branch to generate the new Tree type as its accumulator (rather than a list of I-statements).

Sunday, October 27, 2013

majalan

Copperbox revision 3009.

I've added an internal tree representation for note lists. This should allow sequential concatenation that displaces the onset of right hand lists only once (c.f a Hughes list avoiding ++). It also embeds affine-like transformations - scale, displace and reverse.


Tuesday, October 22, 2013

majalan

Copperbox revision 3008.

I've added an EventList to the experimental Majalan2 branch.

The example is now broken as it was constructing i-statement lists using a temporary (read invalid) API. I need to correct the example to use the Event and EventList types.

Wednesday, October 9, 2013

majalan

Copperbox revision 3007.

Initial work on the Event type. Most of the work is take straight from the original Majalan but I think I can improve the handling of Zak ports.

Tuesday, October 8, 2013

majalan

Copperbox revision 3006.

Work on Answers - the result type for Events / EventLists, etc.

Answer is a tuple of accumulated i-stmts, the timespan of the event or events and a polymorphic user answer. Sometimes timespan will be accessible like a state monad (e.g. EventList), other times it will be opaque like the "output state" of a writer monad (e.g Event).


Monday, October 7, 2013

majalan

Copperbox revision 3005.

I've coded up the basic functionality for printing note lists (now including a column headings comment).

The note list writer is due to be wrapped in some other monad - accumulating the time span (state), parametric on start time (reader)...

Sunday, October 6, 2013

majalan

Copperbox revision 3004.

I've started a new version of Majalan - currently in the directory majalan2 but I'll overwrite majalan when it is functional.

This version will produce independent scores - the previous version was expected to work with Orca, but I'll now to be working with hand-made orchestras (at least initially).


Monday, September 30, 2013

Prolog

I've been learning Prolog this month, none of the results so far merit committing to Copperbox. The intention is to code Lint style rules as Prolog rules and use them to check configurations for bad smells.

By configurations I mean structured data that doesn't necessarily have a corresponding AST - program code naturally has an AST representation and a Lint style checker would traverse the AST; but a configuration might have a flat or nearly flat structure, yet still have dependencies / relationships between values. Prolog (or Datalog) seems a natural choice to represent such data and rules - indeed cfengine is a current exemplar.


Tuesday, September 3, 2013

orca

Copperbox revision 3003.

Work simulating the algorithm style used by Yahama's DX7 synthesizer and others.

The algorithm style is characterized by two parts - a network of operators and the connections between them (on the DX7 the operators were FM phasors) - the algorithm; plus processors that decorated each operator transforming their input and output signals (e.g applying an envelope or filter).

There is a lot that is clunky in my simulation, some can be improved but I need to work out a naming convention for functions with varying input and output arities.



Wednesday, August 28, 2013

Orca

Copperbox revision 3002.

Initial work adding late binding of "dull" parameters through the Reader environment.

Tuesday, August 27, 2013

orca

Copperbox revision 3001.

I've added a wrapper monad over the Orca monad. The wrapper monad is a Reader / environment monad although it won't use the regular Reader interface as it intends to simulate environment acquisition.

Monday, August 26, 2013

orca

Copperbox revision 3000.

I've implemented a new revision of Orca that simplifies the syntax builder monad. The intention is to then wrap this monad again in a Reader that simulates "environment acquisition" - so the dull parameters like table index for oscillators can be acquired from the environment rather than taken directly from function parameters. This should make the parameter lists of functions smaller (thus hopefully clearer) and allow late binding (so hopefully configuration is more flexible).


Friday, August 16, 2013

pretty-expr-hpj

Copperbox revision 2999.

I've added initial support for pretty printing ternary operators like C's (_ ? _ : _). The code is untested and possibly wrong as it is a new feature not present in Norman Ramsey's original code.

Wednesday, August 14, 2013

pretty-expr-hpj

Copperbox revision 2998.

I've done some clean up work on the code as I'm planning to add support for ternary (and possibly mixfix) operators.

Monday, August 5, 2013

flea circus

Copperbox revision 2996.

Move the Lua code (flea_motion and flea_circus)  into the directory art_sound/lua.


Copperbox revision 2997.

mcommand - experiment with Missile Command (cursor!) style player control.


Side Note

Sadly my application to Light Night has been turned down - so work has stopped on the flea circus. Back to Haskell...

Sunday, August 4, 2013

flea circus

Copperbox revision 2994.

I've reworked the flea stack so it grows only from the top. This means that a fair amount of game play is now "working". It also illustrates that the current game play isn't up to scratch - I'm still going to need a lot of design work.

Update - revision 2995.

Minor changes to the player speed to reduce the arc of a jump. 

Saturday, August 3, 2013

flea circus

Copperbox revision 2993.

I've fixed some glitches where the stack of fleas wasn't being animated. Most heinously was I was calling self.play('...') rather than self:play('...') - the former causes a silent fail. Also I had some issues calling self (or not) in the class constructors.


Thursday, August 1, 2013

Lua angst

Tonight I needed to use the Lua interpreter (mostly I run from Love) and it seems that Lua for Windows hadn't set an inadequate path when it installed.

The environment variable LUA_PATH in the control panel was just "C:\Program Files\lua\5.1\lua" but this means the Lua interpreter won't be able to load modules in the current directory when used interactively.

I had to prefix the path with "?;?.lua" - i.e. "?;?.lua;C:\Program Files\Lua\5.1\lua"

Question mark is the wildcard for Lua, the interpreter swaps it for the module name. Semicolon is the "path" separator, though apparently Lua doesn't have much of a notion of paths.


I couldn't find mention of this problem through various frustrated web searches, so I'm posting it here. I expect all Lua coders already know that the LUA_PATH should include "?;?.lua".


Tuesday, July 30, 2013

flea circus

Copperbox revision 2992.

I've added a subclass for the flea stack - the first level of the game (there might only be one) has the player jumping on to a stack of fleas to make a tower (c.f circus acrobats).

The flea stack is a specialized Group - unfortunately it seems I have to make a subclass of Group (and inherit a big API) rather than wrap a Group as an instance variable of a new class. If I wrap Group, the flea stack appears to miss some draw event fired in the framework which leaves it invisible.

Monday, July 29, 2013

flea circus

Copperbox revision 2991.

Slaps forehead, Homer Simpson style...

The problem with the flea player not picking up simultaneous jump and left / right arrow key presses was entirely self-inflicted and not due to a slow computer.

The old code merged all key press detection into one multiway if statement:
if the.keys:pressed("left") then
    self:walkLeft()
elseif the.keys:pressed("right") then
    self:walkRight()
elseif the.keys:pressed(" ") then
    playSound('jump.ogg')
    self:jumpAction()
end
The solution is to group exclusive key presses together (left | right) but use separate if statements for independent actions (jump):
if the.keys:pressed("left") then
    self:walkLeft()
elseif the.keys:pressed("right") then
    self:walkRight()
end

-- We can detect more then one key press per frame if we
-- don't nest them within the same if-elseif ... statement
if the.keys:pressed(" ") then
    playSound('jump.ogg')
    self:jumpAction()
end
Annoyingly I was aware of this idiom as the player control has had it before, but it got removed in a frustrated bout of hacking. This obviates the need for yesterdays Pachinko inspired player control.

Sunday, July 28, 2013

flea circus

Copperbox revision 2990.

I've added another control / motion experiment - Pachinko.

In a nutshell, it seems that holding down the left or right arrows for constant motion is not going to work. So I need a new control strategy that uses singular key presses. Pachinko seems like a good model - start the flea off with maximum velocity and let its acceleration very slowly decay to zero. Jumping is still controlled by a key press (so there is some deviation from Pachinko), but left or right direction is determined by the initial motion and collisions rather than user action.

Saturday, July 27, 2013

flea circus

Copperbox revision 2989.

I've got the basics of the first level working - the player jumps on top of  a growing "acrobat stack" of fleas.

As my dev computer is ancient, it's hard to get a feel of whether the player control of the flea is going to be satisfactory. Maybe I should have picked clowns on unicycles - harder to animate but easier to control....

Thursday, July 25, 2013

skeletons.ps - a PostScript doodle with iteration skeletons

% Stroked circle
% follows the idiom of builtin arc where X Y are parameters
% (i.e. not the ~moveto~ then ~show~ idiom of text)
%
/SCIRC     % X Y R SCIRC
{
  /R exch def
  /Y  exch def
  /X  exch def
  newpath
  X Y R 0.0 360.0 arc
  closepath
  stroke
} bind def





% Font load
/FL   % SZ NAME FL
{
  findfont exch
  scalefont
  setfont
} bind def


% HREPEAT
/HREPEAT % N X Y DX PROC
{
  /PROC exch def
  /DX exch def
  /Y exch def
  /X exch def
  /N exch def
  N { X Y PROC
      X DX add
      /X exch def } repeat
} bind def

% VREPEAT
/VREPEAT % N X Y DY PROC
{
  /PROC exch def
  /DY exch def
  /Y exch def
  /X exch def
  /N exch def
  N { X Y PROC
      Y DY add
      /Y exch def } repeat
} bind def

% XFORALL
/XFORALL % X Y DX ARR PROC
{
  /PROC exch def
  /ARR exch def
  /DX exch def
  /Y exch def
  /X exch def
  ARR { /A1 exch def
        X Y A1 PROC
        X DX add
        /X exch def } forall
} bind def

% YFORALL
/YFORALL % X Y YX ARR PROC
{
  /PROC exch def
  /ARR exch def
  /DY exch def
  /Y exch def
  /X exch def
  ARR { /A1 exch def
        X Y A1 PROC
        Y DY add
        /Y exch def } forall
} bind def


% XYSHOW
/XYSHOW % X Y STR
{
  /STR exch def
  /Y exch def
  /X exch def
  X Y moveto
  STR show
} bind def


% APPLY2 - apply a procedure taking 2 arguments to an
% array with 2 elems (pair)
/APPLY2     % ARR PROC APPLY2
{
  /PROC exch def
  /ARR exch def
  /S1 ARR 0 get def
  /S2 ARR 1 get def
  S1 S2 PROC
} bind def



gsave

12 /Helvetica FL

gsave

5 100 100 20 { 5 SCIRC } HREPEAT

10 100 200 15 { /Y exch def
                /X exch def
                X Y moveto
                (o) show } HREPEAT

7 300 100 15 { (A) XYSHOW } VREPEAT

300 300 50 [5 10 15 20] { SCIRC } XFORALL


100 300 -15 [(1) (2) (3) (4)] { XYSHOW } YFORALL

grestore
showpage

Wednesday, July 24, 2013

PostScript (higher order)

Code is a first class citizen in PostScript. The builtin repeat and forall operators are obvious consumers of code (procedures) but it is also easy to define your own higher order skeletons. For instance the code example at the bottom defines hrepeat as used by Wumpus.

For efficiency reasons I'd like a successor to Wumpus to allow users to create their own drawing procedures, and iterating these drawing procs should be possible in PostScript (rather than having to unroll the iteration skeletons during "compilation" leading to code bloat).



% Stroked circle
% follows the idiom of builtin arc where X Y are parameters
% (i.e. not the ~moveto~ then ~show~ idiom of text)
%
/SCIRC     % X Y R SCIRC
{
  /R exch def
  /Y  exch def
  /X  exch def
  newpath
  X Y R 0.0 360.0 arc
  closepath
  stroke
} bind def





% Font load
/FL   % SZ NAME FL
{
  findfont exch
  scalefont
  setfont
} bind def


% HREPEAT
/HREPEAT % N X Y DX PROC
{
  /PROC exch def
  /DX exch def
  /Y exch def
  /X exch def
  /N exch def
  N { X Y PROC
      X DX add
      /X exch def } repeat
} bind def


gsave

12 /Helvetica FL

gsave

5 100 100 20 { 5 SCIRC } HREPEAT

10 100 200 15 { /Y exch def
                /X exch def
                X Y moveto
                (o) show } HREPEAT

grestore
showpage

Monday, July 22, 2013

flea circus

Copperbox revision 2988.

More work on flea motion.

I think I'm happy that this code models how I want the flea motion to be controlled and the code is clear enough (although the model is simplified as it doesn't yet account for collisions).

There are a couple of intrinsics to the motion that are now captured:

* Fleas should walk left (or right) with the arrow keys pressed. After the arrow is release there is still some residual forward motion until the flea decelerates.

* Jumping should account for the speed/direction at the point of the jump key-press. During the jump - pressing arrow keys has no influence, i.e. control is like a long jump (rather than a jet-pack!).

Sunday, July 21, 2013

flea circus

Copperbox revision 2987.

More work on flea motion - I've started a sandbox project just for this (art_sound/flea_motion).

Motion (direction, acceleration, velocity) is quite complicated to reason about, I'll have to encapsulate it into some kind of state machine. I'm missing algebraic datatypes in Lua.

Sunday, July 14, 2013

ochre-redux

Copperbox revision 2986.

A new experiment remaking the Ochre / Orca monad so it is more comfortable for developing DX7 style algorithms.

The many feature is a kind of late binding implemented via type classes, this intends to regularize the input parameters to components (so they can be composed) - and hide some of the tedious details (such as the table number references needed by FM phasors).




Monday, July 1, 2013

om-shell

Copperbox revision 2985.

Work on a more component style of implementing configuration algorithms.


Configuration algorithm - a block diagram linking operators, where an operator is a signal generator or a signal transformer (implemented with one or more Ugens).

Component style - operators are addressable components with input and output ports. Chaining processors on these ports (e.g adding delay, echo, ...) should be allowed.

Previously a large record was used for all the parametrization of an algorithm which hindered customization with (standard) reusable processors.




Friday, June 28, 2013

om-shell

Copperbox revision 2984.

I've updated OM-Shell to work with the changes to orca (the changes are actually minor).

Sunday, June 23, 2013

orca

Copperbox revision 2983.

I've changed the syntax and internals of the builder monads to separate declarations from statements. The intention behind this is that declarations can potentially be floated to the top during composition of instrument skeletons.


Sunday, June 16, 2013

flea circus

Copperbox revision 2982.

More work on flea motion / control.

In a nutshell the current code is too inefficient. I've spent most of today's coding time looking at why key presses weren't being picked up, but after running it on my (more powerful) laptop I realized the game was dropping keys because it was doing too much processing to fit in the frame rate. Maybe I'll need a faster machine for development, but there are certainly big improvements that could be made to the code first.

Sunday, June 9, 2013

flea circus

Copperbox revision 2981.

Work on the mechanics of flea movement.

Ideally, I want the flea to run with a decaying initial burst of velocity when you press left or right arrow key (if you keep left or right held down the flea keeps running at constant speed). Flea jumping should then 'inherit' the current direction and velocity with no changing direction mid-jump.

I think I have coded this, unfortunately it doesn't work well - using a keyboard doesn't yield a jump key press if you are running left or right (holding down the left or right arrow keys). If you release the left or right arrow key, the deceleration is so quick that the flea is near stationary when a jump key press is registered. This suggests I'm going to need to get a gamepad, though it seems a pity that I can't prototype with the keyboard.


Sunday, June 2, 2013

flea circus

Copperbox revision 2980.

More work on flea circus:






The first "puzzle" is building a stack of fleas by jumping onto the top of them from platforms (think acrobats making human towers). I've got some of the interaction working - the picture above is a screenshot not a mock up though a few cheats were involved.

Monday, May 27, 2013

Something new... Flea Circus

Copperbox revision 2979.

I've started something new (the wheels have rather fallen off my sound / music DSLs) - a platform game in Lua using Love and Zoetrope.

The game is being written for Light Night Leeds, Yorkshire's premier one-night only annual art festival. This year's Light Night theme is circus, hence the subject of my game. Light Night works by submission of interest, so I can make a proposal before I actually write the game. This is a necessity for me as I don't want to do all the work on a game only to have it rejected. Of course, if my submission doesn't make the grade I'll stop work on the game and go back to working on Majalan / Orca.

I do hope I get selected though - it will be fun to learn Lua properly and pressure makes pearls so working to an external deadline will be good discipline. As a game is quite a big project, it should make me get my code mojo working again - I've been very slack about committing to Copperbox this year, time for a change.





Wednesday, May 8, 2013

majalan

Copperbox revision 2978.

ImpulseMap - added more wrappers to functions in the underlying Data.Map.

This is a flagrant attempt to improve my rate of commits per month as I can do this kind of work without thinking about it (I find it difficult to do real design work after doing the day job). But, even autopilot work is better than no work.

Tuesday, May 7, 2013

majalan

Copperbox revision 2977.

Some work on ImpulseMap. The most salient part is that it now has "correct" stretch and reverse implementations. Having correct stretch and reverse should help me work out how the corresponding operations work for ImpulseEventList which is "modular" with respect to start point (ImpulseMap is always fixed - onset times represent actual, fixed times).

Monday, May 6, 2013

majalan

Copperbox revision 2976.

I've put ImpulseMap into its own module. An ImpulseMap - a finite map with onset time as the key - seems like a core data structure for composition, so it merits its own module.

Sunday, May 5, 2013

om-shell

Copperbox revision 2975.

I've updated OM-Shell to use Orca rather than Ochre. The changes were rather small as the monadic "languages" are essentially the same.

orca

Copperbox revision 2974.

I've added wrappers for Csound functions like abs.

orca

Copperbox revision 2973.

Work to get orchestra definitions to print properly when compiled. Note compilation is a misnomer for Orca as there are no optimization passes - the original syntax tree is simply pretty printed as Csound.

Ochre had genuine optimization passes to remove redundant variables and declarations but the utility of these transformations didn't match the complexity cost of their implementation.

Thursday, May 2, 2013

orca

Copperbox revision 2972.

I've now moved enough code from Ochre to define an example FM instrument.

Wednesday, May 1, 2013

orca

Copperbox revision 2971.

I've added the signal cast operations from Ochre. Although casting is somewhat untypical (ahem) in Haskell, the casting operators were one of the better features of the monadic language in Ochre. Without them the code was simply too verbose.

Tuesday, April 30, 2013

orca

Copperbox revision 2970.

More work porting code from Ochre. Plus I've added cabal files so I can build the Haddock docs - Haddock is the best way I've found for project browsing in Haskell.

Monday, April 29, 2013

orca

Copperbox revision 2969.

I've ported more code into Orca from Ochre. The outstanding code to be moved is mostly the monadic code building operations, which might need some tidying up.

Sunday, April 28, 2013

orca

Copperbox revision 2968.

I've added a couple of libraries of opcodes from Ochre, happily these can be imported with just a few direct changes and an instance of "replace all".

orca

Copperbox revision 2967.

I've forked Ochre as a new project Orca.

Orca removes the A Normal Form compiler to directly build instrument language definitions in the monadic embedding.

Wednesday, April 24, 2013

data-aviary-0.4.0

Copperbox revision 2966.

I've made a new release of data-aviary for Hackage. This improves the Haddock docs and removes the "utility" module of favoured combinators - Data.Aviary is not recommended as a linkable library.

Tuesday, April 23, 2013

data-aviary

Copperbox revision 2965.

More work on Haddock docs. Because Arrows, Monads and Comonads and their standard operations introduce data objects Pairs, Sums, Monoids, Lists... there are lots of functions that seem to merit no more explanation than their type signatures.

Saturday, April 20, 2013

data-aviary

Copperbox revision 2964.

I've reactivated this library thanks to a patch from Christopher Young that corrected some typos in the Haddock. It merits some further improvements to the documentation before I upload it to Hackage, but the old version on Hackage needs replacing as it doesn't indicate strongly enough that the library is for reference and not for importing.

Tuesday, April 9, 2013

majalan

Copperbox revision 2963.

I've implemented an event list that accumulates an impulse train.

Data.Map promotes insert rather than concatenate, so it is not a good candidate for accumulating the impulse train via a Writer hence the new event list threads it as State.

Sunday, April 7, 2013

majalan

Copperbox revision 2962.

I've reworked the Score objects to use a Writer or Writer+State monad as their base.

Previously each object was written as a monad from scratch, but I wanted to add an EventList that builds an Impulse Map. Because Impulse Map is a finite map (efficient insert, bad concatenation) it doesn't make a good accumulator as a Writer - it is better to thread a single map as State. Hence I need new primitives to build accumulators.

Tuesday, April 2, 2013

majalan

Copperbox revision 2961.

I've added TimedStream (the name might change...) to implement clock-like signals such as a metronome.

Monday, April 1, 2013

majalan

Copperbox revision 2960.

Provisional work on stretch, reverse and chains.

I've now decided that instances for Stretch and SReverse must be account for their answer type, i.e. this is no longer warranted:

instance SReverse ans => SReverse (EventList u ans) where

instead an instances must written for all answers:

instance SReverse (EventList u ()) where

This leads to a moderate code explosion but some useful answers are not reversible with SReverse instead the need to account for their delta from the time 0. This is because geometrically SReverse would be a translation of the basis to start at 0, a reflection, and traslation back to the original start point from 0.



Chains are not looking a very promising abstraction for music (whereas they have a purpose for graphics). A Chain is a finite walk over an infinite path - the ChainScheme. This makes them the wrong mechanism to model a metronome for instance - a metronome should be an infinite series of events which is evaluated within a fixed time window to make a finite event list.



Wednesday, March 27, 2013

majalan

Copperbox revision 2959.

Initial work on symbolic duration data types.

One type - DSymbol supports proper dot and dot-dot operations to increase the duration by a fractional amount, although this type cannot support addition making it useless for anything except specification. The other type Beat is context sensitive (like em and en in Wumpus) so beat values are interpreted according to the overall beats-per-minute of the score.

Tuesday, March 26, 2013

majalan

Copperbox revision 2958.

I've added Chains (cf. Wumpus) to model infinite, iterated sequences of impulses. At the moment I'm not sure if the types are right - an impulse is currently just a time, but maybe it should be a pair - time and some value of parametric type a.


Monday, March 25, 2013

majalan, om-shell

Copperbox revision 2957.

I've made Space and Displace typeclasses so they are applicable to Events and EventLists (and other structures later). Also I've updated the demos in OM Shell.


Sunday, March 24, 2013

majalan

Copperbox revision 2956.

I've made Behavior parametric on time unit - like Event and EventList. This means that if you are counting with beats rather than seconds you can have time varying Behaviors specified in beats not seconds.

majalan

Copperbox revision 2955.

I've added a distinct EventList type. Whilst Event itself is not atomic and thus can support an some notion of sequential events, it seems valuable to have a type that explicitly represents event lists.

Saturday, March 23, 2013

om-shell

Copperbox revision 2954.

I've updated the instruments and demos in OM Shell to use the new Zak configuration abstraction.

Wednesday, March 20, 2013

majalan, om-shell

Copperbox revision 2953.

I've implemented a good enough notation for Zak configurations - there isn't any real checking and I'm not absolutely sure the construction algorithm is correct, but Zak configs are very minor in the scheme of things so I don't want to spend too much time on them.

Sunday, March 17, 2013

majalan, om-shell

Copperbox revision 2952.

Initial work separating Zak port configuration from Events - rather than having Zak port numbers as final arguments to events I'd like to encapsulate them in a configuration so I won't have to modify each event in the score if the configuration changes.

The work so far is a bit off the mark, I haven't yet worked out a good representation for the static Zak config.

Saturday, March 16, 2013

majalan

Copperbox revision 2951.

I've re-instated Behaviors which allow time-varying events.

Actually Csound encourages its own style of time varying behaviors through globals (or Zak) and Meta-Paramter Control (chapter 18 of the Csound book). These behaviors can be implemented in Ochre, so Ochre+Majalan can support both styles.

Monday, March 11, 2013

majalan

Copperbox revision 2950.

I've implemented symbolic reverse for event lists - symbolic reverse means that that event order is reversed rather than the actual events / sounds. The latter would be rather difficult...

Currently I use this instance for Events:

instance SReverse a => SReverse (Event u a) where

I have a suspicion that this automatic reverse for the answer (param a) might not be the best design and that some answers can't be reversed without knowing the start-end times from the Event itself. If I can solve this satisfactorily it should point out another good simplification for Wumpus.

Sunday, March 10, 2013

majalan

Copperbox revision 2949.

I've added a Processor object to Majalan. Processor is equivalent to Connector in Wumpus - the onset and duration of a Processor are determined by the start and end times of the object it processes.

Saturday, March 9, 2013

om-shell

Copperbox revision 2948.

I've update the rest of the instruments and demos so they run again. A lot can be done to improve the scores, at the moment I haven't implemented many operations on the new score language objects.

Thursday, March 7, 2013

om-shell, majalan

Copperbox revision 2947.

I've updated the first couple of OM-Shell examples to work with the Score representation changes in Majalan. Also I've changed the shim modules in Majalan so scores should need to import just two modules.

Wednesday, March 6, 2013

majalan

Copperbox revision 2946.

Initial work on symbolic stretch. Because events are parametric on onset we would want  let dblevt = stretch 2.0 evt1 to double the length of evt1 but allow us to place dblevt at arbitrary positions - i.e. we don't want to stretch onset as well as duration, so we need a symbolic stretch rather than an affine one.

Unfortunately symbolic stretch seems complicated as Majalan's events may return answers that represent positions and need stretching themselves.

Tuesday, March 5, 2013

majalan

Copperbox revision 2945.

I've added bounded operations directly to the Event type - this seems to indicate Majalan (and Wumpus) might not need a Bounded object.

Monday, March 4, 2013

majalan

Copperbox revision 2944.

I've implemented an Advance object that is much simpler than the corresponding one in Wumpus. The new Advance object is essentially just a state monad - where "onset" is threaded and incremented rather than a constant "start point".

Sunday, March 3, 2013

majalan

Copperbox revision 2943.

I've started on a re-implementation of the Event and event list datatypes. Again, I've decided that the corresponding types in Wumpus (LocImage and TraceDrawing) actually provide a good model that can be adapted from graphics to the domain of music scores.


Tuesday, February 12, 2013

om-shell

Copperbox revision 2942.

I've updated the demos to work with the changes to Gens. Also I've fixed an error with the definition of GEN07 in both Ochre and Majalan.

Monday, February 11, 2013

majalan

Copperbox revision 2941.

I've updated the gens modules in Majalan so they follow their corresponding modules in Ochre. Also Majalan now directly depends on Ochre so it can use the strict pair.

Sunday, February 10, 2013

ochre

Copperbox revision 2940.

I've added some syntax sugar for binding top level orchestra variables - top level variables don't synthesize their name instead it has to be supplied as a string, this is clumsy but it generates better Csound code. I've implemented an idiom with my pair constructor that gives this a pleasant enough syntax.

I've also put the low level gen table wrappers in a module Language.GensRaw  - and started implementing some higher level wrappers.

ochre, om-shell

Copperbox revision 2939.

I've updated the FM demo in OM-Shell to use an orchestra ftgen table. Also I've added more table wrappers to Ochre.

The Ochre Gen modules now have a name clash with Majalan - because they use different symbolic representations for their DSLs the code cannot be shared.

Saturday, February 9, 2013

ochre

Copperbox revision 2938.

I've added the ability to define gentables in orchestras - Csound has had the ftgen opcode to do this for quite some time, but because it isn't covered in the Csound book I've overlooked it.

Wednesday, February 6, 2013

ochre, om-shell

Copperbox revision 2937.

I've changed the module organization in Ochre moving the strict pair from Language.Envelope (now deleted) to Language.Prim. The instruments that used the old envelope notation in OM-Shell have been updated to use the new list-and-strict-pair style.

Tuesday, February 5, 2013

ochre

Copperbox revision 2936.

I've implemented a new notation for envelopes that uses standard lists and novel strict pairs.


envelope1 :: IFloat -> GenKSig
envelope1 idur = expseg                    0.01 
                        [ 0.002        ::: 1.00
                        , idur - 0.002 ::: 0.01
                        ]

Sunday, February 3, 2013

om-shell

Copperbox revision 2935.

I've implemented the FM bell in the style of a DX7 or DX200 algorithm - i.e I've made the connection pattern of the carriers and modulators into a module. This module can be instantiated with configurations (e.g. modulated input frequency) making it more flexible than the previous FM bell. Unfortunately, it still doesn't very compositional at the moment.

Monday, January 28, 2013

om-shell

Copperbox revision 2934.

I've updated the demos to work with the changes to Majalan and added a new combinator to Majalan to nest a note list inside a finalizer. The finalizer takes the time span of the inner note list, so this combinator can be used to set zak based effects to operate on the note list as if it were a track.

Sunday, January 27, 2013

majalan

Copperbox revision 2933.

I've reworked the EventList datatype / monad into two variants - one supports events at arbitrary onset times, the other supports events next to each other in the style of width vectors in computer typography - i.e. an event doesn't have an explicit onset time instead it starts at the point the previous event finished, the duration of the event moves an internal cursor representing onset time forward.

Saturday, January 26, 2013

ochre

Copperbox revision 2932.

I've added some more granular synthesis opcode wrappers. Particularly partikkel has 40 arguments - controlling this opcode will take some effort and suggests a future design might make a distinction between a high-level API and a raw one as per the Haskell OpenGL binding.

Tuesday, January 22, 2013

ochre

Copperbox revision 2931.

I've added the other waveguide opcodes to the Ochre.Language.SignalModifiers module.

Basically this is a brazen attempt to improve my commit number for the month - I can wrap opcodes without much thinking - otherwise this month threatens to be my least productive for years.

Monday, January 21, 2013

om-shell

Copperbox revision 2930.

I've added a waveguide bowed bar instrument. This is one of the physical models from the Csound manual - it makes an attractive enough sound that I can use it for demos as I work on my score language Majalan.

Sunday, January 20, 2013

majalan

Copperbox revision 2929.

I've changed the implementation of EventList to use a datatype representing state rather than pass the two parts of state as separate arguments (the result always had to combine them of course). This is a prelude to making the onset times of events in a notelist relative rather than absolute. With relative onset times it is easy to repeat a notelist after itself - all we have to do is shift the initial onset time of the repeated notelist.

Saturday, January 19, 2013

om-shell

Copperbox revision 2928.

I've updated all instruments to use Parsec Token style modules. Whilst doing this I notices I haven't been very consistent in using camel-case (or avoiding it) for instrument names - I will have to unify the naming scheme at some point.

Thursday, January 17, 2013

om-shell

Copperbox revision 2927.

I've modified FMBell to use a Parsec style module that is instantiated with instrument number - this should make scores safer as the event, instrument and column specification are instantiated with the instrument number in one place rather than three.

Sunday, January 13, 2013

ochre, om-shell

Copperbox revision 2926.

I've changed the symbol for the assignment operator in Ochre and added variations to assignment to an unlifted signal and "self re-assignment" with a signal modifier.


Tuesday, January 1, 2013

majalan

Copperbox revision 2925.

I've added a catalogue of named pitches and fixed a bug with the affine addition of intervals to ET12 pitches - adding negative intervals didn't work and this caused affine subtraction to err.

majalan

Copperbox revision 2924.

I've added symbolic pitch representation that is higher level that just using hertz values. Pitches can be specified in a pitch class notation and rendered to hertz depending on a "global tuning" usually A=440hz.

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.