0x2734…caba

All memos sent from and to 0x2734…caba.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eElkIjoiY2QzZjgwZWMtZjE5Ny00NDUzLThkZGMtZTAzNDhiNjI2MjVjIiwiaWF0IjoxNzEyNDQyNzI3LCJpc3MiOiJwYXBlci54eXoifQ.jupsq-BNplSFzDpU5rm2zGmEYQJVps2PbfN4gAo4B-s
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eElkIjoiM2RiMTVlMDYtZDZjNC00OTRiLWE1OTgtNmZjZTczNWZhZjBmIiwiaWF0IjoxNzEyNDQyMjU2LCJpc3MiOiJwYXBlci54eXoifQ.ZxsOFEvvfi-xLJtTmlw2P5tYCXoKdEz06dTxfYrz-qA
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eElkIjoiZDQ5NTYyYzctODc4NC00YTllLTkyNDItMDU4MDZhYjlkN2QyIiwiaWF0IjoxNzEyNDQxNjA2LCJpc3MiOiJwYXBlci54eXoifQ.V_UESqogZ4vftcD85vXt7nKmYKVI4ePJ2TqEvIuU5dE
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eElkIjoiZjBiOGRiMGYtMjg2ZC00ZWZhLTg4MmQtNDFkMmUwMWU1NzcxIiwiaWF0IjoxNzEwNjk4NzYyLCJpc3MiOiJwYXBlci54eXoifQ.D1rPcYBabBHN9EhadR797m3ffz5IqxBHCMl349Heu_4
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eElkIjoiOGU0NDBhY2QtZTUxNi00Yzc2LWIwOGItZWIwZWFiZWFjY2ZiIiwiaWF0IjoxNzEwNjk0ODAyLCJpc3MiOiJwYXBlci54eXoifQ.DVGV9_loagOx10cLtKiciOJZ-jEqbYe3S__WtNohnj4
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eElkIjoiYzQ3OGFiYWEtMWRkOS00NThkLWIwMGYtNDY5M2U4MDQyMzIxIiwiaWF0IjoxNzAwMjQ1NjMxLCJpc3MiOiJwYXBlci54eXoifQ.Y9lWBjiC5DfaLc2OtbBiqzjqphK0ZiocA0z95u5A4JU
var num_backgrounds var num_horiz_stripes var num_vert_stripes var center_horiz_stripe = false var center_vert_stripe = false var woven = false var num_backgrounds_probs = [0.24,0.29,0.18,.29] var density_probs = [0.05,0.15,0.3,0.3,0.15,0.05] var center_horiz_stripe_prob = 0.1 var center_vert_stripe_prob = 0.1 var weave_prob = 0.72 var synth_size = 2000 var r_period_reset var g_period_reset var b_period_reset var r_period var g_period var b_period const sync_probs = [0.01, 0.05, 0.1, 0.5] var all_period_sync_prob var WIDTH = window.innerWidth var HEIGHT = window.innerHeight var output_img var x_offset = 0 var y_offset = 0 var r_incr = 0.0 var r_value = 0 var r_shifter = 1.0 var r_bot = 0 var r_range = 255 var g_incr = 0.0 var g_value = 0 var g_shifter = 1.0 var g_bot = 0 var g_range = 255 var b_incr = 0.0 var b_value = 0 var b_shifter = 1.0 var b_bot = 0 var b_range = 255 var R var drawn = false var loaded = false function setup() { createCanvas(WIDTH, HEIGHT) noStroke() //tokenData = genTokenData(123) // remove R = new Random() make_parameters() update_incrs() output_img = createImage(WIDTH,HEIGHT) } function make_parameters() { let nbp = [] for (let i = 0; i < 4; i++){ for (let j = 0; j < num_backgrounds_probs[i] * 100; j++){ nbp[nbp.length] = i + 1}} num_backgrounds = nbp[Math.floor(R.random_num(0,nbp.length))] let dp = [] for (let i = 0; i < 6; i++){ for (let j = 0; j < density_probs[i] * 100; j++){ dp[dp.length] = i + 1}} num_horiz_stripes = dp[Math.floor(R.random_num(0,dp.length))] num_vert_stripes = dp[Math.floor(R.random_num(0,dp.length))] woven = R.random_bool(weave_prob) if (woven && num_vert_stripes == 1) num_vert_stripes = 2 center_horiz_stripe = R.random_bool(center_horiz_stripe_prob) center_vert_stripe = R.random_bool(center_vert_stripe_prob) r_period_reset = Math.floor(synth_size / Math.floor(R.random_num(1, 6))) g_period_reset = Math.floor(synth_size / Math.floor(R.random_num(1, 6))) b_period_reset = Math.floor(synth_size / Math.floor(R.random_num(1, 6))) r_period = r_period_reset g_period = g_period_reset b_period = b_period_reset all_period_sync_prob = sync_probs[Math.floor(R.random_num(0, 4))] } function make_augury_image(){ switch (num_backgrounds) { case 1: output_img.copy(make_image(), 0, 0, Math.floor(R.random_num(250,synth_size)),Math.floor(R.random_num(250,synth_size)),0, 0, WIDTH, HEIGHT) break; case 2: output_img.copy(make_image(), 0, 0,Math.floor(R.random_num(250,synth_size)),Math.floor(R.random_num(250,synth_size)),0, 0, Math.floor(WIDTH/2), HEIGHT) output_img.copy(make_image(), 0, 0,Math.floor(R.random_num(250,synth_size)),Math.floor(R.random_num(250,synth_size)),Math.floor(WIDTH/2), 0, Math.floor(WIDTH/2), HEIGHT) break case 3: output_img.copy(make_image(), 0, 0,Math.floor(R.random_num(250,synth_size)),Math.floor(R.random_num(250,synth_size)),0, 0, WIDTH, Math.floor(HEIGHT/3)) output_img.copy(make_image(), 0, 0,Math.floor(R.random_num(250,synth_size)),Math.floor(R.random_num(250,synth_size)),0, Math.floor(HEIGHT/3), WIDTH, Math.floor(HEIGHT/3 * 2)) output_img.copy(make_image(), 0, 0,Math.floor(R.random_num(250,synth_size)),Math.floor(R.random_num(250,synth_size)),0, Math.floor(HEIGHT/3 * 2), WIDTH, HEIGHT) break case 4: output_img.copy(make_image(), 0, 0,Math.floor(R.random_num(250,synth_size)),Math.floor(R.random_num(250,synth_size)),0, 0, Math.floor(WIDTH/2), Math.floor(HEIGHT/2)) output_img.copy(make_image(), 0, 0,Math.floor(R.random_num(250,synth_size)),Math.floor(R.random_num(250,synth_size)),Math.floor(WIDTH/2), 0, WIDTH, Math.floor(HEIGHT/2)) output_img.copy(make_image(), 0, 0,Math.floor(R.random_num(250,synth_size)),Math.floor(R.random_num(250,synth_size)),0, Math.floor(HEIGHT/2), Math.floor(WIDTH/2), HEIGHT) output_img.copy(make_image(), 0, 0,Math.floor(R.random_num(250,synth_size)),Math.floor(R.random_num(250,synth_size)),Math.floor(WIDTH/2), Math.floor(HEIGHT/2), WIDTH, HEIGHT) break default: output_img.copy(make_image(), 0, 0, Math.floor(R.random_num(250,synth_size)),Math.floor(R.random_num(250,synth_size)),0, 0, WIDTH, HEIGHT) break; } var v_stripes = [] var v_stripes_C = 0.0 var h_stripes = [] var h_stripes_C = 0.0 var got_all = false if (center_horiz_stripe){ var h = Math.floor(R.random_num(HEIGHT/50,HEIGHT/7)) h_stripes_C = h num_horiz_stripes -= 1} var num_h_T = Math.floor(R.random_num(0,num_horiz_stripes+1)) var num_h_B = num_horiz_stripes - num_h_T var y = 0 var i = 0 while (!got_all){ got_all = true y = 0 for (i = 0; i < num_h_T; i++){ if (y > HEIGHT/4) got_all = false y = Math.floor(R.random_num(y, HEIGHT / 4)) h_stripes[i] = y y += HEIGHT/50}} got_all = false while (!got_all){ got_all = true y = HEIGHT - HEIGHT / 4 for (i = num_h_T; i < num_horiz_stripes; i++){ if (y > HEIGHT) got_all = false y = Math.floor(R.random_num(y, HEIGHT)) h_stripes[i] = y y += HEIGHT/50}} if (center_vert_stripe){ var w = Math.floor(R.random_num(WIDTH/50,WIDTH/7)) v_stripes_C = w num_vert_stripes -= 1} var num_v_L = Math.floor(R.random_num(0,num_vert_stripes+1)) var num_v_R = num_vert_stripes - num_v_L got_all = false while (!got_all){ got_all = true var x = 0 for (i = 0; i < num_v_L; i++){ if (x > WIDTH/4) got_all = false x = Math.floor(R.random_num(x, WIDTH / 4)) v_stripes[i] = x x += WIDTH/50}} got_all = false while (!got_all){ got_all = true let x = WIDTH - WIDTH / 4 for (i = num_v_L; i < num_vert_stripes; i++){ if (x > WIDTH) got_all = false x = Math.floor(R.random_num(x, WIDTH)) v_stripes[i] = x x += WIDTH/50}} if (woven){ if (center_vert_stripe) vert_stripe(Math.floor(WIDTH/2 - v_stripes_C / 2), v_stripes_C) if (center_horiz_stripe) horiz_stripe(Math.floor(HEIGHT/2 - h_stripes_C / 2), h_stripes_C) let v_done = 0 let h_done = 0 while (v_done < v_stripes.length || h_done < h_stripes.length){ if (v_done < v_stripes.length){ vert_stripe(v_stripes[v_done], Math.floor(R.random_num(25,WIDTH/7))) v_done += 1} if (h_done < h_stripes.length){ horiz_stripe(h_stripes[h_done], Math.floor(R.random_num(25,HEIGHT/7))) h_done += 1}}} else { if (center_horiz_stripe) horiz_stripe(Math.floor(HEIGHT/2 - h_stripes_C / 2), h_stripes_C) for (var i = 0; i < h_stripes.length; i++){horiz_stripe(h_stripes[i], Math.floor(R.random_num(25,HEIGHT/7)))} if (center_vert_stripe) vert_stripe(Math.floor(WIDTH/2 - v_stripes_C / 2), v_stripes_C) for (var i = 0; i < v_stripes.length; i++){vert_stripe(v_stripes[i], Math.floor(R.random_num(25,WIDTH/7)))}} } function horiz_stripe(y_start, h){ img_seg = get_image_segment() num_segs = Math.floor(R.random_num(2,10)) dest_w = WIDTH / num_segs dest_h = h dest_x = 0 dest_y = y_start for (n = 0; n < num_segs; n++){ output_img.copy(img_seg, 0, 0, img_seg.width, img_seg.height, Math.floor(dest_x), dest_y, Math.ceil(dest_w), dest_h) img_seg = mirror_h_image(img_seg) dest_x += dest_w} } function vert_stripe(x_start, w){ img_seg = get_image_segment() num_segs = Math.floor(R.random_num(2,10)) dest_w = w dest_h = HEIGHT / num_segs dest_x = x_start dest_y = 0 for (n = 0; n < num_segs; n++){ output_img.copy(img_seg, 0, 0, img_seg.width, img_seg.height, dest_x, Math.floor(dest_y), dest_w, Math.ceil(dest_h)) img_seg = mirror_v_image(img_seg) dest_y += dest_h} } function draw() { if (frameCount == 1){ background(0) return} if (!drawn) { make_augury_image() image(output_img, 0, 0, WIDTH, HEIGHT) drawn = true} } function mirror_h_image(orig_img) { var mirror_img = createImage(orig_img.width,orig_img.height) mirror_img.loadPixels() orig_img.loadPixels() orig_img_numcols = orig_img.width orig_img_numrows = orig_img.height orig_img_valsperrow = orig_img_numcols * 4 for (var pr = 0; pr < orig_img_numrows; pr++) { for (var pc = 0; pc < orig_img_numcols; pc++) { po = (pr * orig_img_valsperrow) + orig_img_valsperrow pm = (pr * orig_img_valsperrow) + (pc * 4); mirror_img.pixels[pm] = orig_img.pixels[po - ((pc*4) + 4)] mirror_img.pixels[pm+1] = orig_img.pixels[po - ((pc*4) + 3)] mirror_img.pixels[pm+2] = orig_img.pixels[po - ((pr*4) + 2)] mirror_img.pixels[pm+3] = orig_img.pixels[po - ((pc*4) + 1)]}} mirror_img.updatePixels() return mirror_img } function mirror_v_image(orig_img) { var mirror_img = createImage(orig_img.width,orig_img.height) mirror_img.loadPixels() orig_img.loadPixels() orig_img_numcols = orig_img.width orig_img_numrows = orig_img.height orig_img_valsperrow = orig_img_numcols * 4 for (var pr = 0; pr < orig_img_numrows; pr++) { for (var pc = 0; pc < orig_img_numcols; pc++) { po = ((orig_img_numrows - (pr +1) ) * orig_img_valsperrow) + (pc * 4) pm = (pr * orig_img_valsperrow) + (pc * 4) mirror_img.pixels[pm] = orig_img.pixels[po] mirror_img.pixels[pm+1] = orig_img.pixels[po+ 1] mirror_img.pixels[pm+2] = orig_img.pixels[po+ 2] mirror_img.pixels[pm+3] = orig_img.pixels[po + 3]}} mirror_img.updatePixels() return mirror_img } function make_image() { tmp_img = createImage(synth_size,synth_size) tmp_img.loadPixels() var y = 0 for (var j = 0; j < synth_size * synth_size; j++) { if (j % synth_size == 0) y = Math.floor(j / synth_size) var x = int(j % synth_size) pixel_i = int((y * synth_size + x) * 4) tmp_img.pixels[pixel_i] = Math.round(r_value) tmp_img.pixels[pixel_i + 1] = Math.round(g_value) tmp_img.pixels[pixel_i + 2] = Math.round(b_value) tmp_img.pixels[pixel_i + 3] = 255 increment_rbg(j)} tmp_img.updatePixels() if (R.random_bool(all_period_sync_prob)) sync_periods() return tmp_img } function get_image_segment() { var out_w = Math.floor(R.random_num(10,synth_size)) var out_h = Math.floor(R.random_num(10,synth_size)) var src_img = make_image() var tmp_img = createImage(out_w, out_h) var src_w = Math.floor(R.random_num(10,synth_size)) var src_h = Math.floor(R.random_num(10,synth_size)) var src_x = Math.floor(R.random_num(0,synth_size-src_w)) var src_y = Math.floor(R.random_num(0,synth_size-src_h)) tmp_img.copy(src_img, src_x, src_y, src_w, src_h,0,0,out_w,out_h) return tmp_img } function increment_rbg(mega_i) { r_value = ((r_range - abs(r_range - (mega_i % r_period) * r_incr)) + r_bot) * r_shifter if (r_value > 255) r_value = 255 if (Math.floor(r_value) <= r_bot) { if (R.random_bool(0.0001)) { r_period = random_period(r_period) update_incrs() } else if (R.random_bool(0.01)) { if (R.random_bool) { r_incr *= 1.0 + 0.001 } else { r_incr *= 1.0 - 0.001 } } } g_value = ((g_range - abs(g_range - (mega_i % g_period) * g_incr)) + g_bot) * g_shifter if (g_value > 255) g_value = 255 if (Math.floor(g_value) <= g_bot) { if (R.random_bool(0.0001)) { g_period = random_period(g_period) update_incrs() } else if (R.random_bool(0.01)) { if (R.random_bool) { g_incr *= 1.0001 } else { g_incr *= 0.9999 } } } b_value = ((b_range - abs(b_range - (mega_i % b_period) * b_incr)) + b_bot) * b_shifter if (b_value > 255) b_value = 255 if (Math.floor(b_value) <= b_bot) { b_value = 0 b_incr *= -1 if (R.random_bool(0.0001)) { b_period = random_period(b_period) update_incrs() } else if (R.random_bool(0.01)) { if (R.random_bool) { b_incr *= 1.0001 } else { b_incr *= 0.9999 } } } } function random_period(curr_period) { var p = curr_period p += R.random_num(-2, 2) if (p < 10) p = 10 return p } function sync_period(which) { if (which == "r") r_period = r_period_reset else if (which == "g") g_period = g_period_reset if (which == "b") b_period = b_period_reset update_incrs() } function sync_periods() { r_period = r_period_reset g_period = g_period_reset b_period = b_period_reset update_incrs() } function update_incrs() { if (r_period < 10) r_period = 10 if (g_period < 10) g_period = 10 if (b_period < 10) b_period = 10 r_incr = r_range / (r_period * 0.5) g_incr = g_range / (g_period * 0.5) b_incr = b_range / (b_period * 0.5) } class Random { constructor() { this.useA = false var sfc32 = function (uint128Hex) { var a = parseInt(uint128Hex.substr(0, 8), 16) var b = parseInt(uint128Hex.substr(8, 8), 16) var c = parseInt(uint128Hex.substr(16, 8), 16) var d = parseInt(uint128Hex.substr(24, 8), 16) return function () { a |= 0 b |= 0 c |= 0 d |= 0 var t = (((a + b) | 0) + d) | 0 d = (d + 1) | 0 a = b ^ (b >>> 9) b = (c + (c << 3)) | 0 c = (c << 21) | (c >>> 11) c = (c + t) | 0 return (t >>> 0) / 4294967296 } } this.prngA = new sfc32(tokenData.hash.substr(2, 32)) this.prngB = new sfc32(tokenData.hash.substr(34, 32)) for (var i = 0; i < 1e6; i += 2) { this.prngA() this.prngB() } } random_dec() { this.useA = !this.useA return this.useA ? this.prngA() : this.prngB() } random_num(a, b) { return a + (b - a) * this.random_dec() } random_bool(p) { return this.random_dec() < p } }
Augury is a festive collection ranging from vast sorbet-colored landscapes to dense pattern iterations. Augury remixes frames from LoVid’s red, green, and blue (RGB) luminous moving image work. For over two decades, LoVid has been making audiovisual works using custom-built handmade analog video (and audio) synthesizers. In addition to moving-image media, LoVid’s outputs capture stills (frames) from generative video and incorporate these into digital collages, textile designs, wearable works, prints, and more. An essential part of LoVid’s process involves translating signals and experiences from one medium into another. This conversion/interoperability appears critical for living in an interdisciplinary, intermedia, intersectional mixed-reality world. With Augury, LoVid continues exploring on-chain processes that are inspired by the mechanism and aesthetic of analog synthesis.This collection builds upon LoVid’s first analog video synthesizer-inspired collection: Tide Predictor. Each output in Augury grabs frames from the Tide Predictor algorithm (using a unique new hash) and arranges them on the screen based on a set of instructions, possibilities, and limitations. The generative compositions in Augury are therefore both procedurally related to and visually reminiscent of quilting, tapestry pattern designs, and tactile weaving. They use visual elements that LoVid often employs in static works: mirroring and repetitive looping, abrupt changes in intensity and detail, overlapping recycled patterns, and a colliding playful mix of lines and signals buzzing in different directions. The rules applied in Augury are primarily set around placing variable levels of density on the borders, the edges of the work, creating a sense of dynamic movement and discovery. Focusing the viewer’s gaze outside the center encourages shifts in perspectives, literally and symbolically. Augury is inspired both by the ideas and aesthetics in the Pattern and Decoration (P&D) movement and Glitch art. P&D emerged in the 1970s as a response and challenge to a predominantly white male aesthetic that dominated the artworld and historically marginalized art forms and practices of women and people of color. P&D took a feminist approach by shifting the conversation around crafts and decorative arts, placing them on an equal canonic level with western-style paintings. Augury expands this conversation to generative art and challenges hierarchies and relationships to status, economy, and desire. Glitch art refers to artifacts that were created by machine error, intentionally or by chance. Glitch as an art form originally emerged as a response to and celebration of loss in signals “fleeting artifacts that momentarily offer a glimpse into the inner workings and complexities of storage, display, and communication technology” (Iman Moradi, 2009). In Augury, LoVid incorporates a color palette, textures, and shapes inspired by both digital glitches and inherently unstable analog outputs. Aesthetically and viscerally, Augury finds beauty in discarded marginal dysfunctionality. This collection’s title, Augury, refers to the practice of interpreting omens/predicting the future based on the behavior of birds. Complex systems and environmental signals inspire and require attention. LoVid’s Augury harnesses and embraces this chaos, the turbulent flow of data, to bring you a sweet and colorful feast for the eyes, food for thought and beyond!
var r_period_reset var g_period_reset var b_period_reset var r_period var g_period var b_period const sync_probs = [0.01, 0.05, 0.1, 0.5] var all_period_sync_prob var WIDTH = window.innerWidth var HEIGHT = window.innerHeight var img var x_offset = 0 var y_offset = 0 var r_incr = 0.0 var r_value = 0 var g_incr = 0.0 var g_value = 0 var b_incr = 0.0 var b_value = 0 var R var timey = 0 var drawWait = 1 function setup() { createCanvas(WIDTH, HEIGHT) noStroke() R = new Random() make_parameters() update_incrs() img = createImage(1000,1000) img.loadPixels() if (WIDTH > HEIGHT) x_offset = Math.floor((WIDTH - HEIGHT) / 2) else if (HEIGHT > WIDTH) y_offset = Math.floor((HEIGHT - WIDTH) / 2) background(0); } function draw() { if (millis() - timey >= drawWait) { var y = 0 for (var j = 0; j < 1000000; j++) { if (j % 1000 == 0) y = Math.floor(j / 1000) var x = int(j % 1000) pixel_i = int((y * 1000 + x) * 4) img.pixels[pixel_i] = Math.round(r_value) img.pixels[pixel_i + 1] = Math.round(g_value) img.pixels[pixel_i + 2] = Math.round(b_value) img.pixels[pixel_i + 3] = 255 increment_rbg(j) } img.updatePixels() if (WIDTH > HEIGHT) image(img, x_offset, y_offset, HEIGHT, HEIGHT) else image(img, x_offset, y_offset, WIDTH, WIDTH) if (R.random_bool(all_period_sync_prob)) sync_periods() timey = millis() if (drawWait == 1) drawWait = 5000 else if (drawWait == 5000) drawWait = 500 } } function make_parameters() { r_period_reset = Math.floor(1000 / Math.floor(R.random_num(1, 6))) g_period_reset = Math.floor(1000 / Math.floor(R.random_num(1, 6))) b_period_reset = Math.floor(1000 / Math.floor(R.random_num(1, 6))) r_period = r_period_reset g_period = g_period_reset b_period = b_period_reset all_period_sync_prob = sync_probs[Math.floor(R.random_num(0, 4))] } function increment_rbg(mega_i) { r_value = 255 - abs(255 - (mega_i % r_period) * r_incr) if (Math.floor(r_value) <= 0) { if (R.random_bool(0.0001)) { r_period = random_period(r_period) update_incrs() } else if (R.random_bool(0.01)) { if (R.random_bool) { r_incr *= 1.0 + 0.001 } else { r_incr *= 1.0 - 0.001 } } } g_value = 255 - abs(255 - (mega_i % g_period) * g_incr) if (Math.floor(g_value) <= 0) { if (R.random_bool(0.0001)) { g_period = random_period(g_period) update_incrs() } else if (R.random_bool(0.01)) { if (R.random_bool) { g_incr *= 1.0001 } else { g_incr *= 0.9999 } } } b_value = 255 - abs(255 - (mega_i % b_period) * b_incr) if (Math.floor(b_value) <= 0) { b_value = 0 b_incr *= -1 if (R.random_bool(0.0001)) { b_period = random_period(b_period) update_incrs() } else if (R.random_bool(0.01)) { if (R.random_bool) { b_incr *= 1.0001 } else { b_incr *= 0.9999 } } } } function random_period(curr_period) { var p = curr_period p += R.random_num(-2, 2) if (p < 10) p = 10 return p } function sync_period(which) { if (which == "r") r_period = r_period_reset else if (which == "g") g_period = g_period_reset if (which == "b") b_period = b_period_reset update_incrs() } function sync_periods() { r_period = r_period_reset g_period = g_period_reset b_period = b_period_reset update_incrs() } function update_incrs() { if (r_period < 10) r_period = 10 if (g_period < 10) g_period = 10 if (b_period < 10) b_period = 10 r_incr = 255 / (r_period * 0.5) g_incr = 255 / (g_period * 0.5) b_incr = 255 / (b_period * 0.5) } class Random { constructor() { this.useA = false var sfc32 = function (uint128Hex) { var a = parseInt(uint128Hex.substr(0, 8), 16) var b = parseInt(uint128Hex.substr(8, 8), 16) var c = parseInt(uint128Hex.substr(16, 8), 16) var d = parseInt(uint128Hex.substr(24, 8), 16) return function () { a |= 0 b |= 0 c |= 0 d |= 0 var t = (((a + b) | 0) + d) | 0 d = (d + 1) | 0 a = b ^ (b >>> 9) b = (c + (c << 3)) | 0 c = (c << 21) | (c >>> 11) c = (c + t) | 0 return (t >>> 0) / 4294967296 } } this.prngA = new sfc32(tokenData.hash.substr(2, 32)) this.prngB = new sfc32(tokenData.hash.substr(34, 32)) for (var i = 0; i < 1e6; i += 2) { this.prngA() this.prngB() } } random_dec() { this.useA = !this.useA return this.useA ? this.prngA() : this.prngB() } random_num(a, b) { return a + (b - a) * this.random_dec() } random_bool(p) { return this.random_dec() < p } }
LoVid’s signature video work mixes handmade analog synthesizers with digital tools in immersive Red, Green, and Blue (RGB) compositions that celebrate luminosity, chaos, relationships between craft and engineering, and connections between body and tech. Tide Predictor, LoVid’s first onchain generative work, builds a bridge from video synthesizer patches to algorithmic code-derived imagery. This collection is formally and technically inspired by hardware-based image generation, and places experimental moving-image, circuit boards, and electrical signal-based video art at the conceptual roots of generative art. Tide Predictor is a modular video synthesizer patch model, designed to reflect the analog spirit by working with three channels: RGB. Tide Predictor reimagines NTSC-encoded, oscillator driven electrical current based video synthesis while adding digital randomness/unpredictability, and transformations based on code, along with each mint’s unique content. In the late 19th century, mechanical analog computers used rhythm and repetition to anticipate the rise and fall of water levels. In addition to “tides”, which are low frequency oscillations of the ocean, higher frequency changes or “waves” are frequently discussed in reference to both water and electrical signals. By working with looping - and explicitly addressing the period (=1/frequency) for each RGB color - Tide Predictor extends analogies between the flow of water and the flow of electricity. LoVid’s Tide Predictor brings these relationships from the blockchain, through your screen, straight to your retina!