# Barry

Barry is my system for performing live music by coding in a stateless Forth-like programming language, to change audio processing algorithms while they are running.

Stateless means everything is a function of time, similar techniques are used in bytebeat / rampcode.

# 1 Try

you can try barry online:

mathr.co.uk/barry/v2 (solo, reliable)

v3.barry.mathr.co.uk (collaborative, experimental)

see the syntax reference and vocabulary.

# 2 Source Code


git clone https://code.mathr.co.uk/barry.git

# 3 Components

barrington, barry, barrence, bazc-simple, bazc-unified, modded Troop, web

# 3.1 barrington

barrington is an interpreter library for a postfix language (similar in some ways to Forth, but it’s not a Forth)

required packages

  • gcc
  • make

# 3.2 barry

barry is barrington hooked up to an audio backend

required packages

  • gcc
  • make

optional packages

  • libjack-dev (for JACK audio backend)
  • libsdl2-dev (for SDL2 audio backend)
  • libc6-dev (for OSS audio backend)
  • libsndfile-dev (for SNDFILE audio backend)

you need to edit Makefile and barry/barry.c if you want to exclude one or more audio backends

# 3.3 barrence

barrence is a helper for live-coding .baz: it collects blocks that are evaluated individually (wrapped in :{ :}) and outputs the most recent state of the dictionary in topologically sorted order

required packages

  • cabal
  • ghc

required Haskell packages

  • containers
  • fgl
  • parsec

# 3.4 bazc-simple

bazc-simple is a fast compiler from .baz to .c which tracks types of arguments, through stack and locals, to determine which overloaded primitive functions to call

required packages

  • cabal
  • ghc

required Haskell packages

  • containers
  • mtl
  • parsec

# 3.5 bazc-unified

bazc-unified is a slow compiler from .baz to .c which uses unification to determine which overloaded primitive functions to call (experimental)

required packages

  • cabal
  • ghc

required Haskell packages

  • containers
  • mtl
  • parsec

# 4 Sound

# 4.1 Barry

barry plays sound using SDL2, JACK or OSS, and can write audio files with SNDFILE

note: sound can be loud with unpleasant frequencies and large DC offsets

quick start:

: audio { c t -- o } t i8 ;
RUN audio
0 -> time
1 -> increment

# 4.2 Clive

clive is a system for live-coding audio in C, and with bazc-simple you can embed live-coded BAZ in clive

(not so) quick start

install barrence and bazc-simple:

git clone https://code.mathr.co.uk/barry.git
cd barry
cabal install

make sure cabal-install results are accessible in your shell’s $PATH environment variable

launch Troop server:

git clone https://github.com/claudeha/Troop.git
cd Troop
git checkout feature-barry-interpreter
python3 run-server.py

launch clive system:

git clone https://code.mathr.co.uk/clive-core.git
cd clive-core
git checkout barry
cd client
ln -s ../../barry/barry.h
cd ..

launch Troop client from within clive working directory

cd clive-core/client
python3 ../../Troop/run-client.py

select Barry from the language dropdown

code to enter into Troop to get started

: audio { c t -- o } t i8 ;
C-ABI barry { I64 I64 -- I8 } audio ;

evaluating this code in Troop with Ctrl-Enter, sends it as a block to barrence, which writes out the current document to barry.baz, which clive-client notices and launches make; the local-native-sse.mk file has rules to compile .baz to .c using bazc-simple; the main go.c in clive #includes barry.c, calls barry() and has some small code to increment input time and rescale the output; clive-client recompiles the C code into a shared object, which clive-server reloads and hot-swaps the code, preserving heap memory.

a lot of moving parts to go wrong, but the compiled code is more efficient (in both time and space).

# 4.3 Web

barry can be compiled with emscripten to run in the web browser. first install, activate, and source emscripten variables in the shell. then:

make clean
emmake make web/barry.html SDL2="-s USE_SDL=2"

for technical reasons, you have to serve the files over http(s)://, loading from a file:// URL won’t always work.

the files you need to serve are:


where the source code tarball must correspond to the compiled JS+WASM. you can use make tarball to create it.

# 5 Syntax

mostly Forth-like


\ backslash to the next end of line is a comment
( anything between parentheses is a comment )
( comments ( can ( be ( nested
  over ) multiple )
  lines )

# 5.2 Integers

the default integer type is 64bit signed (i64)

023 ( octal )
123 ( decimal )
0x3 ( hexadecimal )
+2  ( positive )
-2  ( negative )

the integer types available include

u8 u16 u32 u64 ( unsigned )
i8 i16 i32 i64 ( signed )

# 5.3 Floats

the default float type is 64bit double (f64)

0.        ( with digits before a dot )
1.23      ( with digits before and after a dot )
+1.23     ( positive )
-1.23     ( negative )
1.23e10   ( with exponent )
1.23e+10  ( with positive exponent )
1.23e-10  ( with negative exponent )

the float types available include

f32 f64 ( floating point )

# 5.4 Symbols

anything else is a symbol

# 5.5 Compilation Mode

: name def ini tio n ;
: name { arg ume nts -- out put } def ini tio n ;
: name { arg ume nts | var iab les -- out put } def ini tio n ;

arguments and variables (before the --) are self-fetching with varname

they can be set with -> varname

# 5.6 Immediate Mode

40 2 + . cr

# 6 Vocabulary

# 6.1 Output

.    ( pop atom from the stack and print it )
cr   ( print a newline )

# 6.2 Binary Operators

+ - * / %     ( arithmetic, for integers and floats )
<< >> & | ^   ( bitwise operators, for integers only )

# 6.3 Unary Operators

! ~                                    ( logical not, bitwise complement)
u8 i8 u16 i16 u32 i32 f32 u64 i64 f64  ( numeric cast )

# 7 Bugs

  • the SNDFILE audio backend is hardcoded to barry.wav duration about 90mins

  • the SDL2 audio backend cannot be used in an SDL2 program (it assumes it is the only thing doing SDL2 stuff)

  • symbol_new() is O(n), which makes the table quadratic in symbol count

  • probably some more

# 8 Changelog

  1. initial release
  2. usability improvements for web
  3. collaborative version using Etherpad

# 9 License

barry – bytebeat livecoding environment

Copyright (C) 2020 Claude Heiland-Allen

Source code under GNU Affero General Public License version 3.