Skip to content

Commit

Permalink
Merge pull request #225 from Bubobubobubobubo/spl-refactoring
Browse files Browse the repository at this point in the history
Merging dev branch with new features
  • Loading branch information
Bubobubobubobubo authored Jun 11, 2023
2 parents 9e0a406 + 49742e1 commit d98bbd3
Show file tree
Hide file tree
Showing 38 changed files with 1,105 additions and 840 deletions.
2 changes: 2 additions & 0 deletions docs/old/oldwebsite/documentation/sardinopedia/rhythm.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
## Rhythm

This set of functions is all about generating and manipulating rhythms easily.

### Probability rhythm

```python3
Expand Down
13 changes: 8 additions & 5 deletions docs/sardine_doc/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@
- [Pattern Languages](pattern_languages.md)
- [Sardine Pattern Language](pattern_languages/sardine.md)
- [Numbers](pattern_languages/sardine/numbers.md)
- [Notes](pattern_languages/sardine/notes.md)
- [Names](pattern_languages/sardine/names.md)
- [Addresses](pattern_languages/sardine/addresses.md)
- [Notes](pattern_languages/sardine/notes.md)
[Polyphony](pattern_languages/sardine/polyphony.md)
- [Operators](pattern_languages/sardine/operators.md)
- [Silence](pattern_languages/sardine/silence.md)
Expand All @@ -61,13 +61,16 @@
- [Extend](pattern_languages/sardine/extend.md)
- [Extend-Repeat](pattern_languages/sardine/extend_repeat.md)
- [Function Library](pattern_languages/sardine/function_library.md)
- [Mathematical](pattern_languages/sardine/math_functions.md)
- [Euclidian](pattern_languages/sardine/euclidian_functions.md)
- [Voice Leading](pattern_languages/sardine/voice_leading.md)
- [Variable Functions](pattern_languages/sardine/variable_functions.md)
- [Time Functions](pattern_languages/sardine/time_functions.md)
- [Math Functions](pattern_languages/sardine/math_functions.md)
- [Rhythm Functions](pattern_languages/sardine/rhythm_functions.md)
- [Filter Functions](pattern_languages/sardine/filter_functions.md)
- [Melody Functions](pattern_languages/sardine/melodic_functions.md)
- [Note Functions](pattern_languages/sardine/notes_functions.md)
- [Condition Functions](pattern_languages/sardine/conditions.md)
- [Combinatorics](pattern_languages/sardine/combinatorics_functions.md)
- [Low Frequency Oscillators (LFOs)](pattern_languages/sardine/low_frequency_oscillators.md)
- [Conditions](pattern_languages/sardine/conditions.md)
- [Ziffers](pattern_languages/ziffers.md)
- [Presentation](pattern_languages/ziffers/what_is_ziffers.md)
- [Pitch](pattern_languages/ziffers/pitch.md)
Expand Down
10 changes: 5 additions & 5 deletions docs/sardine_doc/src/diving_deeper/amphibian_variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ V.s = 60 # this is an amphibian variable
@swim
def fun():
# Calling the variable from inside the Sardine Pattern Language
N('(v s)')
N('(getA s)')
if random() > 0.8:
V.s = random() * 80 # setting a random value
again(fun)
Expand All @@ -16,14 +16,14 @@ def fun():
- They are defined using the variable `V` followed by a letter from the alphabet (uppercase or lowercase) : `V.a`, `V.A`, `V.Z`, `V.j`. These variables can be freely manipulated from the Python side or from the pattern side. **They are amphibian because they exist in the two languages**.

Here is how you manipulate them:
- The `(v letter)` function can access an amphibian variable from inside the pattern language.
- The `(vs letter value)` function can set an amphibian variable from inside the pattern language.
- The `(getA letter)` function can access an amphibian variable from inside the pattern language.
- The `(setA letter value)` function can set an amphibian variable from inside the pattern language.

```python
@swim
def fun(p=0.25):
# Now having fun with it
N('(vs s 5~80)') # setting a random value to the variable
N('(setA s 5~80)') # setting a random value to the variable
if random() > 0.8:
v.s = 50
again(fun, p=0.25)
Expand All @@ -33,7 +33,7 @@ Amphibian Variables also work in Players:
```python

V.n = [52, randint(40, 60), 72, 35]
Pa * d('supersaw', n='(v n)', p=0.75 )
Pa * d('supersaw', n='(getA n)', p=0.75 )
```

