soundboard.go (3192B)
1 package main 2 3 import ( 4 "fmt" 5 "encoding/csv" 6 "github.com/gdamore/tcell/v2" 7 "os" 8 "os/exec" 9 ) 10 11 var styles = map[string]tcell.Style{} 12 var termHeight int 13 var termWidth int 14 15 var homeDir string 16 17 type sound struct { 18 name string 19 path string 20 key rune 21 } 22 23 var sounds []sound 24 25 var cmds []*exec.Cmd 26 27 /* 28 soundboard.csv: 29 `v,Vine boom,wav/vineboom.wav` 30 `<key>,<name>,<filename>` 31 */ 32 33 const CONFIG_FILE=".config/regexghost/soundboard.csv" 34 const SOUND_LOC=".local/share/regexghost/sounds" 35 36 // Function to allow adding strings to screen instead of just individual runes (chars) 37 func drawText(s tcell.Screen, x1, y1, x2, y2 int, style tcell.Style, text string) { 38 row := y1 39 col := x1 40 for _, r := range []rune(text) { 41 s.SetContent(col, row, r, nil, style) 42 col++ 43 if col >= x2 { 44 row++ 45 col = x1 46 } 47 if row > y2 { 48 break 49 } 50 } 51 } 52 53 func errorOut(e string) { 54 fmt.Println(e) 55 os.Exit(1) 56 } 57 58 func loadSounds() { 59 file, err := os.Open(homeDir + "/" + CONFIG_FILE) 60 61 if err != nil { 62 errorOut("Error, config file not present") 63 } 64 65 defer file.Close() 66 67 reader := csv.NewReader(file) 68 records, err := reader.ReadAll() 69 70 if err != nil { 71 errorOut("Error parsing csv file") 72 } 73 74 for _, record := range records { 75 key := rune(record[0][0]) 76 newSound := sound { 77 name: record[1], 78 path: record[2], 79 key: key, 80 } 81 sounds = append(sounds, newSound) 82 fmt.Println(newSound) 83 } 84 } 85 86 func drawSoundboard(s tcell.Screen) { 87 s.Clear() 88 drawText(s, 0, 0, 50, 10, styles["pink"], "Soundboard") 89 for i, soundEntry := range sounds { 90 line := string(soundEntry.key) + ": " + soundEntry.name 91 drawText(s, 0, i+2, 50, 100, styles["blue"], line) 92 } 93 } 94 95 func playSound(path string) { 96 // cmd := exec.Command("mpv", "--no-config", "--no-resume-playback", "--force-window=no", homeDir + "/" + SOUND_LOC + "/" + path) 97 cmd := exec.Command("aplay", homeDir + "/" + SOUND_LOC + "/" + path) 98 cmds = append(cmds, cmd) 99 cmd.Start() 100 } 101 102 func killSounds() { 103 for _, cmd := range cmds { 104 cmd.Process.Kill() 105 } 106 } 107 108 func findAndPlaySound(key rune) { 109 for _, soundEntry := range sounds { 110 if soundEntry.key == key { 111 playSound(soundEntry.path) 112 } 113 } 114 } 115 116 func main() { 117 homeDir, _ = os.UserHomeDir() 118 119 loadSounds() 120 121 s, err := tcell.NewScreen() 122 if err != nil { 123 panic(err) 124 } 125 err = s.Init() 126 if err != nil { 127 panic(err) 128 } 129 130 // Create colours 131 blueColour := tcell.NewHexColor(0x38ffea) 132 pinkColour := tcell.NewHexColor(0xff76c1) 133 134 // Use the colours to make styles and add to "styles" map 135 styles["white"] = tcell.StyleDefault.Background(tcell.ColorReset).Foreground(tcell.ColorReset) 136 styles["blue"] = tcell.StyleDefault.Background(tcell.ColorReset).Foreground(blueColour) 137 styles["pink"] = tcell.StyleDefault.Background(tcell.ColorReset).Foreground(pinkColour) 138 139 s.SetStyle(styles["white"]) 140 s.Clear() 141 142 quit := func() { 143 s.Fini() 144 os.Exit(0) 145 } 146 147 for { 148 s.Show() 149 150 drawSoundboard(s) 151 ev := s.PollEvent() 152 153 switch ev := ev.(type) { 154 case *tcell.EventResize: 155 s.Sync() 156 case *tcell.EventKey: 157 if ev.Key() == tcell.KeyRune { 158 if ev.Rune() == 'q' { 159 killSounds() 160 quit() 161 } else if ev.Rune() == ' ' { 162 killSounds() 163 } else { 164 findAndPlaySound(ev.Rune()) 165 } 166 } 167 } 168 } 169 }