Lisbit is a programming language designed for creating 1-bit audio. It works by running the program that you write once for every frame of the audio output, passing in the current time as a variable called `time`

. If the last statement in your program returns `on`

(Lisbit's version of what other languages might call "true") the audio is turned on for that frame. By alternating which frames end with `on`

, you can make the audio quickly turn on and off, creating audible sound.

Code in Lisbit consists of nested lists. Each list starts with an `(`

and ends with a `)`

. Items in lists are separated by whitespace. Items in lists can be *numbers*, *symbols*, or other *lists*.

*Numbers* are just normal numbers. They can be positive or negative and they can have a decimal place. You can also put commas where ever you you want in them, which will simply be ignored without changing the meaning of the number. Here are some examples:

```
500
-30.25
10,000.56
1,00,00.00,00
```

*Symbols* are names for things. If Lisbit runs into a symbol when it's trying to read code, it will replace it with whatever value you've bound to it using the `define`

command. Symols can contain letters, `!`

, `?`

, and `-`

. They can also contain numbers as long as they aren't the first character. Here are some examples:

```
this-is-a-symbol
is-this-a-symbol?
symbol3
```

You can also add comments where ever you want by putting text between `/*`

and `*/`

. Comment will be ignored by Lisbit and just treated like whitespace, so feel free to use them to leave notes to yourself and anyone else who might be looking at your code.

When Lisbit is trying to read code, it does the following:

- Looks at the first list in the program.
- It expects the first item in the list to be a symbol with a command bound to it
- If that command is function, then it first tries to evaluate every other item in the list.
- It passes the rest of the list into the command as arguments
- The command will return a value, and that will be the result of evaluating the list.
- Moves on the the next list.

There are two types of the commands that can be run: *functions* and *macros*. Arguments passed to *functions* get evaluated as code before the function sees them, but arguments to *macros* get passed in directly, so the macro can choose whether it wants to evaluate them or not. This lets you build your own custom languages structures, that can be pretty powerful. Here are some examples of *functions* and *macros* getting called:

```
(add 1 1)
(mul (add 1 1) (sub 1 1))
(define foo 5)
(add foo 10) /* This is treated the same as (add 5 10) */
(define double (function (my-number) (add my-number my-number)))
(double 5) /* This is treated the same as (add 5 5) */
```

While Lisbit gives you all the tools you need to create audio, it doesn't really point you in any particular direction when it comes to actually producing sound. This can be nice, since it lets you experiment with a lot of different techniques, but it can also make it hard to know how to start. Hopefully this section will help you figure out how to make basic notes.

You ears hear sound whenever waves of pressurised air hits your eardrum, causing it so move vibrate and send signals to your brain. If the waves of pressure are short, switching quickly between high pressure and low pressure, you'll hear a high pitched sound. If they're longer, you'll hear a low pitched sound. The larger the difference in pressure, the louder the sound will be.

Lisbit only offers you two options for pressure: `on`

and `off`

. This doesn't make it easy to create the complex sounds or the real world, but it can make some pretty interesting sounds and provide a fun constraint for anyone making audio.

You can create alternating waves in Lisbit by writing functions that will return `on`

or `off`

depending on what the time is. Here's an example of a function like that:

```
(define tone (function (time hz)
(eq? (mod (floor (mul time hz)) 2) 0)))
```

This function will return a value that will switch on and off `hz`

times per second. If you pass in a high value for `hz`

you can use it for a hight tone, and if you pass a low value for `hz`

you can use it for a low tone.

Since the values `tone`

returns are just regular *booleans* you can pass them to functions and modify or combine sounds. Here's an example:

```
(and
(tone time 300)
(tone time 2000))
```

This example might not sound particularly pleasant, but with some creativity you can use these techniques to create some really cool sounds.

`time`

- *number* - the current time in seconds.

`on`

- *boolean* - a truthy value.

`off`

- *boolean* - a falsey value.

`define`

Binds a value to a symbol.

*symbol* - The name of the symbol to bind to.

*boolean*/*number*/*list*/*function* - The value to bind to it.

```
(define pi 3.14159)
(define double (function (x) (mul x 2)))
(define no (eq? 5 6))
(define shopping-list (list oranges bread fish))
```

`function`

Returns a new function. It also binds the symbol 'recur' to itself so you can make recursive calls.

*symbol*/*list* - A symbol that will be bound to the list of parameters, or a list of symbols that will each be bound to one of the parameters.

*expression* - The code that will be executed whenever the function is called.

```
(function (x y) (mul x y))
(function numbers (apply mul numbers))
(define factorial (function n (if (eq? n 1) 1 (mul n (recur (sub n 1))))))
```

`macro`

Returns a new macro. This works like a function, but it doesn't evaluate its arguments so you can evaluate them yourself.

*symbol*/*list* - A symbol that will be bound to the list of parameters, or a list of symbols that will each be bound to one of the parameters.

*expression* - The code that will be executed whenever the macro is called.

```
(define unless
(macro (condition if-on if-on)
(if (not (eval condition))
(eval if-off)
(eval if-on))))
(define my-quote (macro (arg) arg))
```

`quote`

Return an object without evalutating it.

*any* - The object to be quoted.

`begin`

Evaluate pieces of code in sequence

*expression* - The code to evalute first.

*more expressions, etc.*

*expression* - The code to evaluate last. The return value of this expression will be used as the return value of `begin`

.

```
(begin
(define a 1)
(define b 2)
(add a b))
```

`begin`

Evaluate the first argument. If the result is `on`

return the result of evaluating the second argument. Otherwise return the result of the third argument if it exists.

*expression* - Condition to evalute.

*expression* - The result if it's `on`

.

*expression* - The result in all other cases.

```
(if (eq? 1 1) 1 0)
(if (lt? (add 1 1) (mul 1 1))
(add 100 100)
(mul 100 100))
```

`cond`

Return the result of evaluating second item of the first argument who's first item evaluates to `on`

.

*list*

*expression* - Condition to evalute.

*expression* - The result if it's `on`

.

*more lists, etc.*

```
(cond
((gt? 1 3) 1)
((gt? 2 3) 2)
((gt? 3 3) 3)
((gt? 4 3) 4) /* 4 gets returned */
((gt? 5 3) 5))
```

`and`

Evaluates its arguments until it finds one that returns `off`

, in which it returns `off`

. If none of them are `off`

then it returns `on`

.

*expression* - First condition to test

*more expressions, etc.*

```
(and on on)
(and (lt? 0 1) (gt? 0 -1))
```

`or`

Evaluates its arguments until it finds one that returns `on`

, in which it returns `on`

. If none of them are `on`

then it returns `off`

.

*expression* - First condition to test

*more expressions, etc.*

```
(or on off)
(or on on)
(or (eq? 1 1) (eq? 1 0))
```

`eval`

Evaluate a list as code

*list* - The list to evaluate.

```
(define code (list add 1 1))
(eval code)
```

`list`

Create a list out of the arguments passed in.

*any* - The first list item.

*more of any, etc.*

```
(list 1 2 3)
(list 1 (add 1 1) (add 1 1 1))
```

`apply`

Call a function with arguments pulled from a list.

*function* - The function to call.

*list* - The arguments to the function.

```
(apply add (list 1 2 3))
(apply and (list on on))
```

`head`

Return the first item in an array.

*list* - The list to get the item from.

```
(head (list 1 2 3))
```

`tail`

Return a list with every item from a list except the first element.

*list* - The list to get the items from.

```
(tail (list 1 2 3))
```

`length`

Get the length of a list.

*list* - The list you want the length of.

```
(length (list 1 2 3))
(length (list))
```

`index`

Get the item in a list that's located at a specific index.

*list* - The list you want the item from.

*number* - The index of the item. The first item of the list is at index 0.

```
(index (list 1 2 3) 0)
(index (list 1 2 3) (add 1 1))
```

`print`

Prints whatever values you pass to it to a special console you can use for debugging. It also returns its arguments without modifying them, so you can easily stick `print`

anywhere you want to know the value of something.

*any* - The first item to print out.

*more of any, etc.*

```
(print 5)
(print 1 2 3)
(print (add 1 1))
(add (print 1) 1)
```

`add`

Add numbers together.

*number* - The first item to add.

*more numbers, etc.*

```
(add 1 1)
(add 2 2.5 3 4.5)
```

`sub`

Subtract numbers from each other.

*number* - The starting number.

*number* - The first number to subtract from it.

*more numbers, etc.*

```
(sub 4 2)
(sub 10 5 3 2 1)
```

`mul`

Multiply numbers together.

*number* - The first number to multiply.

*more numbers, etc.*

```
(mul 10 10)
(mul 10 20 30 40)
```

`div`

Divide numbers by each other.

*number* - The starting number.

*number* - The first number to divide it by.

*more numbers, etc.*

```
(div 100 10)
(div 10 2 2)
```

`div`

Get the remainder of dividing numbers by each other.

*number* - The starting number.

*number* - The first number to divide by it to get a remainder.

*more numbers, etc.*

```
(mod 5 2)
(mod 13 5 2)
```

`exp`

Raise numbers to the power of each other.

*number* - The starting number.

*number* - The first power to raise it to.

*more numbers, etc.*

```
(exp 10 2)
(exp 10 2 3)
```

`log`

Get the logarithm of a number with a specified base.

*number* - The number your getting a logarithm of.

*number* - The base of the first logarithm operation.

*more numbers, etc.*

```
(log 256 2)
(log 100,000,000 10 2)
```

`min`

Get the lowest number from all the arguments.

*number* - The first number to test.

*more numbers, etc.*

```
(min 1 2 5 0)
(min (add 1 1) (sub 1 1) (mul 1 1) (div 1 1))
```

`max`

Get the highest number from all the arguments.

*number* - The first number to test.

*more numbers, etc.*

```
(max 100 10000 10)
(max (add 10 10) (sub 10 10) (mul 10 10) (div 10 10))
```

`not`

Return the inverse of a boolean argument.

*boolean* - The boolean to get the inverse of.

```
(not off)
(not (and off on))
```

`eq?`

Returns `on`

if all of the arguments are equal.

*number* - The first number to test.

*more numbers, etc.*

```
(eq? 1 1)
(eq? (add 1 0) (sub 1 0) (mul 1 1) (div 1 1))
```

`lt?`

Returns `on`

if every argument is less than the next one.

*number* - The first number to test.

*more numbers, etc.*

```
(lt? 1 2 3)
(lt? (mul 1 1) (mul 10 10) (mul 100 1000))
```

`gt?`

Returns `on`

if every argument is greater than the next one.

*number* - The first number to test.

*more numbers, etc.*

```
(gt? 3 2 1)
(gt? (mul 2 2 2 2) (mul 2 2 2) (mul 2 2))
```

`xor`

Return `on`

if an odd number of its arguments are `on`

.

*boolean* - The first boolean to test.

*more booleans, etc.*

```
(xor on off)
(xor on off on off)
```

`xor`

Return `on`

if an odd number of its arguments are `on`

.

*boolean* - The first boolean to test.

*more booleans, etc.*

```
(xor on off)
(xor on off on off)
```

`floor`

Round down a number.

*number* - The number to round down.

```
(floor 3.14)
(floor (div 10 3))
```

`floor`

Round up a number.

*number* - The number to round up.

```
(ceil 6.28)
(ceil (div 20 7))
```

`rand`

Returns a pseudorandom number between 0 and 1 based on a seed value you supply.

*number* - A seed value that's used to create a pseudorandom number. If you use the same seed multiple times, it will return the same value each time.

```
(rand 0)
(rand time)
```

`rand-bool`

Pseudorandomly returns `on`

or `off`

based on a seed value you supply.

*number* - A seed value that's used to create a pseudorandom result. If you use the same seed multiple times, it will return the same result each time.

```
(rand-bool 0)
(rand-bool time)
```