Skip to content
This repository was archived by the owner on Jun 13, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 61 additions & 20 deletions tidal-listener/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,28 @@ Experimental tidal OSC listener.

## Install

Move to the repository directory and run `cabal install`.
Move to the repository directory and run `cabal install`.

On Linux systems, the `tidal-listener` binary will be found inside `~/.cabal/bin/`.

There are some command line options to set the listening, reply and dirt port as well as to specify the mode of the listener. There is a mode that assumes that GHC and Tidal are installed on the system, the other mode makes no such assumption but requires a specific folder of additional files. Unfortunately, this mode is currently broken and in progress of being fixed, see
https://github.com/haskell-hint/hint/issues/156

```
Usage: tidal-listener [-l|--listenport INT] [-r|--replyport INT]
[-d|--dirtport INT] [--no-ghc]

An OSC interpreter for TidalCycles

Available options:
-l,--listenport INT Specify the listening port (default: 6011)
-r,--replyport INT Specify the reply port (default: 6012)
-d,--dirtport INT Specify the dirt port (default: 5720)
--no-ghc If this flag is active, the interpreter will assume
that GHC not installed on the system
-h,--help Show this help text
```

## Protocol

This is a work-in-progress and the below is not yet implemented.
Expand All @@ -17,23 +35,51 @@ Basic protocol ideas (`>`, incoming message `<`, outgoing message)
> /ping
< /pong
```
run code, get ok or errors back
run statements, get ok, a value or errors back
```
> /eval <statement>
< /eval/ok
```
or
```
< /eval/value <value>
```
or
```
< /eval/error <error message>
```

get the type of an expression (or an error)
```
> /type <expression>
< /type/ok <type>
```
> /code <id> <source>
< /code/ok
or
```
< /type/error <error>
```

load a file at a given path
```
> /load <path>
< /load/ok
```
or
```
< /code/error <id> <error message>
< /load/error <error>
```
Set a name (optional, doesn't have to be unique)

get current cps
```
> /name <name>
< /name/ok
> /cps
< /cps <number>
```

## Speculative, not implemented yet

'Expand' an expression into canonical mininotation, ref https://github.com/tidalcycles/Tidal/issues/633
```
< /expand <code>
< /expand <code>
> /expand/ok <expanded code>
```
Set port listening to replies (if not the sending port)
Expand All @@ -49,38 +95,33 @@ Set highlights on, get stream of active code spans+durations back (or set it off
< /highlights/off ok
< /code/highlight <pattern id> <duration> <cycle position> <col> <row> <col> <row>
```
get current cps
```
> /cps
< /cps <number>
```
set cps
```
> /cps/set <number>
> /cps/set <number>
< /cps/set ok
< /cps <number> - sent to all clients ?
```

Show which patterns are playing/currently active:
Show which patterns are playing/currently active:
```
> /nowplaying/ <d1?>
< /nowplaying/ true/false -- add highlighting to variables currently active?
> /nowplaying/ <d1?>
< /nowplaying/ true/false -- add highlighting to variables currently active?
```


Show events using queryArc -- from https://github.com/tidalcycles/tidal-listener/issues/1
```
> queryArc "some pattern" arcsize
< [((1,1),(2,1)),((1,1),(2,1))|"a",[((1,1),(2,1)),((3,1),(4,1))]0-(½>1)|"b"]
OR
OR
> getEvents 4 8 (s "bd ~ cp/4")
```


Show length of sample -- from https://club.tidalcycles.org/t/ticking-sound-on-splice-and-cps-question/3033
```
> /samplelength/ "bev"
< /samplelength/ 16
< /samplelength/ 16
```

We probably need a way to add an identifier to incoming commands that gets added to outgoing commands, to help clients match up replies.
6 changes: 5 additions & 1 deletion tidal-listener/app/Main.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import Sound.Tidal.Listener
import Sound.Tidal.Listener.Command
import Options.Applicative (execParser)

main :: IO ()
main = listen
main = do
config <- execParser conf
listenWithConfig config
30 changes: 24 additions & 6 deletions tidal-listener/examples/first.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,41 @@ udp <- udpServer "127.0.0.1" 6012

r <- openUDP "127.0.0.1" 6011

sendMessage r $ Message "/code" [string "hello", string "sound \"bd sn\""]
-- execute an arbitrary statement
sendMessage r $ Message "/eval" [string "return 10"]
m <- recvMessage udp
m

sendMessage r $ Message "/code" [string "hello", string "sound silence"]
-- evaluate a definition
sendMessage r $ Message "/eval" [string "let x = 10"]
m <- recvMessage udp
m

-- evaluate a binding statement
sendMessage r $ Message "/eval" [string "y <- return 1"]
m <- recvMessage udp
m

-- evaluate a tidal statment
sendMessage r $ Message "/eval" [string "d1 $ s \"bd\" # n x"]
m <- recvMessage udp
m

-- error
sendMessage r $ Message "/eval" [string "d1 $ suond \"bd\""]
m <- recvMessage udp
m

-- error..
sendMessage r $ Message "/code" [string "hello", string "sund \"bd sn\""]
-- ask the type of an expression
sendMessage r $ Message "/type" [string "s \"bd\""]
m <- recvMessage udp
m

sendMessage r $ Message "/ping" []
m <- recvMessage udp
m


-- receive cps values
-- receive cps values
sendMessage r $ Message "/cps" []
m <- recvMessage udp
m
Loading