Claude Heiland-Allen

2020-03-10

barry

bytebeat livecoding environment

https://mathr.co.uk/barry

try

you can try barry online:

https://mathr.co.uk/barry/v2

source code

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

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

components

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

barrington

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

required packages

barry

barry is barrington hooked up to an audio backend

required packages

optional packages

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

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

required Haskell packages

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

required Haskell packages

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

required Haskell packages

sound

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

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 #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).

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.

BAZ syntax

mostly Forth-like

comments

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

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 )

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 )

symbols

anything else is a symbol

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

immediate mode

40 2 + . cr

vocabulary

output

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

binary operators

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

unary operators

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

bugs

changelog

  1. initial release
  2. usability improvements for web
barry -- bytebeat livecoding environment
Copyright (C) 2020  Claude Heiland-Allen <claude@mathr.co.uk>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.