xyosc/config/config.go

225 lines
6.7 KiB
Go
Raw Normal View History

2024-10-20 22:58:09 +02:00
package config
import (
"bufio"
"fmt"
"image/color"
"os"
"path/filepath"
"xyosc/utils"
2024-11-02 17:50:15 +01:00
"github.com/fsnotify/fsnotify"
2024-10-20 22:58:09 +02:00
"github.com/kirsle/configdir"
"gopkg.in/yaml.v2"
)
type ConfigS struct {
2024-11-03 14:48:53 +01:00
FPSCounter bool
ShowMPRIS bool
MPRISTextOpacity uint8
TargetFPS int32
WindowWidth int32
WindowHeight int32
CaptureDeviceIndex int
SampleRate uint32
RingBufferSize uint32
ReadBufferSize uint32
Gain float32
LineOpacity uint8
LineBrightness float64
LineThickness float32
LineInvSqrtOpacityControl bool
Particles bool
ParticleGenPerFrameEveryXSamples int
ParticleMaxCount int
ParticleMinSize float32
ParticleMaxSize float32
ParticleAcceleration float32
2024-11-19 22:41:47 +01:00
ParticleDrag float32
2025-01-16 21:52:14 +01:00
DefaultToSingleChannel bool
2025-01-16 22:58:28 +01:00
PeakDetectSeparator int
2025-01-16 23:12:14 +01:00
SingleChannelWindow uint32
2025-01-17 14:45:54 +01:00
PeriodCrop bool
PeriodCropCount int
PeriodCropLoopOverCount uint32
2025-01-17 15:01:51 +01:00
FFTBufferOffset uint32
2025-01-19 00:07:42 +01:00
ForceColors bool
2025-01-19 00:26:53 +01:00
AccentColor string
FirstColor string
ThirdColor string
2024-10-20 22:58:09 +02:00
}
var DefaultConfig = ConfigS{
2024-11-03 14:48:53 +01:00
FPSCounter: false,
ShowMPRIS: true,
MPRISTextOpacity: 255,
TargetFPS: 240,
WindowWidth: 1300,
WindowHeight: 1300,
CaptureDeviceIndex: 0,
SampleRate: 96000,
RingBufferSize: 9600,
ReadBufferSize: 9600,
Gain: 1,
LineOpacity: 200,
LineBrightness: 1,
LineThickness: 3,
LineInvSqrtOpacityControl: false,
Particles: true,
2024-11-19 22:41:47 +01:00
ParticleGenPerFrameEveryXSamples: 2000,
ParticleMaxCount: 600,
2024-11-03 14:48:53 +01:00
ParticleMinSize: 0.2,
ParticleMaxSize: 2.0,
2024-11-19 22:41:47 +01:00
ParticleAcceleration: 0.015,
ParticleDrag: 5.0,
2025-01-16 21:52:14 +01:00
DefaultToSingleChannel: false,
2025-01-16 23:07:49 +01:00
PeakDetectSeparator: 100,
2025-01-16 23:16:25 +01:00
SingleChannelWindow: 1200,
2025-01-17 14:45:54 +01:00
PeriodCrop: true,
PeriodCropCount: 2,
PeriodCropLoopOverCount: 1,
2025-01-17 15:01:51 +01:00
FFTBufferOffset: 3200,
2025-01-19 00:07:42 +01:00
ForceColors: false,
2025-01-19 00:26:53 +01:00
AccentColor: "FF0000",
FirstColor: "FF0000",
ThirdColor: "FF0000",
2024-10-20 22:58:09 +02:00
}
var Config ConfigS
var AccentColor color.RGBA
2024-10-21 00:44:44 +02:00
var FirstColor color.RGBA
var ThirdColor color.RGBA
2024-11-02 23:58:30 +01:00
var ThirdColorAdj color.RGBA
2024-10-20 22:58:09 +02:00
2024-11-02 17:50:15 +01:00
var watcher *fsnotify.Watcher
2025-01-16 21:25:11 +01:00
var SingleChannel bool = false
2025-01-16 22:19:56 +01:00
var HannWindow []float64
2024-10-20 22:58:09 +02:00
func Init() {
configPath := configdir.LocalConfig("ontake", "xyosc")
err := configdir.MakePath(configPath) // Ensure it exists.
utils.CheckError(err)
configFile := filepath.Join(configPath, "config.yml")
// Does the file not exist?
if _, err = os.Stat(configFile); os.IsNotExist(err) {
// Create the new config file.
fh, err := os.Create(configFile)
utils.CheckError(err)
defer fh.Close()
encoder := yaml.NewEncoder(fh)
encoder.Encode(&DefaultConfig)
Config = DefaultConfig
} else {
// Load the existing file.
fh, err := os.Open(configFile)
utils.CheckError(err)
defer fh.Close()
decoder := yaml.NewDecoder(fh)
decoder.Decode(&Config)
2025-01-16 22:19:56 +01:00
2024-10-20 22:58:09 +02:00
}
2025-01-16 22:19:56 +01:00
SingleChannel = Config.DefaultToSingleChannel
2024-10-20 22:58:09 +02:00
// Get pywal accent color
2024-11-02 17:50:15 +01:00
watcher, err = fsnotify.NewWatcher()
utils.CheckError(err)
updatePywalColors()
walPath := configdir.LocalCache("wal")
walFile := filepath.Join(walPath, "colors")
// Start listening for events.
go func() {
for {
select {
case event, ok := <-watcher.Events:
if !ok {
return
}
if event.Has(fsnotify.Write) {
updatePywalColors()
}
case err, ok := <-watcher.Errors:
if !ok {
return
}
utils.CheckError(err)
}
}
}()
if _, err := os.Stat(walFile); os.IsNotExist(err) {
} else {
err = watcher.Add(walFile)
utils.CheckError(err)
}
}
func updatePywalColors() {
2024-10-20 22:58:09 +02:00
walPath := configdir.LocalCache("wal")
walFile := filepath.Join(walPath, "colors")
2025-01-19 00:15:11 +01:00
if _, err := os.Stat(walFile); os.IsNotExist(err) || Config.ForceColors {
2025-01-19 00:26:53 +01:00
AccentColorParsed, err := ParseHexColor(Config.AccentColor)
utils.CheckError(err)
FirstColorParsed, err := ParseHexColor(Config.FirstColor)
utils.CheckError(err)
ThirdColorParsed, err := ParseHexColor(Config.ThirdColor)
utils.CheckError(err)
AccentColor = color.RGBA{AccentColorParsed.R, AccentColorParsed.G, AccentColorParsed.B, Config.LineOpacity}
FirstColor = color.RGBA{FirstColorParsed.R, FirstColorParsed.G, FirstColorParsed.B, Config.LineOpacity}
ThirdColor = color.RGBA{ThirdColorParsed.R, ThirdColorParsed.G, ThirdColorParsed.B, Config.LineOpacity}
ThirdColorAdj = color.RGBA{uint8(float64(ThirdColorParsed.R) * Config.LineBrightness), uint8(float64(ThirdColorParsed.G) * Config.LineBrightness), uint8(float64(ThirdColorParsed.B) * Config.LineBrightness), Config.LineOpacity}
2024-10-20 22:58:09 +02:00
} else {
fh, err := os.Open(walFile)
utils.CheckError(err)
defer fh.Close()
scanner := bufio.NewScanner(fh)
var line int
var rgbaColor color.RGBA
for scanner.Scan() {
2024-10-21 00:44:44 +02:00
if line == 0 {
rgbaColor, err = ParseHexColor(scanner.Text())
utils.CheckError(err)
FirstColor = color.RGBA{rgbaColor.R, rgbaColor.G, rgbaColor.B, Config.LineOpacity}
}
2024-10-20 22:58:09 +02:00
if line == 1 {
rgbaColor, err = ParseHexColor(scanner.Text())
utils.CheckError(err)
2024-10-21 00:44:44 +02:00
AccentColor = color.RGBA{rgbaColor.R, rgbaColor.G, rgbaColor.B, Config.LineOpacity}
}
if line == 2 {
rgbaColor, err = ParseHexColor(scanner.Text())
utils.CheckError(err)
ThirdColor = color.RGBA{rgbaColor.R, rgbaColor.G, rgbaColor.B, Config.LineOpacity}
2024-11-02 23:58:30 +01:00
ThirdColorAdj = color.RGBA{uint8(float64(rgbaColor.R) * Config.LineBrightness), uint8(float64(rgbaColor.G) * Config.LineBrightness), uint8(float64(rgbaColor.B) * Config.LineBrightness), Config.LineOpacity}
2024-10-20 22:58:09 +02:00
break
}
line++
}
}
}
func ParseHexColor(s string) (c color.RGBA, err error) {
c.A = 0xff
switch len(s) {
case 7:
_, err = fmt.Sscanf(s, "#%02x%02x%02x", &c.R, &c.G, &c.B)
case 4:
_, err = fmt.Sscanf(s, "#%1x%1x%1x", &c.R, &c.G, &c.B)
// Double the hex digits:
c.R *= 17
c.G *= 17
c.B *= 17
default:
err = fmt.Errorf("invalid length, must be 7 or 4")
}
return
}