Advertisement
Guest User

Untitled

a guest
Jun 25th, 2019
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 36.39 KB | None | 0 0
  1. -- Passersby w/ tunnels . Monome Grid Version
  2. -- 1.1.1 @markeats
  3. -- llllllll.co/t/21089
  4. --
  5. -- GRID controlled West Coast
  6. -- style mono synth.
  7. --
  8. -- E1/K2 : Change page
  9. -- K3 : Change tab
  10. -- E2/3 : Adjust parameters
  11. --
  12. -- Tunnels page
  13. -- K1 (hold): clear buffer
  14. -- K2/K3: randomize params
  15. -- tunnels v1.1 @speakerdamage
  16.  
  17. local MusicUtil = require "musicutil"
  18. local UI = require "ui"
  19. local Graph = require "graph"
  20. local EnvGraph = require "envgraph"
  21. local Passersby = require "passersby/lib/passersby_engine"
  22.  
  23. local tab = require 'tabutil'
  24. local pattern_time = require 'pattern_time'
  25. local g = grid.connect()
  26. local mode_transpose = 0
  27. local root = { x=5, y=5 }
  28. local trans = { x=5, y=5 }
  29. local lit = {}
  30. local screen_framerate = 15
  31. local screen_refresh_metro
  32.  
  33. local ripple_repeat_rate = 1 / 0.3 / screen_framerate
  34. local ripple_decay_rate = 1 / 0.5 / screen_framerate
  35. local ripple_growth_rate = 1 / 0.02 / screen_framerate
  36. local screen_notes = {}
  37.  
  38.  
  39.  
  40. local tn = include('tunnels/lib/tunnel')
  41.  
  42. local SCREEN_FRAMERATE = 15
  43. local screen_refresh_metro
  44. local screen_dirty = true
  45.  
  46. local midi_in_device
  47. local active_notes = {}
  48.  
  49. local pages
  50. local tabs
  51. local tab_titles = {{"Wave", "FM"}, {"Env", "Reverb"}, {"LFO", "Targets"}, {"Fate"}, {"Tunnels"}}
  52.  
  53. local input_indicator_active = false
  54. local wave_table = {}
  55. local wave = {}
  56. local wave_graph
  57. local SUB_SAMPLING = 4
  58. local fm1_dial
  59. local fm2_dial
  60. local env_graph
  61. local env_status = {}
  62. local env_status_metro
  63. local spring_path = {}
  64. local reverb_slider
  65. local lfo_graph
  66. local dice_throw_vel = 0
  67. local dice_throw_progress = 0
  68. local dice_thrown = false
  69. local dice_need_update = false
  70. local dice = {}
  71. local drift_dial
  72.  
  73. local timbre = 0
  74. local wave_shape = {actual = 0, modu = 0, dirty = true}
  75. local wave_folds = {actual = 0, modu = 0, dirty = true}
  76. local fm1_amount = {actual = 0, modu = 0, dirty = true}
  77. local fm2_amount = {actual = 0, modu = 0, dirty = true}
  78. local attack = {actual = 0, modu = 0, dirty = true}
  79. local peak = {actual = 0, modu = 1, dirty = true}
  80. local decay = {actual = 0, modu = 0, dirty = true}
  81. local reverb_mix = {actual = 0, modu = 0, dirty = true}
  82. local lfo_shape = {dirty = true}
  83. local lfo_freq = {dirty = true}
  84. local lfo_destinations = {dirty = true}
  85. local drift = {actual = 0, dirty = true}
  86.  
  87. engine.name = "Passersby"
  88.  
  89. params:bang()
  90.  
  91.  
  92. local function getHz(deg,oct)
  93. return base * ratios[deg] * (2^oct)
  94. end
  95.  
  96. local function getHzET(note)
  97. return 55*2^(note/12)
  98. end
  99. -- current count of active voices
  100.  
  101. local nvoices = 0
  102.  
  103. function init()
  104. m = midi.connect()
  105. m.event = midi_event
  106.  
  107.  
  108.  
  109.  
  110. local MAX_NUM_VOICES = 16
  111.  
  112.  
  113.  
  114. engine.noteOffAll()
  115. stop_all_screen_notes()
  116.  
  117.  
  118. if g then gridredraw() end
  119.  
  120.  
  121. end
  122. --local tunnelgroup
  123. local tunnelmode = 1
  124. local tgroup
  125. local tunnelmodes_list
  126. local tunnelmodes = {"off", "fractal landscape", "disemboguement", "post-horizon", "coded air", "failing lantern", "blue cat", "crawler"}
  127.  
  128.  
  129. -- Utilities
  130.  
  131. local function generate_wave_table(cycles, length)
  132. local wave_table = {{},{},{},{}}
  133. for sx = 1, length do
  134. local x = util.linlin(1, length, 0, cycles, sx)
  135. local square = math.abs(x * 2 % 2 - 1) - 0.5
  136. square = square > 0 and 0.5 or math.floor(square) * 0.5
  137. table.insert(wave_table[1], math.sin(x * 2 * math.pi)) -- Sine
  138. table.insert(wave_table[2], math.abs((x * 2 - 0.5) % 2 - 1) * 2 - 1) -- Tri
  139. table.insert(wave_table[3], square) -- Square
  140. table.insert(wave_table[4], (1 - (x + 0.25) % 1) * 2 - 1) -- Saw
  141. end
  142. return wave_table
  143. end
  144.  
  145. local function generate_wave(x)
  146.  
  147. x = util.round(x)
  148. local index_f = wave_shape.actual * (#wave_table - 1) + 1
  149. local index = util.round(index_f)
  150. local delta = index_f - index
  151.  
  152. local index_offset = delta < 0 and -1 or 1
  153. local y
  154.  
  155. -- Wave table lookup
  156. if delta == 0 then
  157. y = wave_table[index][x]
  158. else
  159. y = wave_table[index + index_offset][x] * math.abs(delta) + wave_table[index][x] * (1 - math.abs(delta))
  160. end
  161.  
  162. -- Wave folding
  163. y = y * (1 + wave_folds.actual)
  164. local abs_y = math.abs(y)
  165.  
  166. if abs_y > 1 then
  167. local folded = abs_y % 1
  168. if math.floor(abs_y - 1) % 2 == 0 then
  169. folded = 1 - folded
  170. else
  171. folded = folded
  172. end
  173. folded = folded * 2 - 1
  174. if y < 0 then folded = folded * -1 end
  175. y = folded
  176. end
  177.  
  178. return y
  179. end
  180.  
  181. local function generate_spring_path(width, height, turns)
  182. local spring_path = {}
  183. for y = 0, height - 1 do
  184. local progress = util.linlin(0, height - 1, 0, math.pi * turns * 2, y)
  185. table.insert(spring_path, {x = width * 0.5 + math.sin(progress) * width * 0.5, y = y})
  186. end
  187. return spring_path
  188. end
  189.  
  190. local function generate_lfo_wave(x)
  191.  
  192. local lfo_shape = params:get("lfo_shape")
  193. x = x * util.linlin(Passersby.specs.LFO_FREQ.minval, Passersby.specs.LFO_FREQ.maxval, 0.5, 10, params:get("lfo_freq"))
  194.  
  195. if lfo_shape == 1 then -- Tri
  196. x = math.abs((x * 2 - 0.5) % 2 - 1) * 2 - 1
  197. elseif lfo_shape == 2 then -- Ramp
  198. x = ((x + 0.25) % 1) * 2 - 1
  199. elseif lfo_shape == 3 then -- Square
  200. x = math.abs(x * 2 % 2 - 1) - 0.5
  201. x = x > 0 and 1 or math.floor(x)
  202. elseif lfo_shape == 4 then -- Random
  203. local NOISE = {0.7, -0.65, 0.2, 0.9, -0.1, -0.5, 0.7, -0.9, 0.25, 1.0, -0.6, -0.2, 0.6, -0.35, 0.7, 0.1, -0.5, 0.7, 0.2, -0.85, -0.3}
  204. x = NOISE[util.round(x * 2) + 1]
  205. end
  206.  
  207. return x * 0.75
  208. end
  209.  
  210. local function update_lfo_amounts_list()
  211. lfo_amounts_list.entries = {
  212. util.round(params:get("lfo_to_freq_amount") * 100, 1),
  213. util.round(params:get("lfo_to_wave_shape_amount") * 100, 1),
  214. util.round(params:get("lfo_to_wave_folds_amount") * 100, 1),
  215. util.round(params:get("lfo_to_fm_low_amount") * 100, 1),
  216. util.round(params:get("lfo_to_fm_high_amount") * 100, 1),
  217. util.round(params:get("lfo_to_attack_amount") * 100, 1),
  218. util.round(params:get("lfo_to_peak_amount") * 100, 1),
  219. util.round(params:get("lfo_to_decay_amount") * 100, 1),
  220. util.round(params:get("lfo_to_reverb_mix_amount") * 100, 1)
  221. }
  222. end
  223.  
  224. local function randomize_dice()
  225. for i = 1, 2 do
  226. local direction = 0
  227. if dice[i] then
  228. direction = (dice[i].top_angle - dice[i].table_angle > 0) and 1 or -1
  229. end
  230. dice[i] = {}
  231. dice[i].face = math.random(6)
  232. dice[i].top_angle = 1 + math.random() * 2
  233. if math.random() > 0.5 then dice[i].top_angle = dice[i].top_angle * -1 end
  234. dice[i].table_angle = math.random() * 0.5 - 0.25 + (2 * math.pi * direction)
  235. end
  236. end
  237.  
  238. local function set_dice_throw_vel(vel_delta)
  239. dice_throw_vel = util.clamp(dice_throw_vel + vel_delta, -0.35, 0.3)
  240. dice_need_update = true
  241. end
  242.  
  243. local function start_env_status_timeout(status_text, x, y)
  244. env_status.text = status_text
  245. env_status.x, env_status.y = x, y
  246. if env_status_metro.is_running then
  247. env_status_metro:stop()
  248. end
  249. env_status_metro:start(1, 1)
  250. end
  251.  
  252. local function update_tabs()
  253.  
  254. wave_graph:set_active(tabs.index == 1)
  255. env_graph:set_active(tabs.index == 1 or params:get("env_type") == 2)
  256. lfo_graph:set_active(tabs.index == 1)
  257.  
  258. if tabs.index == 2 then env_status.text = "" end
  259. lfo_destinations_list.active = tabs.index == 2
  260. lfo_amounts_list.active = tabs.index == 2
  261. fm1_dial.active = tabs.index == 2
  262. fm2_dial.active = tabs.index == 2
  263.  
  264. screen_dirty = true
  265. end
  266.  
  267. local function update_pages()
  268. tabs:set_index(1)
  269. tabs.titles = tab_titles[pages.index]
  270. env_status.text = ""
  271. lfo_destinations_list:set_index(1)
  272. lfo_amounts_list:set_index(1)
  273. update_tabs()
  274. end
  275.  
  276. local function init_env_graph(env_type)
  277. if env_type == 1 then
  278. env_graph = EnvGraph.new_ar(0, 1, 0, 1, 0.003, util.explin(Passersby.specs.DECAY.minval * 0.5, Passersby.specs.DECAY.maxval, 0, 1, decay.actual), util.explin(Passersby.specs.PEAK.minval * 0.5, Passersby.specs.PEAK.maxval, 0, 1, peak.actual), -4)
  279. else
  280. env_graph = EnvGraph.new_asr(0, 1, 0, 1, util.explin(Passersby.specs.ATTACK.minval, Passersby.specs.ATTACK.maxval, 0, 0.4, attack.actual), util.explin(Passersby.specs.DECAY.minval, Passersby.specs.DECAY.maxval, 0, 0.4, decay.actual), 1, -4)
  281. end
  282. env_graph:set_position_and_size(8, 22, 49, 36)
  283. env_graph:set_show_x_axis(true)
  284. end
  285.  
  286.  
  287. -- Engine functions
  288.  
  289. local function note_on(note_num, vel)
  290. engine.noteOn(note_num, MusicUtil.note_num_to_freq(note_num), vel)
  291. table.insert(active_notes, note_num)
  292. input_indicator_active = true
  293. screen_dirty = true
  294. end
  295.  
  296. local function note_off(note_num)
  297. engine.noteOff(note_num)
  298. for i = #active_notes, 1, -1 do
  299. if active_notes[i] == note_num then
  300. table.remove(active_notes, i)
  301. end
  302. end
  303. if #active_notes == 0 then
  304. input_indicator_active = false
  305. screen_dirty = true
  306. end
  307. end
  308.  
  309. local function set_pitch_bend(bend_st)
  310. engine.pitchBendAll(MusicUtil.interval_to_ratio(bend_st))
  311. end
  312.  
  313. local function set_channel_pressure(pressure)
  314. engine.pressureAll(pressure)
  315. end
  316.  
  317. local function set_channel_timbre(value)
  318. engine.timbreAll(value)
  319. timbre = value * 0.5
  320. wave_folds.dirty = true
  321. end
  322.  
  323. -- tunnels
  324. local function update_tunnels()
  325. local tm = tunnelmode
  326. local tg = tgroup
  327. tn.randomize(tm, tg)
  328. end
  329.  
  330. -- Updaters
  331.  
  332. local function update_wave_shape()
  333. wave_shape.actual = util.clamp(params:get("wave_shape") + wave_shape.modu, Passersby.specs.WAVE_SHAPE.minval, Passersby.specs.WAVE_SHAPE.maxval)
  334. wave_graph:update_functions()
  335. wave_shape.dirty = false
  336. screen_dirty = true
  337. end
  338.  
  339. local function update_wave_folds()
  340. wave_folds.actual = util.clamp(params:get("wave_folds") + timbre + wave_folds.modu, Passersby.specs.WAVE_FOLDS.minval, Passersby.specs.WAVE_FOLDS.maxval + 0.5)
  341. wave_graph:update_functions()
  342. wave_folds.dirty = false
  343. screen_dirty = true
  344. end
  345.  
  346. local function update_fm1_amount()
  347. fm1_amount.actual = util.clamp(params:get("fm_low_amount") + fm1_amount.modu, Passersby.specs.FM_LOW_AMOUNT.minval, Passersby.specs.FM_LOW_AMOUNT.maxval)
  348. fm1_dial.value = fm1_amount.actual * 100
  349. fm1_amount.dirty = false
  350. screen_dirty = true
  351. end
  352.  
  353. local function update_fm2_amount()
  354. fm2_amount.actual = util.clamp(params:get("fm_high_amount") + fm2_amount.modu, Passersby.specs.FM_HIGH_AMOUNT.minval, Passersby.specs.FM_HIGH_AMOUNT.maxval)
  355. fm2_dial.value = fm2_amount.actual * 100
  356. fm2_amount.dirty = false
  357. screen_dirty = true
  358. end
  359.  
  360. local function update_attack()
  361. attack.actual = util.clamp(params:get("attack") + attack.modu, Passersby.specs.ATTACK.minval, Passersby.specs.ATTACK.maxval)
  362. if params:get("env_type") == 2 then
  363. local norm_attack = util.explin(Passersby.specs.ATTACK.minval, Passersby.specs.ATTACK.maxval, 0, 0.4, attack.actual)
  364. env_graph:edit_asr(norm_attack)
  365. end
  366. attack.dirty = false
  367. screen_dirty = true
  368. end
  369.  
  370. local function show_attack_status()
  371. if params:get("env_type") == 2 then
  372. local norm_attack = util.explin(Passersby.specs.ATTACK.minval, Passersby.specs.ATTACK.maxval, 0, 0.4, params:get("attack") + attack.modu)
  373. local norm_peak = util.explin(Passersby.specs.PEAK.minval * 0.5, Passersby.specs.PEAK.maxval, 0, 1, params:get("peak") * peak.modu)
  374. local y
  375. if norm_peak > 0.6 then y = 46 else y = util.linlin(0, 1, 52, 18, norm_peak) end
  376. start_env_status_timeout(params:string("attack"), 38, y)
  377. screen_dirty = true
  378. end
  379. end
  380.  
  381. local function update_peak()
  382. peak.actual = util.clamp(params:get("peak") * peak.modu, Passersby.specs.PEAK.minval, Passersby.specs.PEAK.maxval)
  383. local norm_peak = util.explin(Passersby.specs.PEAK.minval * 0.5, Passersby.specs.PEAK.maxval, 0, 1, peak.actual)
  384. if params:get("env_type") == 1 then
  385. env_graph:edit_ar(nil, nil, norm_peak)
  386. else
  387. env_graph:edit_asr(nil, nil, norm_peak)
  388. end
  389. peak.dirty = false
  390. screen_dirty = true
  391. end
  392.  
  393. local function show_peak_status()
  394. local norm_peak = util.explin(Passersby.specs.PEAK.minval * 0.5, Passersby.specs.PEAK.maxval, 0, 1, params:get("peak") * peak.modu)
  395. if params:get("env_type") == 1 then
  396. start_env_status_timeout(params:string("peak"), 57, util.linlin(0, 1, 56, 26, norm_peak))
  397. else
  398. start_env_status_timeout(params:string("peak"), 45, util.linlin(0, 1, 52, 18, norm_peak))
  399. end
  400. screen_dirty = true
  401. end
  402.  
  403. local function update_decay()
  404. decay.actual = util.clamp(params:get("decay") + decay.modu, Passersby.specs.DECAY.minval, Passersby.specs.DECAY.maxval)
  405. if params:get("env_type") == 1 then
  406. local norm_decay = util.explin(Passersby.specs.DECAY.minval * 0.5, Passersby.specs.DECAY.maxval, 0, 1, decay.actual)
  407. env_graph:edit_ar(nil, norm_decay)
  408. else
  409. local norm_decay = util.explin(Passersby.specs.DECAY.minval, Passersby.specs.DECAY.maxval, 0, 0.4, decay.actual)
  410. env_graph:edit_asr(nil, norm_decay)
  411. end
  412. decay.dirty = false
  413. screen_dirty = true
  414. end
  415.  
  416. local function show_decay_status()
  417. local norm_decay
  418. if params:get("env_type") == 1 then
  419. norm_decay = util.explin(Passersby.specs.DECAY.minval * 0.5, Passersby.specs.DECAY.maxval, 0, 0.4, params:get("decay") + decay.modu)
  420. start_env_status_timeout(params:string("decay"), util.linlin(0, 1, 38, 80, norm_decay), 48)
  421. else
  422. norm_decay = util.explin(Passersby.specs.DECAY.minval, Passersby.specs.DECAY.maxval, 0.4, 0, params:get("decay") + decay.modu)
  423. local norm_peak = util.explin(Passersby.specs.PEAK.minval * 0.5, Passersby.specs.PEAK.maxval, 0, 1, params:get("peak") * peak.modu)
  424. local y
  425. if norm_peak > 0.6 then y = 53 else y = util.linlin(0, 1, 52, 18, norm_peak) end
  426. start_env_status_timeout(params:string("decay"), util.linlin(0, 1, 39, 74, norm_decay), y)
  427. end
  428. screen_dirty = true
  429. end
  430.  
  431. local function update_reverb_mix()
  432. reverb_mix.actual = util.clamp(params:get("reverb_mix") + reverb_mix.modu, Passersby.specs.REVERB_MIX.minval, Passersby.specs.REVERB_MIX.maxval)
  433. reverb_slider.value = reverb_mix.actual
  434. reverb_mix.dirty = false
  435. screen_dirty = true
  436. end
  437.  
  438.  
  439. local function update_lfo_shape()
  440. lfo_graph:update_functions()
  441. lfo_shape.dirty = false
  442. screen_dirty = true
  443. end
  444.  
  445. local function update_lfo_freq()
  446. lfo_graph:update_functions()
  447. lfo_freq.dirty = false
  448. screen_dirty = true
  449. end
  450.  
  451. local function update_lfo_destinations()
  452. update_lfo_amounts_list()
  453. lfo_destinations.dirty = false
  454. screen_dirty = true
  455. end
  456.  
  457. local function update_drift()
  458. drift_dial.value = params:get("drift") * 100
  459. drift.dirty = false
  460. screen_dirty = true
  461. end
  462.  
  463.  
  464.  
  465. -- Input functions
  466.  
  467. -- Encoder input
  468. function enc(n, delta)
  469.  
  470. if n == 1 then
  471. -- Page scroll
  472. pages:set_index_delta(util.clamp(delta, -1, 1), false)
  473. update_pages()
  474. end
  475.  
  476. if pages.index == 1 then
  477.  
  478. if tabs.index == 1 then
  479. -- Wave
  480. if n == 2 then
  481. params:delta("wave_shape", delta)
  482. elseif n == 3 then
  483. params:delta("wave_folds", delta)
  484. end
  485.  
  486. else
  487. -- FM
  488. if n == 2 then
  489. params:delta("fm_low_amount", delta)
  490. elseif n == 3 then
  491. params:delta("fm_high_amount", delta)
  492. end
  493. end
  494.  
  495. elseif pages.index == 2 then
  496.  
  497. if tabs.index == 1 then
  498. -- LPG
  499. if n == 2 then
  500. if params:get("env_type") == 1 then
  501. params:delta("peak", delta)
  502. else
  503. params:delta("attack", delta)
  504. end
  505. elseif n == 3 then
  506. if params:get("env_type") == 1 then
  507. params:delta("decay", delta)
  508. else
  509. params:delta("decay", -delta)
  510. end
  511. end
  512.  
  513. else
  514. -- Peak
  515. if n == 2 and params:get("env_type") == 2 then
  516. params:delta("peak", delta)
  517. -- Reverb
  518. elseif n == 3 then
  519. params:delta("reverb_mix", delta)
  520. end
  521. end
  522.  
  523. elseif pages.index == 3 then
  524.  
  525. if tabs.index == 1 then
  526. -- LFO
  527. if n == 2 then
  528. params:delta("lfo_shape", util.clamp(delta, -1, 1))
  529. elseif n == 3 then
  530. params:delta("lfo_freq", delta)
  531. end
  532.  
  533. else
  534. -- LFO scroll lists
  535. if n == 2 then
  536. lfo_destinations_list:set_index_delta(util.clamp(delta, -1, 1), false)
  537. lfo_amounts_list:set_index(lfo_destinations_list.index)
  538. screen_dirty = true
  539.  
  540. -- LFO amounts
  541. elseif n == 3 then
  542. if lfo_destinations_list.index == 1 then
  543. params:delta("lfo_to_freq_amount", delta)
  544. elseif lfo_destinations_list.index == 2 then
  545. params:delta("lfo_to_wave_shape_amount", delta)
  546. elseif lfo_destinations_list.index == 3 then
  547. params:delta("lfo_to_wave_folds_amount", delta)
  548. elseif lfo_destinations_list.index == 4 then
  549. params:delta("lfo_to_fm_low_amount", delta)
  550. elseif lfo_destinations_list.index == 5 then
  551. params:delta("lfo_to_fm_high_amount", delta)
  552. elseif lfo_destinations_list.index == 6 then
  553. params:delta("lfo_to_attack_amount", delta)
  554. elseif lfo_destinations_list.index == 7 then
  555. params:delta("lfo_to_peak_amount", delta)
  556. elseif lfo_destinations_list.index == 8 then
  557. params:delta("lfo_to_decay_amount", delta)
  558. elseif lfo_destinations_list.index == 9 then
  559. params:delta("lfo_to_reverb_mix_amount", delta)
  560. end
  561. end
  562.  
  563. end
  564.  
  565. elseif pages.index == 4 then
  566.  
  567. -- Randomize
  568. if n == 2 then
  569. if not dice_thrown then set_dice_throw_vel(delta * 0.05) end
  570.  
  571. -- Drift
  572. elseif n == 3 then
  573. params:delta("drift", delta)
  574. end
  575.  
  576. -- tunnels
  577. elseif pages.index == 5 then
  578. if n == 2 then
  579. tunnelmodes_list:set_index_delta(util.clamp(delta, -1, 1))
  580. tunnelmode = tunnelmodes_list.index
  581. --softcut.buffer_clear()
  582. tgroup = 1
  583. update_tunnels(tunnelmode)
  584. tgroup = 2
  585. update_tunnels(tunnelmode)
  586. screen_dirty = true
  587. end
  588. end
  589.  
  590. end
  591.  
  592. -- Key input
  593. function key(n, z)
  594. if pages.index == 5 then
  595. if z == 1 then
  596. if n == 1 then
  597. softcut.buffer_clear()
  598. elseif n == 2 then
  599. tgroup = 1
  600. update_tunnels(tunnelmode)
  601. redraw()
  602. elseif n == 3 then
  603. tgroup = 2
  604. update_tunnels(tunnelmode)
  605. redraw()
  606. end
  607. end
  608. else
  609. if z == 1 then
  610. if n == 1 then
  611. softcut.buffer_clear()
  612. elseif n == 2 then
  613. pages:set_index_delta(1, true)
  614. update_pages()
  615.  
  616. elseif n == 3 then
  617. tabs:set_index_delta(1, true)
  618. update_tabs()
  619.  
  620. end
  621. end
  622. end
  623. end
  624.  
  625. -- GRID input
  626.  
  627. local pattern_time = require 'pattern_time'
  628.  
  629. pat = pattern_time.new()
  630. pat.process = grid_note_trans
  631.  
  632. local MAX_NUM_VOICES = 16
  633.  
  634. function grid_note_trans(e)
  635. local note = ((7-e.y+(root.y-trans.y))*5) + e.x + (trans.x-root.x)
  636. if e.state > 0 then
  637. if nvoices < MAX_NUM_VOICES then
  638. --engine.start(id, getHz(x, y-1))
  639. --print("grid > "..id.." "..note)
  640. engine.noteOn(e.id, getHzET(note))
  641. start_screen_note(note)
  642. lit[e.id] = {}
  643. lit[e.id].x = e.x + trans.x - root.x
  644. lit[e.id].y = e.y + trans.y - root.y
  645. nvoices = nvoices + 1
  646. end
  647. else
  648. engine.noteOff(e.id)
  649. stop_screen_note(note)
  650. lit[e.id] = nil
  651. nvoices = nvoices - 1
  652. end
  653. gridredraw()
  654. end
  655.  
  656. function g.key(x, y, z)
  657. if x == 1 then
  658. if z == 1 then
  659. if y == 1 and pat.rec == 0 then
  660. mode_transpose = 0
  661. trans.x = 5
  662. trans.y = 5
  663. pat:stop()
  664. engine.noteOffAll()
  665. pat:clear()
  666. pat:rec_start()
  667. elseif y == 1 and pat.rec == 1 then
  668. pat:rec_stop()
  669. if pat.count > 0 then
  670. root.x = pat.event[1].x
  671. root.y = pat.event[1].y
  672. trans.x = root.x
  673. trans.y = root.y
  674. pat:start()
  675. end
  676. elseif y == 2 and pat.play == 0 and pat.count > 0 then
  677. if pat.rec == 1 then
  678. pat:rec_stop()
  679. end
  680. pat:start()
  681. elseif y == 2 and pat.play == 1 then
  682. pat:stop()
  683. engine.noteOffAll()
  684. stop_all_screen_notes()
  685. nvoices = 0
  686. lit = {}
  687. elseif y == 8 then
  688. mode_transpose = 1 - mode_transpose
  689. end
  690. end
  691. else
  692. if mode_transpose == 0 then
  693. local e = {}
  694. e.id = x*8 + y
  695. e.x = x
  696. e.y = y
  697. e.state = z
  698. pat:watch(e)
  699. grid_note(e)
  700. else
  701. trans.x = x
  702. trans.y = y
  703. end
  704. end
  705. gridredraw()
  706. end
  707.  
  708.  
  709. function grid_note(e)
  710. local note = ((7-e.y)*5) + e.x
  711. if e.state > 0 then
  712. if nvoices < MAX_NUM_VOICES then
  713. --engine.start(id, getHz(x, y-1))
  714. --print("grid > "..id.." "..note)
  715. engine.noteOn(e.id, getHzET(note), vel)
  716.  
  717. lit[e.id] = {}
  718. lit[e.id].x = e.x
  719. lit[e.id].y = e.y
  720. nvoices = nvoices + 1
  721. end
  722. else
  723. if lit[e.id] ~= nil then
  724. engine.noteOff(e.id)
  725.  
  726. lit[e.id] = nil
  727. nvoices = nvoices - 1
  728. end
  729. end
  730. gridredraw()
  731. end
  732.  
  733.  
  734.  
  735. function gridredraw()
  736. g:all(0)
  737. g:led(1,1,2 + pat.rec * 10)
  738. g:led(1,2,2 + pat.play * 10)
  739. g:led(1,8,2 + mode_transpose * 10)
  740.  
  741. if mode_transpose == 1 then g:led(trans.x, trans.y, 4) end
  742. for i,e in pairs(lit) do
  743. g:led(e.x, e.y,15)
  744. end
  745.  
  746. g:refresh()
  747. end
  748.  
  749. function note_on(note, vel)
  750. if nvoices < MAX_NUM_VOICES then
  751. --engine.start(id, getHz(x, y-1))
  752. engine.start(note, getHzET(note))
  753. start_screen_note(note)
  754. nvoices = nvoices + 1
  755. end
  756. end
  757.  
  758. function note_off(note, vel)
  759. engine.stop(note)
  760. stop_screen_note(note)
  761. nvoices = nvoices - 1
  762. end
  763.  
  764.  
  765. function midi_event(data)
  766. if #data == 0 then return end
  767. local msg = midi.to_msg(data)
  768.  
  769. -- Note off
  770. if msg.type == "note_off" then
  771. note_off(msg.note)
  772.  
  773. -- Note on
  774. elseif msg.type == "note_on" then
  775. note_on(msg.note, msg.vel / 127)
  776. end
  777. end
  778. function cleanup()
  779. stop_all_screen_notes()
  780. pat:stop()
  781. pat = nil
  782. end
  783.  
  784.  
  785.  
  786.  
  787. -- MIDI input
  788. local function midi_event(data)
  789.  
  790. local msg = midi.to_msg(data)
  791. local channel_param = params:get("midi_channel")
  792.  
  793. if channel_param == 1 or (channel_param > 1 and msg.ch == channel_param - 1) then
  794.  
  795. -- Note on
  796. if msg.type == "note_on" then
  797. note_on(msg.note, msg.vel / 127)
  798.  
  799. -- Note off
  800. elseif msg.type == "note_off" then
  801. note_off(msg.note)
  802.  
  803. -- Pitch bend
  804. elseif msg.type == "pitchbend" then
  805. local bend_st = (util.round(msg.val / 2)) / 8192 * 2 -1 -- Convert to -1 to 1
  806. set_pitch_bend(bend_st * params:get("bend_range"))
  807.  
  808. -- Pressure
  809. elseif msg.type == "channel_pressure" or msg.type == "key_pressure" then
  810. set_channel_pressure(msg.val / 127)
  811.  
  812. end
  813. end
  814. end
  815.  
  816.  
  817. -- Init
  818.  
  819. function init()
  820.  
  821. screen.aa(1)
  822.  
  823. midi_in_device = midi.connect(1)
  824. midi_in_device.event = midi_event
  825.  
  826. -- Add params
  827.  
  828. params:add{type = "number", id = "midi_device", name = "MIDI Device", min = 1, max = 4, default = 1, action = function(value)
  829. midi_in_device.event = nil
  830. midi_in_device = midi.connect(value)
  831. midi_in_device.event = midi_event
  832. end}
  833.  
  834. local channels = {"All"}
  835. for i = 1, 16 do table.insert(channels, i) end
  836. params:add{type = "option", id = "midi_channel", name = "MIDI Channel", options = channels}
  837.  
  838. params:add{type = "number", id = "bend_range", name = "Pitch Bend Range", min = 1, max = 48, default = 2}
  839.  
  840. params:add_separator()
  841.  
  842. Passersby.add_params()
  843.  
  844. -- Override param actions
  845.  
  846. params:set_action("wave_shape", function(value)
  847. engine.waveShape(value)
  848. wave_shape.dirty = true
  849. end)
  850.  
  851. params:set_action("wave_folds", function(value)
  852. engine.waveFolds(value)
  853. wave_folds.dirty = true
  854. end)
  855.  
  856. params:set_action("fm_low_amount", function(value)
  857. engine.fm1Amount(value)
  858. fm1_amount.dirty = true
  859. end)
  860.  
  861. params:set_action("fm_high_amount", function(value)
  862. engine.fm2Amount(value)
  863. fm2_amount.dirty = true
  864. end)
  865.  
  866. params:set_action("env_type", function(value)
  867. engine.envType(value - 1)
  868. init_env_graph(value)
  869. tab_titles[2][1] = params:string("env_type")
  870. if value == 1 then
  871. tab_titles[2][2] = "Reverb"
  872. else
  873. tab_titles[2][2] = "Peak/Reverb"
  874. end
  875. if pages.index == 2 then
  876. tabs.titles = tab_titles[2]
  877. update_tabs()
  878. screen_dirty = true
  879. end
  880. end)
  881.  
  882. params:set_action("attack", function(value)
  883. engine.attack(value)
  884. if pages.index == 2 then show_attack_status() end
  885. attack.dirty = true
  886. end)
  887.  
  888. params:set_action("peak", function(value)
  889. engine.peak(value)
  890. if pages.index == 2 then show_peak_status() end
  891. peak.dirty = true
  892. end)
  893.  
  894. params:set_action("decay", function(value)
  895. engine.decay(value)
  896. if pages.index == 2 then show_decay_status() end
  897. decay.dirty = true
  898. end)
  899.  
  900. params:set_action("reverb_mix", function(value)
  901. engine.reverbMix(value)
  902. reverb_mix.dirty = true
  903. end)
  904.  
  905. params:set_action("lfo_shape", function(value)
  906. engine.lfoShape(value - 1)
  907. lfo_shape.dirty = true
  908. end)
  909.  
  910. params:set_action("lfo_freq", function(value)
  911. engine.lfoFreq(value)
  912. lfo_freq.dirty = true
  913. end)
  914.  
  915. params:set_action("lfo_to_freq_amount", function(value)
  916. engine.lfoToFreqAmount(value)
  917. lfo_destinations.dirty = true
  918. end)
  919.  
  920. params:set_action("lfo_to_wave_shape_amount", function(value)
  921. engine.lfoToWaveShapeAmount(value)
  922. lfo_destinations.dirty = true
  923. end)
  924.  
  925. params:set_action("lfo_to_wave_folds_amount", function(value)
  926. engine.lfoToWaveFoldsAmount(value)
  927. lfo_destinations.dirty = true
  928. end)
  929.  
  930. params:set_action("lfo_to_fm_low_amount", function(value)
  931. engine.lfoToFm1Amount(value)
  932. lfo_destinations.dirty = true
  933. end)
  934.  
  935. params:set_action("lfo_to_fm_high_amount", function(value)
  936. engine.lfoToFm2Amount(value)
  937. lfo_destinations.dirty = true
  938. end)
  939.  
  940. params:set_action("lfo_to_attack_amount", function(value)
  941. engine.lfoToAttackAmount(value)
  942. lfo_destinations.dirty = true
  943. end)
  944.  
  945. params:set_action("lfo_to_peak_amount", function(value)
  946. engine.lfoToPeakAmount(value)
  947. lfo_destinations.dirty = true
  948. end)
  949.  
  950. params:set_action("lfo_to_decay_amount", function(value)
  951. engine.lfoToDecayAmount(value)
  952. lfo_destinations.dirty = true
  953. end)
  954.  
  955. params:set_action("lfo_to_reverb_mix_amount", function(value)
  956. engine.lfoToReverbMixAmount(value)
  957. lfo_destinations.dirty = true
  958. end)
  959.  
  960. params:set_action("drift", function(value)
  961. engine.drift(value)
  962. drift.dirty = true
  963. end)
  964.  
  965. wave_shape.actual = params:get("wave_shape")
  966. wave_folds.actual = params:get("wave_folds")
  967. fm1_amount.actual = params:get("fm_low_amount")
  968. fm2_amount.actual = params:get("fm_high_amount")
  969. attack.actual = params:get("attack")
  970. peak.actual = params:get("peak")
  971. decay.actual = params:get("decay")
  972. reverb_mix.actual = params:get("reverb_mix")
  973.  
  974. -- tunnels
  975. tn.init()
  976. -- need to set to 0 here for some reason
  977. for i=1, 4 do
  978. softcut.level(i, 0)
  979. end
  980.  
  981. -- Init UI
  982.  
  983. pages = UI.Pages.new(1, 5)
  984. tab_titles[2][1] = params:string("env_type")
  985. tabs = UI.Tabs.new(1, tab_titles[pages.index])
  986. tunnelmodes_list = UI.ScrollingList.new(8, 8, 1, tunnelmodes)
  987.  
  988. fm1_dial = UI.Dial.new(72, 19, 22, fm1_amount.actual * 100, 0, 100, 1)
  989. fm2_dial = UI.Dial.new(97, 34, 22, fm2_amount.actual * 100, 0, 100, 1)
  990.  
  991. reverb_slider = UI.Slider.new(102, 22, 3, 36, reverb_mix.actual, 0, 1, {0.5})
  992.  
  993. lfo_destinations_list = UI.ScrollingList.new(71, 18, 1, {"Freq", "Shape", "Folds", "FM Low", "FM High", "Attack", "Peak", "Decay", "Reverb"})
  994. lfo_destinations_list.num_visible = 4
  995. lfo_destinations_list.num_above_selected = 0
  996. lfo_destinations_list.active = false
  997.  
  998. lfo_amounts_list = UI.ScrollingList.new(120, 18)
  999. lfo_amounts_list.num_visible = 4
  1000. lfo_amounts_list.num_above_selected = 0
  1001. lfo_amounts_list.text_align = "right"
  1002. lfo_amounts_list.active = false
  1003. update_lfo_amounts_list()
  1004.  
  1005. drift_dial = UI.Dial.new(85, 28, 22, params:get("drift") * 100, 0, 100, 1)
  1006.  
  1007. -- Init graphs
  1008.  
  1009. wave_graph = Graph.new(0, 2, "lin", -1, 1, "lin", nil, true, false)
  1010. wave_graph:set_position_and_size(8, 22, 49, 36)
  1011. wave_table = generate_wave_table(2, wave_graph:get_width() * SUB_SAMPLING)
  1012. local wave_func = function(x)
  1013. return generate_wave(util.linlin(0, 2, 1, wave_graph:get_width() * SUB_SAMPLING, x))
  1014. end
  1015. wave_graph:add_function(wave_func, SUB_SAMPLING)
  1016.  
  1017. init_env_graph(params:get("env_type"))
  1018.  
  1019. lfo_graph = Graph.new(0, 1, "lin", -1, 1, "lin", nil, true, false)
  1020. lfo_graph:set_position_and_size(8, 18, 49, 36)
  1021. lfo_graph:add_function(generate_lfo_wave, SUB_SAMPLING)
  1022.  
  1023. env_status.text = ""
  1024. env_status.x, env_status.y = 0, 0
  1025. env_status_metro = metro.init()
  1026. env_status_metro.event = function()
  1027. env_status.text = ""
  1028. screen_dirty = true
  1029. end
  1030.  
  1031. spring_path = generate_spring_path(10, 36, 5)
  1032.  
  1033. randomize_dice()
  1034.  
  1035. -- Init polls
  1036.  
  1037. local wave_shape_poll = poll.set("waveShapeMod", function(value)
  1038. if wave_shape.modu ~= value then
  1039. wave_shape.modu = value
  1040. wave_shape.dirty = true
  1041. end
  1042. end)
  1043. wave_shape_poll:start()
  1044.  
  1045. local wave_folds_poll = poll.set("waveFoldsMod", function(value)
  1046. if wave_folds.modu ~= value then
  1047. wave_folds.modu = value
  1048. wave_folds.dirty = true
  1049. end
  1050. end)
  1051. wave_folds_poll:start()
  1052.  
  1053. local fm1_amount_poll = poll.set("fm1AmountMod", function(value)
  1054. if fm1_amount.modu ~= value then
  1055. fm1_amount.modu = value
  1056. fm1_amount.dirty = true
  1057. end
  1058. end)
  1059. fm1_amount_poll:start()
  1060.  
  1061. local fm2_amount_poll = poll.set("fm2AmountMod", function(value)
  1062. if fm2_amount.modu ~= value then
  1063. fm2_amount.modu = value
  1064. fm2_amount.dirty = true
  1065. end
  1066. end)
  1067. fm2_amount_poll:start()
  1068.  
  1069. local attack_poll = poll.set("attackMod", function(value)
  1070. if attack.modu ~= value then
  1071. attack.modu = value
  1072. attack.dirty = true
  1073. end
  1074. end)
  1075. attack_poll:start()
  1076.  
  1077. local peak_poll = poll.set("peakMulMod", function(value)
  1078. if peak.modu ~= value then
  1079. peak.modu = value
  1080. peak.dirty = true
  1081. end
  1082. end)
  1083. peak_poll:start()
  1084.  
  1085. local decay_poll = poll.set("decayMod", function(value)
  1086. if decay.modu ~= value then
  1087. decay.modu = value
  1088. decay.dirty = true
  1089. end
  1090. end)
  1091. decay_poll:start()
  1092.  
  1093. local reverb_mix_poll = poll.set("reverbMixMod", function(value)
  1094. if reverb_mix.modu ~= value then
  1095. reverb_mix.modu = value
  1096. reverb_mix.dirty = true
  1097. end
  1098. end)
  1099. reverb_mix_poll:start()
  1100.  
  1101. -- Start drawing to screen
  1102. screen_refresh_metro = metro.init()
  1103. screen_refresh_metro.event = function()
  1104. update()
  1105. if screen_dirty then
  1106. screen_dirty = false
  1107. redraw()
  1108. end
  1109. end
  1110. screen_refresh_metro:start(1 / SCREEN_FRAMERATE)
  1111.  
  1112. end
  1113.  
  1114.  
  1115. -- Draw functions
  1116.  
  1117. local function rotate(x, y, center_x, center_y, angle_rads)
  1118. local sin_a = math.sin(angle_rads)
  1119. local cos_a = math.cos(angle_rads)
  1120. x = x - center_x
  1121. y = y - center_y
  1122. return (x * cos_a - y * sin_a) + center_x, (x * sin_a + y * cos_a) + center_y
  1123. end
  1124.  
  1125. local function draw_input_indicator()
  1126. screen.level(4)
  1127. screen.move(0, 1)
  1128. screen.line(5, 1)
  1129. screen.line(2.5, 4)
  1130. screen.close()
  1131. screen.fill()
  1132. end
  1133.  
  1134. local function draw_background_rects()
  1135. screen.level(1)
  1136. screen.rect(8, 18, 49, 44)
  1137. screen.fill()
  1138. screen.rect(71, 18, 49, 44)
  1139. screen.fill()
  1140. end
  1141.  
  1142. local function draw_spring(x, y, active)
  1143. screen.move(x + spring_path[1].x + 0.5, y + spring_path[1].y + 0.5)
  1144. for i = 2, #spring_path do
  1145. screen.line(x + spring_path[i].x + 0.5, y + spring_path[i].y + 0.5)
  1146. end
  1147. if active then
  1148. screen.level(15)
  1149. screen.line_width(0.7)
  1150. else
  1151. screen.level(5)
  1152. end
  1153. screen.stroke()
  1154. screen.line_width(1)
  1155. end
  1156.  
  1157. local function draw_die(x, y, rotation_rads, face)
  1158. screen.level(15)
  1159. local size = 9
  1160. screen.move(rotate(x - size + 0.5, y - size + 0.5, x, y, rotation_rads))
  1161. screen.line(rotate(x + size - 0.5, y - size + 0.5, x, y, rotation_rads))
  1162. screen.line(rotate(x + size - 0.5, y + size - 0.5, x, y, rotation_rads))
  1163. screen.line(rotate(x - size + 0.5, y + size - 0.5, x, y, rotation_rads))
  1164. screen.close()
  1165. screen.stroke()
  1166.  
  1167. local dot_size = 1
  1168. local dx, dy
  1169. if face == 1 then
  1170. dot_size = 1.5
  1171. dx, dy = rotate(x, y, x, y, rotation_rads)
  1172. screen.circle(dx, dy, dot_size)
  1173. screen.fill()
  1174. elseif face == 2 then
  1175. dx, dy = rotate(x + 3, y - 3, x, y, rotation_rads)
  1176. screen.circle(dx, dy, dot_size)
  1177. screen.fill()
  1178. dx, dy = rotate(x - 3, y + 3, x, y, rotation_rads)
  1179. screen.circle(dx, dy, dot_size)
  1180. screen.fill()
  1181. elseif face == 3 then
  1182. dx, dy = rotate(x + 4, y - 4, x, y, rotation_rads)
  1183. screen.circle(dx, dy, dot_size)
  1184. screen.fill()
  1185. dx, dy = rotate(x, y, x, y, rotation_rads)
  1186. screen.circle(dx, dy, dot_size)
  1187. screen.fill()
  1188. dx, dy = rotate(x - 4, y + 4, x, y, rotation_rads)
  1189. screen.circle(dx, dy, dot_size)
  1190. screen.fill()
  1191. elseif face == 4 then
  1192. dx, dy = rotate(x - 3, y - 3, x, y, rotation_rads)
  1193. screen.circle(dx, dy, dot_size)
  1194. screen.fill()
  1195. dx, dy = rotate(x + 3, y - 3, x, y, rotation_rads)
  1196. screen.circle(dx, dy, dot_size)
  1197. screen.fill()
  1198. dx, dy = rotate(x + 3, y + 3, x, y, rotation_rads)
  1199. screen.circle(dx, dy, dot_size)
  1200. screen.fill()
  1201. dx, dy = rotate(x - 3, y + 3, x, y, rotation_rads)
  1202. screen.circle(dx, dy, dot_size)
  1203. screen.fill()
  1204. elseif face == 5 then
  1205. dx, dy = rotate(x, y, x, y, rotation_rads)
  1206. screen.circle(dx, dy, dot_size)
  1207. screen.fill()
  1208. dx, dy = rotate(x - 4, y - 4, x, y, rotation_rads)
  1209. screen.circle(dx, dy, dot_size)
  1210. screen.fill()
  1211. dx, dy = rotate(x + 4, y - 4, x, y, rotation_rads)
  1212. screen.circle(dx, dy, dot_size)
  1213. screen.fill()
  1214. dx, dy = rotate(x + 4, y + 4, x, y, rotation_rads)
  1215. screen.circle(dx, dy, dot_size)
  1216. screen.fill()
  1217. dx, dy = rotate(x - 4, y + 4, x, y, rotation_rads)
  1218. screen.circle(dx, dy, dot_size)
  1219. screen.fill()
  1220. elseif face == 6 then
  1221. dx, dy = rotate(x - 3, y - 4, x, y, rotation_rads)
  1222. screen.circle(dx, dy, dot_size)
  1223. screen.fill()
  1224. dx, dy = rotate(x + 3, y - 4, x, y, rotation_rads)
  1225. screen.circle(dx, dy, dot_size)
  1226. screen.fill()
  1227. dx, dy = rotate(x - 3, y, x, y, rotation_rads)
  1228. screen.circle(dx, dy, dot_size)
  1229. screen.fill()
  1230. dx, dy = rotate(x + 3, y, x, y, rotation_rads)
  1231. screen.circle(dx, dy, dot_size)
  1232. screen.fill()
  1233. dx, dy = rotate(x - 3, y + 4, x, y, rotation_rads)
  1234. screen.circle(dx, dy, dot_size)
  1235. screen.fill()
  1236. dx, dy = rotate(x + 3, y + 4, x, y, rotation_rads)
  1237. screen.circle(dx, dy, dot_size)
  1238. screen.fill()
  1239. end
  1240. end
  1241.  
  1242. local function draw_dice()
  1243. draw_die(20, util.linlin(0, 1, 32, 17, dice_throw_progress), util.linlin(0, 1, dice[1].table_angle, dice[1].top_angle, dice_throw_progress), dice[1].face)
  1244. draw_die(45, util.linlin(0, 1, 46, 61, dice_throw_progress), util.linlin(0, 1, dice[2].table_angle, dice[2].top_angle, dice_throw_progress), dice[2].face)
  1245. end
  1246.  
  1247. local function update_dice()
  1248. if not dice_need_update then return end
  1249.  
  1250. if dice_thrown then
  1251. if dice_throw_progress < 0.05 then
  1252. for i = 1, 2 do
  1253. local direction = (dice[i].table_angle > 0) and 1 or -1
  1254. dice[i].table_angle = dice[i].table_angle - (2 * math.pi * direction)
  1255. end
  1256. dice_thrown = false
  1257. end
  1258. set_dice_throw_vel(-0.08)
  1259. else
  1260. if dice_throw_progress > 0.9 then
  1261. dice_thrown = true
  1262. randomize_dice()
  1263. Passersby.randomize_params()
  1264. set_dice_throw_vel(-0.3)
  1265. else
  1266. set_dice_throw_vel(util.linlin(0, 1, -0.02, -0.03, dice_throw_progress))
  1267. end
  1268. end
  1269.  
  1270. if dice_throw_progress <= 0 then
  1271. dice_throw_vel = math.max(dice_throw_vel, 0)
  1272. end
  1273.  
  1274. dice_throw_progress = util.clamp(dice_throw_progress + dice_throw_vel, 0, 1)
  1275.  
  1276. if pages.index == 4 then screen_dirty = true end
  1277. if dice_throw_progress == 0 and not dice_thrown then dice_need_update = false end
  1278. end
  1279.  
  1280. function update()
  1281.  
  1282. if pages.index == 1 then
  1283. if wave_shape.dirty then update_wave_shape() end
  1284. if wave_folds.dirty then update_wave_folds() end
  1285. if fm1_amount.dirty then update_fm1_amount() end
  1286. if fm2_amount.dirty then update_fm2_amount() end
  1287. elseif pages.index == 2 then
  1288. if attack.dirty then update_attack() end
  1289. if peak.dirty then update_peak() end
  1290. if decay.dirty then update_decay() end
  1291. if reverb_mix.dirty then update_reverb_mix() end
  1292. elseif pages.index == 3 then
  1293. if lfo_shape.dirty then update_lfo_shape() end
  1294. if lfo_freq.dirty then update_lfo_freq() end
  1295. if lfo_destinations.dirty then update_lfo_destinations() end
  1296. elseif pages.index == 4 then
  1297. if drift.dirty then update_drift() end
  1298. elseif pages.index == 5 then
  1299. --update_tunnels()
  1300. end
  1301.  
  1302. update_dice()
  1303. end
  1304.  
  1305. function redraw()
  1306. screen.clear()
  1307.  
  1308. pages:redraw()
  1309. tabs:redraw()
  1310.  
  1311. if input_indicator_active then draw_input_indicator() end
  1312.  
  1313. -- draw_background_rects()
  1314.  
  1315. if pages.index == 1 then
  1316.  
  1317. -- Wave
  1318. wave_graph:redraw()
  1319.  
  1320. -- FM
  1321. fm1_dial:redraw()
  1322. fm2_dial:redraw()
  1323. screen.level(3)
  1324. screen.move(83, 33)
  1325. screen.text_center("L")
  1326. screen.move(108, 48)
  1327. screen.text_center("H")
  1328. screen.fill() -- Prevents extra line
  1329.  
  1330. elseif pages.index == 2 then
  1331.  
  1332. -- Env
  1333. env_graph:redraw()
  1334. screen.level(3)
  1335. screen.move(env_status.x, env_status.y)
  1336. screen.text_right(env_status.text)
  1337.  
  1338. -- Reverb
  1339. screen.fill()
  1340. draw_spring(82, 22, tabs.index == 2)
  1341. reverb_slider:redraw()
  1342.  
  1343. elseif pages.index == 3 then
  1344.  
  1345. -- LFO
  1346. lfo_graph:redraw()
  1347. screen.level(3)
  1348. screen.move(8, 62)
  1349. screen.text(params:string("lfo_freq"))
  1350.  
  1351. -- LFO Targets
  1352. if tabs.index == 2 then screen.level(15) else screen.level(3) end
  1353. lfo_destinations_list:redraw()
  1354. lfo_amounts_list:redraw()
  1355.  
  1356. elseif pages.index == 4 then
  1357.  
  1358. -- Dice
  1359. draw_dice()
  1360.  
  1361. -- Drift
  1362. screen.move(96, 23)
  1363. screen.text_center("Drift")
  1364. screen.fill()
  1365. drift_dial:redraw()
  1366.  
  1367. elseif pages.index == 5 then
  1368. tunnelmodes_list:redraw()
  1369. end
  1370.  
  1371. screen.update()
  1372. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement