flow.gno
1.97 Kb · 61 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 the genres from calm to intense; neighbours blend well.
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// dayparts is the target index in energy for each 3-hour block of the UTC day:
37// Jazz, Ambient, Lo-fi, World, Pop, Rock, House, then Drum & Bass at the peak.
38var dayparts = [8]int{3, 0, 4, 7, 10, 12, 15, 18}
39
40// hourGenre is the genre Main relays at ts: the daypart's target, one step
41// below it in the block's first hour, above it in the last, or the nearest
42// genre with a live track (0: none).
43func hourGenre(t *tx, ts int64) int {
44 h := ts / 3600
45 i := dayparts[h%24/3] + int(h%3) - 1
46 if i < 0 {
47 i = 0
48 } else if i >= len(energy) {
49 i = len(energy) - 1
50 }
51 for k := 0; k < 2*len(energy); k++ {
52 if j := i + (k+1)/2*(1-2*(k%2)); j >= 0 && j < len(energy) && t.hasLive(energy[j]) {
53 return energy[j]
54 }
55 }
56 return 0
57}
58
59// HourGenre is the genre Main relays at unix time at (0: none), for pages
60// that explain it.
61func HourGenre(at int64) int { return hourGenre(rd(), at) }