You can use Amphibian Variables to leverage Python or the pattern syntax for what they do best: patterning or dealing with complex algorithmic transformations. Having them both available makes the pattern syntax even more expressive.
Expand Down
34 changes: 20 additions & 14 deletions docs/sardine_doc/src/pattern_languages/sardine.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,34 @@
# Sardine Pattern Language

The pattern language is everywhere in **Sardine**. Everytime you use any of the senders (`D()`, `N()`, `P()` and their lowercase variants), you are likely to encounter it. **Sardine** automatically turns every argument it receives as a `string` in an expression that is read using the **pattern language**:
## What and where are patterns?

You will find the pattern language pretty much everywhere in **Sardine**. Everytime you use any of the senders like `D()`, `N()`, `P()` and their lowercase variants, you are likely using the pattern language already. **Sardine** automatically turns every `string` argument it receives into a pattern using the **Sardine Pattern Language**:

```python
D('bd', speed=1, legato=2) # speed and legato are using regular Python types
D('b', speed='1|2', legato='1~4') # speed and legato are now patterns (string)
```
**Pattern Object**
Sardine also has a pattern object. This is useful and required when patterning outside of Senders. Examples would be to pattern the period value in the `again()` statement, or patterning the `clock.tempo` value.

See [Diving Deeper > Pattern Object](../diving_deeper/pattern_object.md).
Think of it as having a second programming language inside your main programming language. This language is a welcomed addition:

- It is an efficient way to create variety in the musical output of your code.
- It saves space and makes it easier to express complex pattern transformations.
- It gives you access to new operators that **Python** doesn't provide by default.
- It makes writing lists way easier and less verbose compared to Python.

Note that pattern languages are one of the basic tools used in most live coding environments. Each environment comes with its own flavour, and Sardine comes with multiple pattern languages!

### Patterning - a programming language within
You can't even use a synthesizer or play a note without writing at least one pattern (the initial string). One call to the senders/handlers can result in multiple patterns being interpreted by the **Sardine pattern language** at once.
## Pattern Object

Think of it as having a second programming language inside your main programming language.
Sardine also has a pattern object, named `P()`. This object is very useful when you start exploring on your own and start building your own abstractions. The most typical usage of the `P()` is to pattern the `again` call in a **swimming function** like so:

So, why use the Sardine pattern language?
```python
@swim
def donothing(p=1, i=0):
print('I do nothing really interesting!')
again(donothing, p=P('1 2 0.5!4', i), i=i+1)
```

- It is an efficient way to create change and variety in musical output.
- It saves space, it makes it easier to express complex transformations fast.
- It gives you access to new operators that **Python** doesn't provide.
- It makes writing lists way easier and less verbose.
- It is the key that unlocks Sardine's expressive potential.
- Patterning is a basic tool available in most livecoding environments.
If you want to learn more about it, I encourage you to read: [Diving Deeper > Pattern Object](../diving_deeper/pattern_object.md).


4 changes: 3 additions & 1 deletion docs/sardine_doc/src/pattern_languages/sardine/addresses.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Addresses

- Addresses are names containing one or multiple `/` separators just like any OSC address.
**Addresses** are not really common until you play a lot with custom OSC messages.

- Addresses are names containing one or multiple `/` separators just like any hierarchical address on the web, UNIX systems, etc...
- If using the `send_raw` function in conjunction with OSC, the syntax differs:
- prepend your address with an additional `/`.

