---
# System prepended metadata

title: MusicBox

---

# MusicBox
Ściślej: Collaborative Text Music Box

Chodzi o minimalistyczną aplikację przeglądarkową, gdzie mamy dostępne pole tekstowe. Na podstawie tego co wpiszemy jest tworzona w pętli muzyka.
Piszemy np.:

```
4/4
|BcccTccc|BcBcTcccBcBcTccc|          - linia perkusyjna
|B       |B.......|
|Am|Dm...|

```

## Moduły
* parser (front)
* engine (front)
* synchronizacja stanu (websocket do backendu)
* sample statyczny na backendzie - (B -> bass.mp4, t -> hat.mp4)

```
text -> parser -> format pośredni -> player
               -> podświetlanie składni
```

## Do przygotowania
* synteza prostego rytmu (tone.js?) musimy wiedzieć jak będzie wyglądał pośredni format
  ```
  |bc|bc|
  |Am|Bm|
  ```
* podświetlanie składni w textbox (aktualnie grana kolumna, błędy itp)
* websocket, aktualizacja stanu (wysyłamy nasz text box, dostajemy text box pozostałych)
* wirtualna maszyna w touku
* wizualizacja - wyciągnięcie z spektrum sensowne wartości dla nussrapera, ewentualnie może tome.js lub inna jest w stanie od razu dać jakieś wartości
* metronom na gębie - nusstronom




* frontend - pole tekstowe
```
  4/4
  tempo: 90
  |BcccTccc| -> parser -> reprezentacja wewnętrzna
  reprezentacja wewnętrzna -> engine (player) (sample / synteza tone.js) -> ścieżka
```
* zmiana?
  - na koniec taktu
  - po pętli (<- najprostrze)
  - ctrl + Enter (na koniec taktu, po pętli)

```
mode: takt|loop|ctrl+enter
1: |BcccTcxc|
2: |BcBcTc|
#|1|1|1|2|
|1|1|1|bccis|
|Am Bm |


|bc|bc|
|Am|Bm|
```

## Multiplayer
Do rozpatrzenia dwa warianty:
* każdy ma swoje pole do edycji
np.:
```
user1:
------------
|BcccTccc|BcBcTccc|
------------

user2:
------------
|Am...|Dm...|
------------
```
* lub jedno wspólne - tak jak w google docs (fajniejsze i trudniejsze ;)

## Dodatkowe opcje
* nussraper
* wizualizacja na podstawie spektrum (https://www.youtube.com/watch?v=VXWvfrmpapI&t=108s&ab_channel=Frankslaboratory)
* pokoje
* kolekcje (zapisywanie tego co się uda stworzyć)
* efekty
* syntezacja tekstu i rapowanie (nth zwiększający fun factor :D)
* eksport do midi / mp4
* transpozycja
* jakieś opcje odsłuchu/zapętlenia poszczególnych taktów
* vocaloid


## Notacja wewnętrzna

```javascript
// |kccc|
// |AmAm| -> |Am       Am       |

// |kccc| -> |k   c   c   c   |
// |Am|   -> |Am        |

// |kcccsccc| -> |kcccsccc|


let takt = [
  ['p:k:16n', 'g:Am:1n']
  [],
  ['p:h:16n']
  ...
]
```

```
engine.graj(doZagrania) {
  'p:k:16n' 
  let insturment
  let note
  let duration
  if (insturment = perkusja)
    players.player(note).play(duration)
  
}
```

```javascript
 let seq = new Tone.Sequence(function(time, idx) {
        takt[idx].forEach((doZagrania) => engine.graj(doZagrania))
    }, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], '16n')
    Tone.Transport.start('+0.4')
    seq.start()
```    

* Do rozkminienia co z tym time

## Stack
* frontend: czysty typescript + snowpack (raczej bez frameworków)?
* komunikacja frontend - backend - websocket, opcjonalnie fajnie byłoby sprawdzić p2p na webRTC?
* backend: wiadomo - w kotlinie :P

### Synteza dźwięku
https://tonejs.github.io/examples/stepSequencer
https://github.com/tonaljs/tonal - teoria muzyki w js
https://www.devbridge.com/articles/tonejs-coding-music-production-guide/

### Instrumenty
https://editor.p5js.org/ada10086/sketches/BynF7xdcQ
https://tonejs.github.io/examples/jump

## Inspiracje
https://notes.ameo.design/fm.html
https://gibber.cc/alpha/playground/
https://tidalcycles.org/Mini_notation_syntax - perkusja
https://nestup.cutelab.nyc/ - język / notacja muzyczna


# Backend

```json
//client -> ws
{
  room: 1
  name: 'rgl'
}
//client -> swój stan (text) - on update + rebounce
{
  msgType: 'update'
  state: {
    rgl: '|pccckccc|...'
  }
}
//server -> stan wszystkich
{
  room: 1
  msgType: 'update'
  state: {
      rgl: ''
      rsr: ''
      ...
  }
}
```