summaryrefslogtreecommitdiffstats
path: root/virtual-programs/music.folk
blob: 726a329423854af25f11f1834f23278026ce84ee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
if {$::isLaptop} { return }
if {[catch {exec which sclang}]} { return }

namespace eval ::Music { variable musicDir $::env(HOME)/music }
exec mkdir -p $::Music::musicDir
set bootTidal [open $::Music::musicDir/BootTidal.hs w]
# https://raw.githubusercontent.com/tidalcycles/Tidal/main/BootTidal.hs
puts $bootTidal {
:set -XOverloadedStrings
:set prompt ""

import Sound.Tidal.Context

import System.IO (hSetEncoding, stdout, utf8)
hSetEncoding stdout utf8

tidal <- startTidal (superdirtTarget {oLatency = 0.05, oAddress = "127.0.0.1", oPort = 57120}) (defaultConfig {cVerbose = True, cFrameTimespan = 1/20})

:{
let only = (hush >>)
    p = streamReplace tidal
    hush = streamHush tidal
    panic = do hush
               once $ sound "superpanic"
    list = streamList tidal
    mute = streamMute tidal
    unmute = streamUnmute tidal
    unmuteAll = streamUnmuteAll tidal
    unsoloAll = streamUnsoloAll tidal
    solo = streamSolo tidal
    unsolo = streamUnsolo tidal
    once = streamOnce tidal
    first = streamFirst tidal
    asap = once
    nudgeAll = streamNudgeAll tidal
    all = streamAll tidal
    resetCycles = streamResetCycles tidal
    setCycle = streamSetCycle tidal
    setcps = asap . cps
    getcps = streamGetcps tidal
    getnow = streamGetnow tidal
    xfade i = transition tidal True (Sound.Tidal.Transition.xfadeIn 4) i
    xfadeIn i t = transition tidal True (Sound.Tidal.Transition.xfadeIn t) i
    histpan i t = transition tidal True (Sound.Tidal.Transition.histpan t) i
    wait i t = transition tidal True (Sound.Tidal.Transition.wait t) i
    waitT i f t = transition tidal True (Sound.Tidal.Transition.waitT f t) i
    jump i = transition tidal True (Sound.Tidal.Transition.jump) i
    jumpIn i t = transition tidal True (Sound.Tidal.Transition.jumpIn t) i
    jumpIn' i t = transition tidal True (Sound.Tidal.Transition.jumpIn' t) i
    jumpMod i t = transition tidal True (Sound.Tidal.Transition.jumpMod t) i
    jumpMod' i t p = transition tidal True (Sound.Tidal.Transition.jumpMod' t p) i
    mortal i lifespan release = transition tidal True (Sound.Tidal.Transition.mortal lifespan release) i
    interpolate i = transition tidal True (Sound.Tidal.Transition.interpolate) i
    interpolateIn i t = transition tidal True (Sound.Tidal.Transition.interpolateIn t) i
    clutch i = transition tidal True (Sound.Tidal.Transition.clutch) i
    clutchIn i t = transition tidal True (Sound.Tidal.Transition.clutchIn t) i
    anticipate i = transition tidal True (Sound.Tidal.Transition.anticipate) i
    anticipateIn i t = transition tidal True (Sound.Tidal.Transition.anticipateIn t) i
    forId i t = transition tidal False (Sound.Tidal.Transition.mortalOverlay t) i
    d1 = p 1 . (|< orbit 0)
    d2 = p 2 . (|< orbit 1)
    d3 = p 3 . (|< orbit 2)
    d4 = p 4 . (|< orbit 3)
    d5 = p 5 . (|< orbit 4)
    d6 = p 6 . (|< orbit 5)
    d7 = p 7 . (|< orbit 6)
    d8 = p 8 . (|< orbit 7)
    d9 = p 9 . (|< orbit 8)
    d10 = p 10 . (|< orbit 9)
    d11 = p 11 . (|< orbit 10)
    d12 = p 12 . (|< orbit 11)
    d13 = p 13
    d14 = p 14
    d15 = p 15
    d16 = p 16
:}

:{
let getState = streamGet tidal
    setI = streamSetI tidal
    setF = streamSetF tidal
    setS = streamSetS tidal
    setR = streamSetR tidal
    setB = streamSetB tidal
:}

:set prompt "tidal> "
:set prompt-cont ""

default (Pattern String, Integer, Double)
}
close $bootTidal
set scStartup [open $::Music::musicDir/startup.sc w]
puts $scStartup "SuperDirt.start;"
close $scStartup

set ::env(DBUS_SESSION_BUS_ADDRESS) "unix:path=/run/user/1000/bus"

proc ::Music::exec {args} {
  variable musicDir
  if {[lindex $args end] eq "&"} {
    ::exec {*}[lreplace $args end end] >>$musicDir/music.log 2>>$musicDir/music.log &
  } else {
    ::exec {*}$args >>$musicDir/music.log 2>>$musicDir/music.log
  }
}
proc ::Music::finishSetup {} {
  variable musicDir

  if {$::thisNode ne "folk-beads"} {
    exec jack_control start
    exec jack_control ds alsa
    exec jack_control dps device hw:HDMI,10
    exec jack_control dps rate 48000
    exec jack_control dps nperiods 2
    exec jack_control dps period 64
  }

  catch {exec pkill ghci}
  catch {exec pkill sclang}
  after 500 {
    ::Music::exec -ignorestderr xvfb-run --auto-servernum sclang $::Music::musicDir/startup.sc &

    set fifo $::Music::musicDir/tidal-input
    exec rm -f $fifo
    exec mkfifo $fifo
    ::Music::exec -ignorestderr sh -c "ghci < $fifo" &
    set fifoId [open $fifo w]
    exec cat $::Music::musicDir/BootTidal.hs > $fifo
  }
}

proc ::Music::waitForDbus {} {
    puts "Waiting for D-Bus."
    if {[file exists /run/user/1000/bus]} {
        puts "Found D-Bus."
        ::Music::finishSetup
    } else {
        after 100 ::Music::waitForDbus
    }
}

::Music::waitForDbus