Expand Down
5 changes: 1 addition & 4 deletions docs/sardine_doc/src/pattern_languages/sardine/choice.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
# Choice

The pipe operator `|` can be used on anything to make a 50/50%
choice between two tokens. You can also chain them: `1|2|3|4`.
The behavior of chaining multiple choice operators has not been
clearly defined. The distribution might not be the one you expect.
The pipe operator `|` can be used on to generate a 50/50% choice operation between two tokens. You can also chain them: `1|2|3|4`. The behavior of chaining multiple choice operators has not been clearly defined. The distribution might not be the one you expect.

```python
@swim
Expand Down
Original file line number Diff line number Diff line change
@@ -1,104 +1,88 @@
# Combinatorics

<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
This category of functions is containing many functions that perform many simple but important operations on lists.

<colgroup>
# rev

<col class="org-left" />
Reverse a list.

<col class="org-left" />
- **Arguments:**
- **None**

<col class="org-left" />
**Example:**
```python
(rev 1 2 3 [1 2 3])
```

<col class="org-left" />
</colgroup>
<tbody>
<tr>
<td class="org-left">Function name</td>
<td class="org-left"> Arguments</td>
<td class="org-left">Description</td>
<td class="org-left">Return type</td>
</tr>
# pal

Creates a palindrome. This will keep the list as is but will also append the list in reverse.

<tr>
<td class="org-left">invert</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">???</td>
<td class="org-left">&#xa0;</td>
</tr>
- **Arguments:**
- **cut:** whether to repeat the last/first value of reversed list or not.

**Example:**
```python
(pal [1:10] ::cut 1# or ::cut 0
```

<tr>
<td class="org-left">aspeed</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">Add one more silence to the pattern for every element it crosses.</td>
<td class="org-left">[pattern]</td>
</tr>
# shuf

Shuffle any list.

<tr>
<td class="org-left">expand</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>
Description ...
- **Arguments:**
- **None**

**Example:**
```python
(shuf 1 2 3 4 5)
```

<tr>
<td class="org-left">pal</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">Return a palindrome of the given pattern</td>
<td class="org-left">[pattern]</td>
</tr>
# leave

Braid multiple lists of uneven length.

<tr>
<td class="org-left">rev</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">Reverse the pattern</td>
<td class="org-left">[pattern]</td>
</tr>
- **Arguments:**
- **...:** feed multiple lists to braid them together.

**Example:**
```python
(leave [1 2 3] [3 4 5] [1 2] [4 8 6 4])
```

<tr>
<td class="org-left">leave</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">Interleave function</td>
<td class="org-left">[pattern]</td>
</tr>
# insertp

Insert a fixed element as pair element of each list.

<tr>
<td class="org-left">insertp</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">Braid a pattern with the first pattern being even and the second odd index numbers</td>
<td class="org-left">[pattern]</td>
</tr>
- **Arguments:**
- **None**

**Example:**
```python
```

<tr>
<td class="org-left">insert</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">???</td>
<td class="org-left">[pattern]</td>
</tr>
# insert

Insert a fixed element as odd element of each list.

<tr>
<td class="org-left">insertprot</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">???</td>
<td class="org-left">[pattern]</td>
</tr>
- **Arguments:**
- **None**

**Example:**
```python
```

<tr>
<td class="org-left">shuf</td>
<td class="org-left">[pattern]</td>
<td class="org-left">Shuffle/randomize a given pattern</td>
<td class="org-left">[pattern]</td>
</tr>
# insertprot

</tbody>
</table>
Description ...

- **Arguments:**
- **None**

**Example:**
```python
```

# insertrot
# aspeed
32 changes: 16 additions & 16 deletions docs/sardine_doc/src/pattern_languages/sardine/conditions.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,35 @@
# Conditions

Every function from the function library can be applied conditionally. To do so, use the special `cond` keyword. This keyword is available to every function. There are many types of conditions you can apply on your pattern and you can even create conditions manually. Conditions are working by providing them binary values:
Every function in the **Sardine Pattern Language** can be applied conditionally. To do so, use the special `cond` keyword argument. This keyword is available for every function. There are many types of conditions you can apply on your pattern and you can even create your own types of conditions.


There is no `True` or `False` statement in **SPL**. Conditions are created by using binary values:
- `1` represents truth: `True`.
- `0` represents false: `False`.

The function above will turn the sequence into a palindrome but only on beats 1 and 3:

```python
Pa >> d('(pal F A C E ::cond (beat 0 2))')
Pa * d('(pal F A C E ::cond (beat 0 2))')
```

In the Sardine Pattern Language, everything is a function, including the logical constructs themselves (`if`, `while`). It means that you can also add conditions to your conditions, etc&#x2026;
Of course, the rabbit goes down and you go after it. Any condition can receive conditions, etc...

## If condition

The `if` condition is a binary condition: it will execute something if true, something else if false. In the following example, the function will play a clap for every pair bar (2, 4, etc.) and another sample on every odd bar.
The `if` condition is a binary condition: it will execute something if true (`1`), something else if false (`0`). In the following example, the function will play a clap for every pair bar (2, 4, etc.) and another sample on every odd bar.
```python
Pa >> d('(if (every 2) cp sid')
Pa * d('(if (every 2) cp sid')
```
The `nif` function can be used to reverse the logic (*not if*).

The `nif` function can be used to reverse the logic (*not if*) just by typing one letter Saving 20 milliseconds is important because life is too short.

## While condition

The `while` condition is an unary condition: it will execute something if true, nothing at all if false. In the following example, the function will sometimes play a clap:
The `while` condition is an unary condition: it will execute something if true (`1`), nothing at all if false (`0`). In the following example, the function will sometimes play a clap:

```python
Pa >> d('(while rand*5>2 cp)')
Pa * d('(while rand*5>2 cp)')
```

In that specific case, as a demonstration, we craft our own condition by using the greater-than (`>`) operator.
Expand Down Expand Up @@ -116,17 +118,15 @@ Some functions from the library can be used to build more complex conditions in
</tbody>
</table>

The `beat` function is a great place to start. Let&rsquo;s play a clap on the start of the bar:
The `beat` function is a great to start with because it is also very simple. Let's play a clap on the start of the bar:
```python
Pa >> d('(if (beat 0) cp)')
Pa * d('(if (beat 0) cp)')
```

Let's add another beat to the equation. It will now also play on the following beat of the bar:

```python
Pa >> d('(if (beat 0 1) cp)')
Pa * d('(if (beat 0 1) cp)')
```

You get it. Other functions work similarly.
These functions are cool but you might have guessed already that you can craft your own functions yourself if you are clever enough :) If you think of some cool functions to add, I&rsquo;ll be more than happy to include them into Sardine.

You get it. Other functions are working in a similar fashion. These functions are cool but you might have guessed already that you can craft your own functions yourself if you are clever enough :) If you think of some cool functions to add, I'll be more than happy to include them into Sardine :)
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
# Euclidian

Functions that apply a boolean mask on a pattern. This mask will
either leave the pattern as is or replace some values by silences.
The euclidian rhythm generator lives in this category. I know
that you were looking for it :)
Functions that apply a boolean mask on a pattern. This mask will either leave the pattern as is or replace some values by silences. The euclidian rhythm generator lives in this category. I know that you were looking for it :)

<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">

Expand Down
3 changes: 1 addition & 2 deletions docs/sardine_doc/src/pattern_languages/sardine/extend.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# Extend

- you can extend a list by calling the `!` operator on it.
- This will repeat the list x times.
You can extend a list by calling the `!` operator on it. This will repeat the list `x` times. Some people confuse this operator with its bigger brother, `!!`, called extend-repeat.

```python
@swim
Expand Down
Loading

0 comments on commit d98bbd3

Please sign in to comment.