Impromptu (programming environment)

This is an old revision of this page, as edited by 62.197.126.229 (talk) at 18:40, 1 June 2011 (Independant academic sources referencing Impromptu: fixed the links). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
This article is about the programming language. For other uses, see Impromptu (disambiguation).

Impromptu is a Mac OS X programming environment for composers, sound artists, VJs and graphic artists with an interest in live or interactive programming. Impromptu is a Scheme language environment, a member of the Lisp family of languages.

Impromptu
ParadigmFunctional, multi-paradigm
Designed byAndrew Sorensen
First appeared2005
Stable release
2.5
Typing disciplineDynamic & static
OSMac OS X
Websitehttp://impromptu.moso.com.au/

Its key features are :

  • A fully dynamic Scheme environment. You can evaluate any portion of code in the builtin editor while the program is running, which means you can (re)define variables or functions live, the changes take effect immediately.
  • Asynchronous scheduling. Impromptu allows a programmer to create and schedule code for future execution as well as data events such as notes and graphics objects. Once an event is scheduled, execution continues. Looping is performed by using an idiom called "temporal recursion" which works by having a function asynchronously schedule a future call to itself as its final action.
  • Extensive library based on a tight integration with Mac OS X. Audio synthesis is done via Audio Units and graphics/video are composed using QuickTime, Quartz, Core Image, OpenGL etc.. You can also call Objective-C code from the editor and call back into the Scheme interpreter from your own Objective C frameworks.
  • Impromptu includes a static type inferencing compiler for a minimal functional language similar to Scheme but designed for systems style programming. The compiler uses LLVM for backend compilation to x86. You can find out more about the compiler and language here.
  • Impromptu's Scheme Interpreter was initially built from the TinyScheme 1.35 baseline. The interpreter has been substantially modified since Impromptu's initial release.
  • Free to use, but not open-source.

Livecoding Screencast

Andrew Sorensen's "A Study In Keith" (sound starts about 2 minutes in)

You can watch more of Andrew's screencasts here

Examples

Some very simple musical examples

;; first define an instrument
(define dls (au:make-node "aumu" "dls " "appl"))
;; next connect dls to the default output node
(au:connect-node dls 0 *au:output-node* 0)
;; lastly update the audio graph to reflect the connection
(au:update-graph)

;; play one note by itself
(play-note (now) inst 60 80 (* *second* 1.0))

;; play three notes together
(dotimes (i 3)
   (play-note (now) inst (random 60 80)  80 (* *second* 1.0)))

;; play a looping sequence of random notes
(define loop
   (lambda (time)
      (play-note time inst (random 40 80) 80 1000)
      (callback (+ time 8000) 'loop (+ time 10000))))

;; start the loop
(loop (now))

;; stop the loop by defining loop to be null
(define loop '())

;; define a new loop to play a repeating sequence of notes
;; with a small random twist
(define loop
   (lambda (time pitches)
      (play-note time inst (car pitches) (random 40 80) 8000)
      (callback (+ time 4000) 'loop (+ time 5000)
                (if (null? (cdr pitches))
                    (list 60 63 62 (random 65 68) 68 59)
                    (cdr pitches)))))

(loop (now) '(60 63 62 67 68 59))

;; stop the loop by defining loop to be null
(define loop '())

A very simple graphics example which plays back a pixellated movie

(define canvas (gfx:make-canvas 640 480))

(define mov (gfx:load-movie "/tmp/hollywood_flick.mp4"))
(define dur (gfx:get-movie-duration mov))
(define fx (gfx:make-filter "CIPixellate"))

(define loop
   (lambda (pos) 
      (let* ((frame (gfx:get-movie-frame mov pos))
             (filtered (gfx:apply-filter fx frame)))
         (gfx:draw-image (now) canvas filtered 1 '(0 0 640 480))
         (objc:release (+ (now) 5000) frame filtered)
         (if (< pos dur)
             (callback (+ (now) (/ *samplerate* 24)) 'loop (+ pos 1/24))))))

(loop 0)

Writing some on-the-fly audio DSP code

;; simple DSP code example
(define aucode1 (au:make-node "aumf" "code" "MOSO"))
(au:connect-node aucode1 0 *au:output-node* 0)
(au:update-graph)

;; simplest of the simple - whitenoise
(au:code:load aucode1 "dsp" (lambda (sample time channel data)
                               (* 0.1 (random))))


;; sinewave with phase information maintained
(define sinewave
   (lambda (sample time channel data)
      (let ((phase (objc:data:get-double data channel))
            (freq (objc:data:get-double data 2))
            (inc (* 2.0 3.141592 (/ freq 44100))))
         (objc:data:set-double data channel (+ inc phase))
         (* 0.3 (sin (+ inc phase))))))

;; create a data object to share with aucode1
(define dat (objc:data:make (* 8 3)))
;; set frequency in dat[2] save dat[0] and dat[1] for left and right phase
(objc:data:set-double dat 2 220.0)
;; load sinewave with dat into aucode1
;; which will also replace whitenoise on-the-fly
(au:code:load aucode1 sinewave dat)

References

Papers by Andrew Sorensen

Independant academic sources referencing Impromptu

See also