Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

flow.gno

2.77 Kb · 88 lines
 1package radio
 2
 3// Main's flow is a pure function of the clock and the stations: between
 4// listeners' picks, each UTC hour Main simulcasts one genre station, playing
 5// what it plays (its own picks included) until the next hour. The hour's genre follows an energy line around the
 6// target of the time of day (UTC dayparts: calm at night, peak in the
 7// evening): one step below the target in a 3-hour block's first hour, the
 8// target in its second, one step above in its third, or the nearest genre
 9// with a live track. Reads compute it and nothing is written, so it never
10// runs dry and costs GnoRadio nothing: no Sync, robot or keeper.
11
12// energy orders every genre from calm to intense; Main falls back on it.
13var energy = [NumGenres]int{
14	3,  // Ambient
15	16, // Cinematic & Classical
16	15, // Folk & Acoustic
17	14, // Jazz & Blues
18	8,  // Lo-fi Beats
19	10, // R&B & Soul
20	19, // Reggae & Dub
21	17, // World
22	18, // Latin
23	20, // Funk & Disco
24	13, // Pop
25	9,  // Hip-hop & Rap
26	11, // Rock & Indie
27	2,  // Synthwave
28	1,  // Electronica
29	5,  // House
30	4,  // Techno
31	7,  // Dubstep & Trap
32	6,  // Drum & Bass
33	12, // Metal & Punk
34}
35
36// mainFlow is what Main relays by default, from calm to intense: the
37// mainstream genres. The niche ones (Ambient, Cinematic, Synthwave, Techno,
38// Dubstep, Drum & Bass, Metal, World) keep their own stations; Main reaches
39// for them only when none of these has a live track.
40var mainFlow = []int{
41	8,  // Lo-fi Beats
42	14, // Jazz & Blues
43	15, // Folk & Acoustic
44	10, // R&B & Soul
45	19, // Reggae & Dub
46	13, // Pop
47	18, // Latin
48	11, // Rock & Indie
49	9,  // Hip-hop & Rap
50	20, // Funk & Disco
51	1,  // Electronica
52	5,  // House
53}
54
55// dayparts is the target index in mainFlow for each 3-hour block of the UTC
56// day: Jazz, Lo-fi, Folk, R&B, Pop, Rock, Funk & Disco, then House late at night.
57var dayparts = [8]int{1, 0, 2, 3, 5, 7, 9, 11}
58
59// hourGenre is the genre Main relays at ts: the daypart's target, one step
60// below it in the block's first hour, above it in the last, or the nearest
61// mainstream genre with a live track, else any genre with one (0: none).
62func hourGenre(t *tx, ts int64) int {
63	h := ts / 3600
64	if g := nearestLive(t, mainFlow, dayparts[h%24/3]+int(h%3)-1); g > 0 {
65		return g
66	}
67	return nearestLive(t, energy[:], 0)
68}
69
70// nearestLive is the genre of order nearest to index i with a live track, the
71// calmer one first on a tie (0: none).
72func nearestLive(t *tx, order []int, i int) int {
73	if i < 0 {
74		i = 0
75	} else if i >= len(order) {
76		i = len(order) - 1
77	}
78	for k := 0; k < 2*len(order); k++ {
79		if j := i + (k+1)/2*(1-2*(k%2)); j >= 0 && j < len(order) && t.hasLive(order[j]) {
80			return order[j]
81		}
82	}
83	return 0
84}
85
86// HourGenre is the genre Main relays at unix time at (0: none), for pages
87// that explain it.
88func HourGenre(at int64) int { return hourGenre(rd(), at) }