# 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/local-native-sse.sh
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 #include
s 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:
index.html
barry.js
barry.wasm
barry-${VERSION}.tar.xz
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
# 5.1 Comments
\ 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
- initial release
- usability improvements for web
- 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.