# UzuParser
Parser for Uzu pattern mini-notation, used in live coding and algorithmic music generation.
## Overview
UzuParser converts text-based pattern notation into structured, timed musical events. It's designed for live coding environments and algorithmic music systems, providing a simple yet expressive syntax for creating rhythmic and melodic patterns.
## Installation
Add `uzu_parser` to your dependencies in `mix.exs`:
```elixir
def deps do
[
{:uzu_parser, "~> 0.1.0"}
# Or for local development:
# {:uzu_parser, path: "../uzu_parser"}
]
end
```
## Quick Start
```elixir
# Parse a simple pattern
UzuParser.parse("bd sd hh sd")
# => [
# %UzuParser.Event{sound: "bd", time: 0.0, duration: 0.25},
# %UzuParser.Event{sound: "sd", time: 0.25, duration: 0.25},
# %UzuParser.Event{sound: "hh", time: 0.5, duration: 0.25},
# %UzuParser.Event{sound: "sd", time: 0.75, duration: 0.25}
# ]
```
## Syntax
### Basic Sequences
Space-separated sounds are evenly distributed across one cycle (0.0 to 1.0):
```elixir
UzuParser.parse("bd sd hh sd") # 4 events at times 0.0, 0.25, 0.5, 0.75
```
### Rests
Use `~` for silence:
```elixir
UzuParser.parse("bd ~ sd ~") # kick and snare on alternating beats
```
### Subdivisions
Brackets create faster divisions within a step:
```elixir
UzuParser.parse("bd [sd sd] hh") # snare plays twice as fast
UzuParser.parse("bd [sd hh cp]") # three sounds in the time of one step
```
### Repetition
Asterisk multiplies elements:
```elixir
UzuParser.parse("bd*4") # equivalent to "bd bd bd bd"
UzuParser.parse("bd*2 sd") # two kicks, one snare
```
### Sample Selection
Colon selects different samples/variations:
```elixir
UzuParser.parse("bd:0") # kick drum, sample 0
UzuParser.parse("bd:1 bd:2") # different kick drum samples
UzuParser.parse("bd:0*4") # repeat sample 0 four times
UzuParser.parse("bd:0 sd:1 hh:2") # each sound uses a different sample
```
### Complex Patterns
Combine features for expressive patterns:
```elixir
# Realistic drum pattern
UzuParser.parse("bd sd [hh hh] sd")
# Layered pattern with repetition and subdivisions
UzuParser.parse("bd*4 ~ [sd sd] ~")
# Nested subdivisions and rests
UzuParser.parse("[bd ~ sd ~] hh")
```
## Event Structure
Each parsed event contains:
- `sound` - The sound/sample name (string)
- `sample` - Sample number (integer >= 0, or nil for default)
- `time` - Position in the cycle (0.0 to 1.0)
- `duration` - How long the event lasts (0.0 to 1.0)
- `params` - Additional parameters (map, for future extensions)
```elixir
%UzuParser.Event{
sound: "bd",
sample: 0,
time: 0.0,
duration: 0.25,
params: %{}
}
```
## Projects Using UzuParser
- [KinoSpaetzle](https://github.com/rpmessner/kino_spaetzle) - Livebook live coding environment
- [discord_uzu](https://github.com/rpmessner/discord_uzu) - Discord bot for live coding
## Future Features
- Parameters: `"bd|gain:0.8|speed:2"`
- Polyphony: `"[bd,sd]"` (multiple sounds at once)
- Euclidean rhythms: `"bd(3,8)"` (3 hits in 8 steps)
- Pattern transformations: `fast()`, `slow()`, `rev()`
## Development
```bash
# Run tests
mix test
# Generate documentation
mix docs
# Format code
mix format
```
## License
MIT License - See LICENSE for details
## Credits
Inspired by the pattern mini-notation from [TidalCycles](https://tidalcycles.org/) and [Strudel](https://strudel.cc/).