OpenMusic

Visual Programming | Computer-Assisted Composition

Writing User Libraries

We show in this page the way to write user libraries for OM. Section Writing code for OM may be necessary to understand this text. Libraries are specialized set of classes and methods written in Common-Lisp and loaded dynamically in OM.

Here you can download a template user-defined library: https://github.com/openmusic-project/my-lib

Unzip this file if you want to try to load it in OM and/or to use it as a template for writing a new library.

GitHub-project downloads append the name of the branch to the folder name (“my-lib-masyer”): rename it “my-lib” to comply with the following requirements.

Loading Libraries in OM

All the registered OM libraries are acessible from the Library window.

Load one libray by double-clicking the bottom part of the lib icon, or by right-clicking/control-clicking on it and choosing “Open/Load Library” in the contextual menu.

The library classes and functions will then be available in the same window, or from the general patch menus “classes” and “Functions” under “User Libraries”.

There are several ways of loading a library in OM.

The Library Folder

A user library is directory that contains source code and resources needed to build a library in OM. This directory must respect some constraints :

MyLib.lisp is the only necessary element. The other ones are optionals.
Note that the file is called “MyLib.lisp” and not “MyLib 1.0.lisp”.

Loading the Code

When you load a library from OM, the file MyLib.lisp is loaded. It should contain the instructions for loading the rest of the library source code.

Here is an example of how to proceed with a sample library:

(defvar *MyLib-files* nil)

(setf *MyLib-files* 
  (list
    (make-pathname :directory (append (pathname-directory *load-pathname*) (list "sources")) :name "src-file1")		
    (make-pathname :directory (append (pathname-directory *load-pathname*) (list "sources")) :name "src-file2")	
    (make-pathname :directory (append (pathname-directory *load-pathname*) (list "sources")) :name "src-file3")	
))

(mapc #'compile&load *MyLib-files*)

*load-pathname* is a global variable that records the path of the file being loaded. In our case, this is the path to our MyLib.lisp file, hence to our library folder.

We use this path in order to build the other pathnames to be loaded (in this case […]/MyLib/sources/src-file1.lisp, etc.)

compile&load compiles the corresponding Lisp files if needed and load the .cfsl (or .*fasl) compiled files.

Sub-Packages

The classes and functions defined in the library can then be organized in sub-packages of this library.

When a library is loaded, the variable *current-lib* is set to this library.

You can use functions omng-make-new-package, AddPackage2Pack, AddClass2Pack, AddLispFun2Pack, AddGenFun2Pack (detailed in Writing code for OM) for setting your library package architecture.

There exists a function fill-library that creates and fill the subpackages from a list of the form (sub-pack-name subpack-lists class-list function-list class-alias-list)

For example:

(om::fill-library '(
	("SubPackage1" nil nil (Addition) nil)
        ("SubPackage2" nil nil (Multiplication) nil)
))

… creates 2 sub-packages and and place the functions addition and multiplication in it.

Icons

Icons are bitmap files (currently supported formats: tif, bmp, png, jpg…) to be put in the MyLib/resources/icon/ directory. The file name must be a number which will correspond to the icon identifier in OM.

Icon identifiers in a library can be used only for the library.

For example, if a file called “176.tif” representing this icon : is in MyLib/resources/icon/, then when you define the function “multiplication”:

(defmethod! Multiplication ((self number) (arg number))
	:initvals '( 10 10 )
	:indoc '("First operand" "Second operand")
	:icon 176
	:doc "Multiply 2 things. Things can be numbers, lists, chords."
	(* self arg) )

… the icon is and not that is the correponding icon for 176 in OM.

If you want to use an icon defined in the OM resources use a list with the iconID, for example:

(defmethod! Addition ((self number) (arg number))
	:initvals '( 10 10 )
	:indoc '("First operand" "Second operand")
	:icon '(176)
	:doc "Adds 2 things. Things can be numbers, lists, chords."
	(+ self arg) )

Dependencies

If your library needs to load other libraries use the function require-library.

(require-library "OMAlea")

Example patches and in line tutorials

Your library may contain some example patches or in line tutorials for the objects (functions, classes) it contains.

Example patches can be loaded from OM using the “Help/Import Tutorials” menu. Just put patches in a directory called “examples” in the library folder.

In line tutorial patches are opened by selecting an object in a patch and pressing ‘T’ key. Create a patch with the same name as your function or class and put it in in a directory called “inline” in the library folder.