mirror of
https://github.com/make-42/xyosc
synced 2024-11-22 09:10:09 +01:00
init: init commit
This commit is contained in:
parent
2cb565cd8c
commit
adfc70db3b
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
xyosc
|
55
audio/audio.go
Normal file
55
audio/audio.go
Normal file
@ -0,0 +1,55 @@
|
||||
package audio
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"xyosc/config"
|
||||
"xyosc/utils"
|
||||
|
||||
"github.com/gen2brain/malgo"
|
||||
"github.com/smallnest/ringbuffer"
|
||||
)
|
||||
|
||||
var SampleRingBuffer *ringbuffer.RingBuffer
|
||||
var SampleSizeInBytes uint32
|
||||
|
||||
const format = malgo.FormatF32
|
||||
|
||||
func Init() {
|
||||
deviceConfig := malgo.DefaultDeviceConfig(malgo.Duplex)
|
||||
SampleRingBuffer = ringbuffer.New(int(config.Config.RingBufferSize))
|
||||
deviceConfig.Capture.Format = format
|
||||
SampleSizeInBytes = uint32(malgo.SampleSizeInBytes(deviceConfig.Capture.Format))
|
||||
}
|
||||
|
||||
func Start() {
|
||||
ctx, err := malgo.InitContext(nil, malgo.ContextConfig{}, func(message string) {
|
||||
fmt.Printf("LOG <%v>\n", message)
|
||||
})
|
||||
utils.CheckError(err)
|
||||
defer func() {
|
||||
_ = ctx.Uninit()
|
||||
ctx.Free()
|
||||
}()
|
||||
|
||||
deviceConfig := malgo.DefaultDeviceConfig(malgo.Duplex)
|
||||
deviceConfig.Capture.Format = format
|
||||
deviceConfig.Capture.Channels = 2
|
||||
deviceConfig.SampleRate = config.Config.SampleRate
|
||||
deviceConfig.Alsa.NoMMap = 1
|
||||
onRecvFrames := func(pSample2, pSample []byte, framecount uint32) {
|
||||
SampleRingBuffer.Write(pSample)
|
||||
}
|
||||
captureCallbacks := malgo.DeviceCallbacks{
|
||||
Data: onRecvFrames,
|
||||
}
|
||||
device, err := malgo.InitDevice(ctx.Context, deviceConfig, captureCallbacks)
|
||||
|
||||
utils.CheckError(err)
|
||||
|
||||
err = device.Start()
|
||||
|
||||
utils.CheckError(err)
|
||||
for {
|
||||
}
|
||||
//device.Uninit()
|
||||
}
|
114
config/config.go
Normal file
114
config/config.go
Normal file
@ -0,0 +1,114 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"image/color"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"xyosc/utils"
|
||||
|
||||
"github.com/kirsle/configdir"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
type ConfigS struct {
|
||||
FPSCounter bool
|
||||
TargetFPS int32
|
||||
WindowWidth int32
|
||||
WindowHeight int32
|
||||
SampleRate uint32
|
||||
RingBufferSize uint32
|
||||
ReadBufferSize uint32
|
||||
Gain float32
|
||||
LineOpacity uint8
|
||||
LineThickness float32
|
||||
}
|
||||
|
||||
var DefaultConfig = ConfigS{
|
||||
FPSCounter: false,
|
||||
TargetFPS: 60,
|
||||
WindowWidth: 800,
|
||||
WindowHeight: 800,
|
||||
SampleRate: 192000,
|
||||
RingBufferSize: 192000 * 4,
|
||||
ReadBufferSize: 192000,
|
||||
Gain: 1,
|
||||
LineOpacity: 50,
|
||||
LineThickness: 2,
|
||||
}
|
||||
|
||||
var Config ConfigS
|
||||
|
||||
var AccentColor color.RGBA
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
// Get pywal accent color
|
||||
walPath := configdir.LocalCache("wal")
|
||||
walFile := filepath.Join(walPath, "colors")
|
||||
if _, err = os.Stat(walFile); os.IsNotExist(err) {
|
||||
AccentColor = color.RGBA{255, 0, 0, Config.LineOpacity}
|
||||
} 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() {
|
||||
if line == 1 {
|
||||
rgbaColor, err = ParseHexColor(scanner.Text())
|
||||
utils.CheckError(err)
|
||||
break
|
||||
}
|
||||
line++
|
||||
}
|
||||
|
||||
AccentColor = color.RGBA{rgbaColor.R, rgbaColor.G, rgbaColor.B, Config.LineOpacity}
|
||||
}
|
||||
fmt.Println(AccentColor)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
17
go.mod
Normal file
17
go.mod
Normal file
@ -0,0 +1,17 @@
|
||||
module xyosc
|
||||
|
||||
go 1.23.2
|
||||
|
||||
require (
|
||||
github.com/gen2brain/malgo v0.11.22
|
||||
github.com/gen2brain/raylib-go/raylib v0.0.0-20241019150900-b7833eeae8d0
|
||||
github.com/kirsle/configdir v0.0.0-20170128060238-e45d2f54772f
|
||||
github.com/smallnest/ringbuffer v0.0.0-20240827114233-62e3c686e6c0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/ebitengine/purego v0.7.1 // indirect
|
||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
|
||||
golang.org/x/sys v0.20.0 // indirect
|
||||
)
|
18
go.sum
Normal file
18
go.sum
Normal file
@ -0,0 +1,18 @@
|
||||
github.com/ebitengine/purego v0.7.1 h1:6/55d26lG3o9VCZX8lping+bZcmShseiqlh2bnUDiPA=
|
||||
github.com/ebitengine/purego v0.7.1/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ=
|
||||
github.com/gen2brain/malgo v0.11.22 h1:fRtTbzVI9CDWnfEJGo/GxKxN7pXtCb0NsAeUVUjZk9U=
|
||||
github.com/gen2brain/malgo v0.11.22/go.mod h1:f9TtuN7DVrXMiV/yIceMeWpvanyVzJQMlBecJFVMxww=
|
||||
github.com/gen2brain/raylib-go/raylib v0.0.0-20241019150900-b7833eeae8d0 h1:ssHgKQvc9AIHFSlpkfHr89lJU8nzGBdpKoQJBTPkvnQ=
|
||||
github.com/gen2brain/raylib-go/raylib v0.0.0-20241019150900-b7833eeae8d0/go.mod h1:BaY76bZk7nw1/kVOSQObPY1v1iwVE1KHAGMfvI6oK1Q=
|
||||
github.com/kirsle/configdir v0.0.0-20170128060238-e45d2f54772f h1:dKccXx7xA56UNqOcFIbuqFjAWPVtP688j5QMgmo6OHU=
|
||||
github.com/kirsle/configdir v0.0.0-20170128060238-e45d2f54772f/go.mod h1:4rEELDSfUAlBSyUjPG0JnaNGjf13JySHFeRdD/3dLP0=
|
||||
github.com/smallnest/ringbuffer v0.0.0-20240827114233-62e3c686e6c0 h1:6wTlHUWggWb8Y5Q4f7xnIBHa3L7DgijNQP8eM6oTEhQ=
|
||||
github.com/smallnest/ringbuffer v0.0.0-20240827114233-62e3c686e6c0/go.mod h1:tAG61zBM1DYRaGIPloumExGvScf08oHuo0kFoOqdbT0=
|
||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
|
||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
|
||||
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
52
main.go
Normal file
52
main.go
Normal file
@ -0,0 +1,52 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"xyosc/audio"
|
||||
"xyosc/config"
|
||||
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
)
|
||||
|
||||
func main() {
|
||||
config.Init()
|
||||
audio.Init()
|
||||
go audio.Start()
|
||||
|
||||
scale := min(config.Config.WindowWidth, config.Config.WindowHeight) / 2
|
||||
rl.InitWindow(config.Config.WindowWidth, config.Config.WindowHeight, "xyosc")
|
||||
defer rl.CloseWindow()
|
||||
rl.SetWindowOpacity(0.0)
|
||||
rl.SetConfigFlags(rl.FlagWindowTransparent)
|
||||
rl.SetWindowState(rl.FlagWindowUndecorated)
|
||||
rl.SetTargetFPS(config.Config.TargetFPS)
|
||||
rl.SetWindowPosition(rl.GetMonitorWidth(rl.GetCurrentMonitor())/2, rl.GetMonitorHeight(rl.GetCurrentMonitor())/2)
|
||||
var AX float32
|
||||
var AY float32
|
||||
var BX float32
|
||||
var BY float32
|
||||
for !rl.WindowShouldClose() {
|
||||
rl.BeginDrawing()
|
||||
rl.ClearBackground(rl.Blank)
|
||||
|
||||
binary.Read(audio.SampleRingBuffer, binary.NativeEndian, &AX)
|
||||
binary.Read(audio.SampleRingBuffer, binary.NativeEndian, &AY)
|
||||
for i := uint32(0); i < config.Config.ReadBufferSize/audio.SampleSizeInBytes/2; i++ {
|
||||
binary.Read(audio.SampleRingBuffer, binary.NativeEndian, &BX)
|
||||
binary.Read(audio.SampleRingBuffer, binary.NativeEndian, &BY)
|
||||
fAX := float32(AX) * config.Config.Gain * float32(scale)
|
||||
fAY := -float32(AY) * config.Config.Gain * float32(scale)
|
||||
fBX := float32(BX) * config.Config.Gain * float32(scale)
|
||||
fBY := -float32(BY) * config.Config.Gain * float32(scale)
|
||||
rl.DrawLineEx(rl.NewVector2(float32(config.Config.WindowWidth/2)+fAX, float32(config.Config.WindowWidth/2)+fAY), rl.NewVector2(float32(config.Config.WindowWidth/2)+fBX, float32(config.Config.WindowWidth/2)+fBY), config.Config.LineThickness, config.AccentColor)
|
||||
AX = BX
|
||||
AY = BY
|
||||
}
|
||||
if config.Config.FPSCounter {
|
||||
rl.DrawFPS(0, 0)
|
||||
}
|
||||
rl.EndDrawing()
|
||||
}
|
||||
|
||||
rl.CloseWindow()
|
||||
}
|
9
utils/utils.go
Normal file
9
utils/utils.go
Normal file
@ -0,0 +1,9 @@
|
||||
package utils
|
||||
|
||||
import "log"
|
||||
|
||||
func CheckError(err error) {
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user