mirror of
https://github.com/make-42/xyosc
synced 2024-11-22 17:20: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