packages feed

live-sequencer-0.0.2: live-sequencer.cabal

Name:          live-sequencer
Version:       0.0.2
Author:        Henning Thielemann and Johannes Waldmann
Maintainer:    Johannes Waldmann <waldmann@imn.htwk-leipzig.de>, Henning Thielemann <haskell@henning-thielemann.de>
Category:      Sound, Music, GUI
License:       GPL
License-file:  LICENSE
Cabal-Version: >= 1.6
Tested-With:   GHC==6.12.3, GHC==7.2.1
Homepage:      http://www.haskell.org/haskellwiki/Live-Sequencer
Synopsis:      Live coding of MIDI music
Description:
   An editor shows a textual description of music (like Haskore),
   an interpreter computes and emits a stream of MIDI events,
   and (that's the main point) the user can change the program on the fly.
   Additionally the state of the interpreter is shown
   in the form of the current reduced term
   for educational and debugging purposes.
   .
   1. example usage *****
   .
   The live-sequencer does not make music itself,
   its entire task is to control other software or hardware synthesizers.
   That is, in order to hear something you need a working MIDI synthesizer
   such as the sampling based software synthesizer TiMidity.
   You may run TiMidity and the live-sequencer this way:
   .
   > timidity -iA &
   > live-sequencer-gui --connect-to TiMidity Simplesong &
   .
   This should give you an ongoing stream of notes.
   Then change one of the numbers
   that appear in the lines like
   @qn = 300@
   and press CTRL-R for \"reloading\" that module into the interpreter.
   This should immediately have an effect,
   namely increasing the tempo of the melody.
   You may also alter a note name like @c 4@ to @cis 4@, then reload,
   then undo the modification and reload, again, after a while.
   This is the main idea of changing the song while it is playing.
   The way the changes are applied warrants
   that the change takes effect when the time comes.
   Music is not interrupted and
   does not need to be restarted for reacting to changes.
   .
   The overall task performed by the sequencer
   is to lazily evaluate a term called @main@
   that is a list of events.
   The value of @main@ is a stream of midi events
   (@On/Off pitch velocity@, @PgmChange@, @Controller@)
   or (@Wait milliseconds@).
   You may wrap a MIDI event in a @Channel@ constructor
   in order to assign the event to the particular MIDI channel.
   If you omit this constructor then the event is put to channel 0.
   .
   In each step, the head of the @main@ stream gets reduced
   to head normal form (with @:@ at the top),
   and the first arg of the @:@ gets fully expanded
   and it must be a MIDI event.
   .
   2. input language *****
   .
   The used language is syntactically almost a subset of Haskell with
   only strict pattern matching and
   pattern matching only at the definition level (no case),
   no local bindings (no lambda, let, where),
   no types (no type inference, type signatures and type declarations are skipped),
   and with diet syntax (i.e. drastically reduced syntactic sugar,
   like no layout rule, no do syntax, no list comprehension, no operator sections).
   .
   Semantics is similar to lazy evaluation,
   but we have no sharing.
   The design goal is that code can be changed
   while the program is running.
   This implies that evaluation of one expression
   may give different results at different times
   (e.g., during a live performance,
   one changes some chords of a musical theme).
   In turn, this implies that we do not store
   and share results of evaluations,
   hence, we don't have local bindings.
   .
   You may import and use
   the special functions 'Controls.checkBox', 'Controls.slider'
   from the "Controls" module.
   For every call to these functions a widget is added to the control window
   and the state of the widget is the result of the function call.
   Technically every change of these widgets
   internally adds or updates a rule in the "Controls" module.
   The effect is very similar to updating a value definition in a module
   and then reloading that module to the interpreter,
   but using the widgets is more intuitive.
   .
   3. Offline rendering *****
   .
   In the library interface of this package
   we provide the basic Live-Sequencer modules
   in order to allow offline rendering of music
   that you programmed within the Live-Sequencer.
   You may generate a standard MIDI file
   using functions from the "Render" module.
   To this end load your song module into GHCi and call
   .
   >YourModule> Render.writeStream "yoursong.mid" yourSong
   .
   4. HTTP access *****
   .
   You may open a browser and view all modules under
   <http://localhost:8080/>.
   If the user of the GUI inserts comments like this one:
   .
   >----------------
   .
   , then it is possible to modify the content below this mark via HTTP.
   This way multiple people can participate in the composition process.
   The recommended situation is a room
   with a data projector and a loudspeaker,
   where the conductor explains the functions to the auditory
   and the participants can watch the screen and listen to the music.
   .
   You may choose any other port using the command line option @--http-port@.
   If you want to use a system port like the standard HTTP port 80,
   we recommend to configure a firewall to redirect the external port 80
   to the internal user port.
   We discourage from starting the live-sequencer as root user.
   You may disable the HTTP server altogether
   by compiling with @cabal install -f-httpServer@.
   .
   5. Execution modes *****
   .
   There are three modes of execution
   that you can choose from the @Execution@ menu:
   .
   * Real-time:
     This is the mode for musical live performances.
     The interpreter waits according to the @Wait@ elements in the main list.
   .
   * Slow motion:
     This mode is for demonstration and debugging.
     You can alter the speed using @CTRL-\<@ and @CTRL-\>@.
   .
   * Single step:
     This mode is for demonstration, debugging and as a pause mode,
     when the interpreter reaches the end of the main list.
     You can trigger evaluation of the next element using @CTRL-N@.
     Unfortunately it is currently not possible to undo a step.
   .
   6. Editing *****
   .
   You can change a module name by altering the module identifier
   between the @module@ and @where@ keywords
   and then triggering module reload.
   The same way you can load new modules
   by adding import lines and reloading the module.
   Alternatively, you may create new modules or close old ones
   using functions from the @File@ menu.
   .
   For composition it is useful to play parts of the music.
   You can do this by simply placing the cursor within an identifier
   or by marking an expression
   and then call @Play term@ from the @Execution@ menu.
   This will make the marked expression the current term
   and start playing.
   .
   Once the music is playing you can change it
   by altering the module and reload it.
   However you may find out
   that you cannot do a certain modification this way.
   In this case you can mark an expression
   that denotes a stream transformation function
   and call the @Apply term@ menu item.
   This will apply the marked function to the current term.
   Useful functions are:
   .
   * @merge newTrack@ for adding a new track simultaneously.
     However, mind the latency!
   .
   * @flip append newTrack@ for appending some events to the current music.
   .
   * @dropTime time@ for skipping a part of the music.
     However this may skip some @Off@ events and this yields hanging tones.
     Additionally you may exceed the number of maximally allowed reductions.
   .
   * @skipTime time@ for skipping a part of the music.
     This one only removes or shortens @Wait@ constructors.
     Thus all events are played but you risk exceeding the limit
     for playing many events at once.
   .
   * @compressTime acceleration time@ for accelerating the music for a certain time.
     This should circumvent the problems of @dropTime@ and @skipTime@.
   .
   7. Limits *****
   .
   Without some safety belts it would be very easy
   to consume all memory or all processing power
   by accident or by people who contribute malicious code via HTTP.
   Thus we have added some limits.
   These have reasonable default values
   but you can adjust them to your needs via command line options at startup.
   These are the limits you can set:
   .
   * maximum number of reduction steps per list element:
     With this limit you can prevent infinite loops.
   .
   * term size:
     With this limit you can prevent memory leaks.
   .
   * term depth:
     With this limit you can prevent unbalanced expression trees.
     Unbalanced trees do not consume more memory than balanced ones,
     but they consume considerably more graphical space on pretty-printing.
   .
   * maximum number of events per time period:
     If your song is too fast or does not contain any @Wait@ elements at all,
     your machine will run out of processing power.
     Thus you can restrict the number of events
     generated in a certain period of time.
     It is controlled by two options:
     @--event-period@ sets the time period in milliseconds
     whereas @--max-events-per-period@
     sets the maximum number of events within this time period.
     In principle you can consider this a ratio
     but you cannot simply cancel it.
     E.g. both @--event-period=100 --max-events-per-period=15@
     and @--event-period=1000 --max-events-per-period=150@
     describe the same ratio,
     the difference is how liberal is the sequencer
     with respect to exceeding the ratio for a short time.
     Read the first setting as:
     \"For 15 adjacent events,
     the duration between the first and the last one must be at least 100ms.\"
     That is, if you emit 20 events simultaneously every second,
     then the first setting will forbid this,
     and the second setting will allow it.
     Thus we recommend to first set @--max-events-per-period@
     to the number of events that you want to emit simultaneously
     and then set @--event-period@ large enough
     to match the power of your machine.
   .
   8. ALSA
   .
   Using the @--new-out-port@ option
   you may add more ALSA MIDI ports.
   Every port extends the range of MIDI channels by 16 new logical channels.
   That is @Channel 40 ev@ sends an event
   to MIDI channel 8 at the second newly added ALSA port
   (because 40 = 2*16+8).
   Every @--connect-to@ option refers to the latest added port.
   Example:
   .
   > live-sequencer --connect-to Synth0 --new-out-port out1 --connect-to Synth1 --new-out-port out2 --connect-to Synth2
   .
   You do not need to connect to any synthesizer at startup.
   You may connect or disconnect the live-sequencer
   to any synthesizer once it is running
   using @aconnect@ (command line) or
   @kaconnect@, @alsa-patch-bay@, @patchage@ (graphical interfaces).
Build-Type: Simple

Data-Files:
  data/example/Band.hs
  data/example/BandControlled.hs
  data/example/Finite.hs
  data/example/Klingklong.hs
  data/example/Simplesong.hs
  data/example/Sweep.hs
  data/example/UD.hs
  data/example/CrossSum.hs
  data/example/Fibonacci.hs
  data/example/DeBruijn.hs
  data/example/Pattern.hs

  data/base/Bool.hs
  data/base/Chords.hs
  data/base/Controls.hs
  data/base/Drum.hs
  data/base/Function.hs
  data/base/Instrument.hs
  data/base/Integer.hs
  data/base/List.hs
  data/base/ListLive.hs
  data/base/Midi.hs
  data/base/Music.hs
  data/base/Pitch.hs
  data/base/Render.hs
  data/base/Tuple.hs

  data/prelude/Prelude.hs

Extra-Source-Files:
  http/enable/HTTPServer.hs
  http/enable/HTTPServer/GUI.hs
  http/enable/HTTPServer/Option.hs
  http/disable/HTTPServer/GUI.hs
  http/disable/HTTPServer/Option.hs

Source-Repository head
  Type: git
  Location: git://dfa.imn.htwk-leipzig.de/srv/git/seq/

Source-Repository this
  Type: git
  Tag: 0.0.2
  Location: http://code.haskell.org/~thielema/livesequencer/

Flag gui
  Description: Build the wxWidgets GUI for the sequencer
  Default: True

Flag mplayer
  Description: Build the remote controller to the mplayer
  Default: True

Flag httpServer
  Description: Enable access to modules via a web browser
  Default: True


Library
  Hs-Source-Dirs: data/base, data/example
  GHC-Options: -Wall
  Build-Depends:
    -- for Render
    non-negative >=0.0.6 && <0.2,
    event-list >=0.0.11 && <0.2,
    base >=4.2 && <5
  Exposed-Modules:
    Render
    Bool
    Chords
    Controls
    Drum
    Function
    Instrument
    Integer
    ListLive
    Midi
    Music
    Pitch
    Tuple
  Other-Modules:
    List
    Pattern
    Finite
    CrossSum
    DeBruijn
    Fibonacci


Executable live-sequencer
  Hs-Source-Dirs: src, http/disable
  Main-is: Console.hs
  Other-Modules:
    ALSA
    Event
    IO
    Module
    Option
    Option.Utility
    Program
    Rewrite
    Rule
    Step
    Term
    Time
    Type
    Log
    Paths_live_sequencer
    Utility.NonEmptyList
  Other-Modules:
    Lilypond
  GHC-Options: -Wall -threaded
  If impl(ghc>=7.0)
    GHC-Options: -fwarn-unused-do-bind -fwarn-missing-import-lists
  Build-Depends:
    transformers >=0.2.2 && <0.4,
    explicit-exception >=0.1.5 && <0.2,
    parsec >=2.1 && <3.2,
    pretty >=1.0 && <1.2,
    midi-alsa >=0.1.1 && <0.2,
    midi >=0.1.5 && <0.2,
    alsa-seq >=0.5 && <0.6,
    alsa-core >=0.5 && <0.6,
    data-accessor-transformers >=0.2.1 && <0.3,
    data-accessor >=0.2.1 && <0.3,
    strict >=0.3.2 && <0.4,
    utility-ht >=0.0.8 && <0.1,
    containers >=0.3 && <0.5,
    process >=1.0 && <1.2,
    directory >=1.0 && <1.2,
    filepath >=1.1 && <1.4,
    base >=4.2 && <5

Executable live-sequencer-gui
  If flag(gui)
    Build-Depends:
      wx >=0.12.1 && <0.13,
      wxcore >=0.12.1 && <0.13,
      stm >=2.2 && <2.4,
      transformers >=0.2.2 && <0.4,
      explicit-exception >=0.1.5 && <0.2,
      parsec >=2.1 && <3.2,
      pretty >=1.0 && <1.2,
      midi-alsa >=0.1.1 && <0.2,
      midi >=0.1.5 && <0.2,
      alsa-seq >=0.5 && <0.6,
      alsa-core >=0.5 && <0.6,
      data-accessor-transformers >=0.2.1 && <0.3,
      data-accessor >=0.2.1 && <0.3,
      strict >=0.3.2 && <0.4,
      utility-ht >=0.0.8 && <0.1,
      containers >=0.3 && <0.5,
      process >=1.0 && <1.2,
      directory >=1.0 && <1.2,
      filepath >=1.1 && <1.4,
      base >=4.2 && <5
  Else
    Buildable: False

  Hs-Source-Dirs: src
  Main-is: GUI.hs
  Other-Modules:
    ALSA
    Event
    IO
    Exception
    Module
    Option
    Option.Utility
    Controls
    ControlsBase
    Program
    Rewrite
    Rule
    Step
    Term
    Time
    Type
    Log
    Paths_live_sequencer
    Utility.NonEmptyList
    Utility.Concurrent
    Utility.WX

  GHC-Options: -threaded -Wall
  If impl(ghc>=7.0)
    GHC-Options: -fwarn-tabs -fwarn-incomplete-uni-patterns

  If flag(httpServer)
    Hs-Source-Dirs: http/enable
    Other-Modules:
      HTTPServer
    Build-Depends:
      httpd-shed >=0.4 && <0.5,
      network >=2.3 && <2.4,
      cgi >=3001.1 && <3001.2,
      html >=1.0 && <1.1
  Else
    Hs-Source-Dirs: http/disable

  Other-Modules:
    HTTPServer.Option
    HTTPServer.GUI

Executable live-mplayer-control
  If flag(mplayer)
    Build-Depends:
      midi-alsa >=0.1.1 && <0.2,
      midi >=0.1.5 && <0.2,
      alsa-seq >=0.5 && <0.6,
      alsa-core >=0.5 && <0.6,
      unix >=2.4 && <2.6,
      directory >=1.0 && <1.2,
      transformers >=0.2.2 && <0.4,
      base >=4.2 && <5
  Else
    Buildable: False

  Hs-Source-Dirs: src
  Main-is: MPlayer.hs

  Other-Modules:
    Option.Utility

  GHC-Options: -threaded -Wall
  If impl(ghc>=7.0)
    GHC-Options: -fwarn-tabs -fwarn-incomplete-uni-patterns