software

Lubyk the library

The library consists of many objects and open source libraries carefully selected and adapted to work together in a seamless way. Objects can be directly used in Lua scripts by requiring ‘lubyk’.

Mimas the editor

Mimas is the graphical interface to work with Lubyk “nodes” (Lua scripts that wrap some functionality) in a graphical way to compose larger projects (eventually across the network). The editor is built with the library.

  • Raspberry Pi live coding Lua

    A couple of days ago, the Raspberry Pi was announced. Needless to say that this hardware is the perfect complement to the software provided by lubyk.

    Raspberry Pi project

    The goal is to create a debian based OS (eventually installed on sd-cards) to ease the adoption on lubyk (and Lua) as a scripting platform for RPi.

    Why lubyk ?

    Lubyk is a very good environment to program that removes most of the burden related to some difficult programming tasks, mainly:

    1. Build and installation (not needed with a scripting language).
    2. Boilerplate code to connect to hardware and such tasks (not needed by using the provided prototypes).
    3. Networking and configuration (not needed because lubyk transparently uses Zeroconf and ZeroMQ for networking).
    4. Control and parametrization (lubyk provides easy to use controls)

    controls

    Why Raspberry Pi ?

    Apart from its very low price, this hardware has some very good arguments to serve for educational, low-fi gaming and artistic needs:

    1. Very decent CPU (700Mhz ARM processor)
    2. Good GPU (supporting OpenGL ES 2.0, full hd and mpeg4 decoding)
    3. Small size (less then 9×6 cm)
    4. Networking (10/100 RJ45 ethernet)
    5. USB (two ports).
    6. Good IO (8 × GPIO, UART, I²C bus, SPI bus).

    What now ?

    Here is a list of the required steps to produce a first OS image:

    1. Port the linux-core to linux. [done 2012-03-07]
    2. Fix build to use native lua/luajit (remove the need for RTLD_GLOBAL). [done 2012-03-08]
    3. Fix build for to make it debian friendly (use debian libs, install location, etc).
    4. Build a debian installer.
    5. Compile for ARM.
    6. Create an empty debian OS with ARM target.
    7. Install and setup launch scripts for lubyk on the OS.
    8. Test, fix and repeat.

    If anyone wants to join into this effort (or has special needs for what should be installed by default on the OS), please drop a line on the mailing-list.

    Gaspard Bucher
    2012-03-08 - comments (0)
  • first run on linux

    All required modules to run lubyk on linux now compile and I managed to open the editor:

    lubyk2

    First run of the editor on linux

    As you can see, there are many bugs:

    • missing host names
    • morph server not shown
    • a very rubato timer that reminds me of the first experiments with rubyk
    • missing menus
    • etc

    But at least, the porting of mdns and other OS specific parts are well advanced and having something to see and play with will surely drive motivation !

    Gaspard Bucher
    2012-03-06 - comments (0)
  • Connecting controls

    This is just a short post to show what Lubyk currently looks like.

    The big picture

    This shows the important parts of the editor with a remote process showing a window (the green thing), the log window (right below), the patch view where nodes and processes are connected together and the control view on the right.

    big picture

    For those new to Lubyk, the nodes (the things called “w” or “p”) are boxes with inlets and outlets that simply execute a Lua script inside a remote process connected with ZeroMQ. By double clicking on a node, your favorite editor (vim here) opens the remote script (through WebDAV):

    edit node

    Full script of node “w”

    Parameters / controls

    Declaring parameters in a Lua script is as easy as this:

    defaults {
      sat = 0.5,
      temp = 35,
    }
    

    These two parameters will then appear when changing connections for a control (see image below). Controls can have multiple “connectors” (like a pad does) or just a single one (like the slider shown here).

    Once a control is connected to a node’s parameter, changing the value simply updates the value of the given variable in the Lua script, eventually triggering hooks like “param.changed”.

    controls

    Connecting node parameters and controls.

    Debug

    Since the scripts run remotely, we cannot read the console for debug information, errors and printed values. We thus use a log window as shown bellow that gets all “print” “warn” and error notifications from remote processes:

    debug

    Informations, warnings and errors in the log window.

    Clicking on a line in the log window will open the culprit at the concerned line in the text editor.

    Gaspard Bucher
    2012-03-04 - comments (0)
  • Choosing an icon

    To ease deployment and installation on mac os X, we have decided to create a single object (an application) which you can simply drag or give to friends. The application will install a few files to work from the command line but all the examples/documentation/libraries will be in the resource folder.

    To build this application, we need an icon. Nicolas Joos has been working on an icon some time now and after settling for the four rounded shape, we have to build an “Application” icon.

    Before diving into the sketches and propositions, here is what I think this icon should convey (most important first) :

    1. stability (we can rely on lubyk: it works)
    2. organic (“ecosystem”, sharing, alive)
    3. strangeness (arty)

    Logo

    Here were some of the propositions for the icon:

    all_lubyk

    first ideas

    lubyk_logo_V2

    developments over the ‘animal’ idea

    We settled for the four circle shape (cells, ecosystem, proximity, etc):

    v4_bleu

    logo and font choice

    Application icon

    Now that we have the logo, it is time to build the actual “app” icon: something that has to live in a dock, a filesystem, etc. We want an icon that stands out a little by it’s strangeness, something appealing but not too candy.

    Here are the last contenders for the application icon in different contexts:

    all

    in a large filesystem icon view

    all_list

    small version when listed in the Finder

    dock

    in the dock

    open_apps

    in the application tab

    Final choice

    Not decided yet…

    Gaspard Bucher
    2011-09-03 - comments (2)
  • Network loop to test latency

    Now that I can create and remove links between processes, I thought of a little experiment:

    What happens if I create a loop ?

    loop

    Here’s the content of both scripts:

    counter

    inlet('bang', 'Send next number on [bang].')
    pass = outlet('pass', 'Increasing numbers [float]')
    
    function inlet.bang(i)
      i = i + 1
      print(i)
      pass(i)
    end
    
    -- initiates the loop on script save
    pass(0)
    

    loop

    inlet('bang', 'Send next number on [bang].')
    pass = outlet('pass', 'Increasing numbers [float]')
    
    function inlet.bang(i)
      i = i + 1
      pass(i)
    end
    

    results

    I stated the script and I let it run for 30s. The counter reached 241’558 in these 30 seconds which means 8’050 messages per second.

    The monitor (open during the test) shows 2.4Mb/s of data being transferred.

    The same loop in a single process gives this result 1’298’724 (43’290 messages per second). Note that I had to change the “counter” so that it uses “app:post” to send in order to avoid a stack overflow error (in-process messaging is the same as a function call):

    local loop

    Updated “counter” inlet function:

    function inlet.bang(i)
      i = i + 1
      print(i)
      app:post(function()
        -- post to avoid stack overflow
        count(i)
      end)
    end
    
    count(0)
    

    network overhead

    A local loop takes 23μ s with the post overhead. It takes 124μ s when going through the network. This is roughly 0.1 ms latency overhead. This is not too bad.

    Another thing to take into account is that sending is a blind process unless feedback is setup. This means that the receiver should work faster or the incoming mailbox will grow. We could overcome this issue by providing other types of links if needed.

    Gaspard Bucher
    2011-06-29 - comments (0)
  • Messaging between processes

    An important milestone has been reached today: messaging between processes works and displays in Mimas as in the example below:

    messaging in mimas

    ‘a’ and ‘b’ are different processes, possibly on different boxes

    plug & play

    The connection between process “a” and “b” does not depend on the order in which the processes are started and does not require complicated IP configuration. The link is simply defined in the source (sender) with a fully qualified url. For example, this is the yaml definition for the counter in process “a” :

    counter:
      x: 30
      y: 45
      hue: 0
      links:
        count:
          /b/play/in/trigger: true
        params:
          tempo: 580
    

    The links are defined as a dictionary so that link removal can be managed by setting the url to false.

    resiliency

    If “a” or “b” goes offline, the link goes into “disconnected” state. When the missing process comes back, the link automatically reconnects and the messages are transmitted on the line.

    links in the editor

    As highlighted in the image above, links properly display in the editor, even if we cannot create them there yet and there are some display bugs.

    technical details

    The receiver has a single zmq “PULL” socket announced by ZeroConf and the sender pushes the data through this socket along with the target url. When an object is taken offline, ZeroConf informs the other party and the sender stops sending.

    Gaspard Bucher
    2011-06-26 - comments (0)
  • Managing code for distributed processes

    We are working on a storage system for patch information that makes it easy to work with versioning tools such as git/mercurial/bazaar and such.

    Here is an overview of a project’s file organization (on local filesystem or remote on Mnémosyne server):

    ... <== base project directory. This is the current dir for the process
    .../A              <== Everything for process with role "A" 
    .../A/_patch.yml   <== Patch for process with role "A" 
    .../B              <== Everything for process with role "B" 
    .../B/_patch.yml   <== Patch for process with role "B" 
    .../B/foo.lua or
    ...[node:url()].lua <== Code for node 'foo' in process 'B'
    .../lib             <== searched for required code

    The idea with this structure is that all the information for the different processes (potentially on different machines) is stored in a single folder. With the “Mnémosyne” server, the process will simply query the server with the required node url (which contains the process name) and the server will serve the code (by reading the filesystem).

    The “Mnémosyne” server will save every code changes by registering for notifications and using git on the project’s folder.

    Gaspard Bucher
    2011-04-09 - comments (0)
  • Sync between editor and process

    Mimas editor

    This is the first tangible result concerning the graphical interface after the switch to Lua and Qt. The development in the new environment is a joy and things advance at a fast pace.

    In this new context, writing tests by mocking parts of the system is really easy with Lua and greatly simplifies test driven development (especially for graphical elements). Difficult conceptual issues such as the relation between model and views remain but testing/fixing is just “command+R” away.

    lk.Process sync

    We have managed to make sync between lk.Process and editor.Process work. This implies many tools working together such as mdns (Zeroconf network discovery), zmq (zmq networking library), msgpack (binary serialization), mimas (Qt bindings), yaml (text serialization) and editor (Mimas application objects).

    In the example below, the process has been automatically discovered on the network, patch information fetched and the process is drawn in the editor.ProcessView .

    process view

    Patch creation

    Another big advance highlighted by this example is that patch definition works (with automatic loading of required lua code). Here is the “simple.yml” file with external “add” and “store” classes. We could have serialized these in the patch by using “script” instead of “class”.

    add:
      class: add
      hue: 0.9
      x: 70
      y: 95
      links:
        sum: store/in/value
      params:
        val1: 0
        val2: 5
    
    store:
      class: store
      hue: 0.2
      bug: 0.7
      x: 90
      y: 155
    

    The “add.lua” file contains this:

    inlet('val1', 'First value [number].')
    inlet('val2', 'Second value [number].')
    sum = outlet('sum', 'Sends sum of first and second values [number].')
    
    val1 = val1 or 0
    val2 = val2 or 0
    
    function inlet.val1(v)
      val1 = v
      sum(val1 + val2)
    end
    
    function inlet.val2(v)
      val2 = v
      sum(val1 + val2)
    end
    

    The “store.lua” file is like this:

    inlet('value', 'Stores the value')
    
    function inlet.value(v)
      value = v
    end
    
    Gaspard Bucher
    2011-03-31 - comments (0)