commit
1882546c4a
@ -0,0 +1,3 @@
|
|||||||
|
/locbackup
|
||||||
|
/numberstation
|
||||||
|
|
@ -0,0 +1,16 @@
|
|||||||
|
module numberstation
|
||||||
|
|
||||||
|
go 1.22.6
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/chzyer/readline v1.5.1
|
||||||
|
github.com/gopxl/beep v1.4.1
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/ebitengine/oto/v3 v3.2.0 // indirect
|
||||||
|
github.com/ebitengine/purego v0.7.1 // indirect
|
||||||
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
|
github.com/stretchr/testify v1.9.0 // indirect
|
||||||
|
golang.org/x/sys v0.24.0 // indirect
|
||||||
|
)
|
@ -0,0 +1,27 @@
|
|||||||
|
github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM=
|
||||||
|
github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ=
|
||||||
|
github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI=
|
||||||
|
github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk=
|
||||||
|
github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04=
|
||||||
|
github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/ebitengine/oto/v3 v3.2.0 h1:FuggTJTSI3/3hEYwZEIN0CZVXYT29ZOdCu+z/f4QjTw=
|
||||||
|
github.com/ebitengine/oto/v3 v3.2.0/go.mod h1:dOKXShvy1EQbIXhXPFcKLargdnFqH0RjptecvyAxhyw=
|
||||||
|
github.com/ebitengine/purego v0.7.1 h1:6/55d26lG3o9VCZX8lping+bZcmShseiqlh2bnUDiPA=
|
||||||
|
github.com/ebitengine/purego v0.7.1/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ=
|
||||||
|
github.com/gopxl/beep v1.4.1 h1:WqNs9RsDAhG9M3khMyc1FaVY50dTdxG/6S6a3qsUHqE=
|
||||||
|
github.com/gopxl/beep v1.4.1/go.mod h1:A1dmiUkuY8kxsvcNJNUBIEcchmiP6eUyCHSxpXl0YO0=
|
||||||
|
github.com/orcaman/writerseeker v0.0.0-20200621085525-1d3f536ff85e h1:s2RNOM/IGdY0Y6qfTeUKhDawdHDpK9RGBdx80qN4Ttw=
|
||||||
|
github.com/orcaman/writerseeker v0.0.0-20200621085525-1d3f536ff85e/go.mod h1:nBdnFKj15wFbf94Rwfq4m30eAcyY9V/IyKAGQFtqkW0=
|
||||||
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
|
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
|
||||||
|
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
@ -0,0 +1,117 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"embed"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/chzyer/readline"
|
||||||
|
"github.com/gopxl/beep"
|
||||||
|
"github.com/gopxl/beep/speaker"
|
||||||
|
"github.com/gopxl/beep/wav"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed sound/*
|
||||||
|
var soundFS embed.FS
|
||||||
|
|
||||||
|
const (
|
||||||
|
pauseBetweenCharacters = 500 * time.Millisecond
|
||||||
|
longPause = 1600 * time.Millisecond
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Create a map to store sound data for each character
|
||||||
|
soundMap := make(map[rune][]byte)
|
||||||
|
|
||||||
|
// Load all sound files into the map
|
||||||
|
for _, c := range "abcdefghijklmnopqrstuvwxyz0123456789" {
|
||||||
|
filename := fmt.Sprintf("sound/sam%c.wav", c)
|
||||||
|
data, err := soundFS.ReadFile(filename)
|
||||||
|
if err == nil {
|
||||||
|
soundMap[c] = data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure readline settings
|
||||||
|
rl, err := readline.NewEx(&readline.Config{
|
||||||
|
Prompt: "> ", // Use a simple prompt for each line input
|
||||||
|
InterruptPrompt: "^C",
|
||||||
|
EOFPrompt: "exit",
|
||||||
|
FuncFilterInputRune: uppercaseFilter, // Filter to show uppercase
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error initializing readline: %s\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer rl.Close()
|
||||||
|
|
||||||
|
// Inform the user about how to enter input
|
||||||
|
fmt.Println("Enter lines of text (press Enter on a blank line to finish):")
|
||||||
|
|
||||||
|
var inputBuilder strings.Builder
|
||||||
|
for {
|
||||||
|
line, err := rl.Readline()
|
||||||
|
if err != nil {
|
||||||
|
if err.Error() == "EOF" {
|
||||||
|
fmt.Println("Exiting.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Printf("Error reading input: %s\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the user entered a blank line to finish input
|
||||||
|
if strings.TrimSpace(line) == "" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append the line to the input builder
|
||||||
|
inputBuilder.WriteString(line + "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the complete input as a string
|
||||||
|
input := inputBuilder.String()
|
||||||
|
input = strings.ToLower(strings.TrimSpace(input))
|
||||||
|
|
||||||
|
for _, c := range input {
|
||||||
|
if c == '-' || c == '_' || c == ' ' || c == '\n' {
|
||||||
|
time.Sleep(longPause)
|
||||||
|
} else {
|
||||||
|
if soundData, ok := soundMap[c]; ok {
|
||||||
|
playSound(soundData)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("No sound file found for character: %c\n", c)
|
||||||
|
}
|
||||||
|
time.Sleep(pauseBetweenCharacters)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to play sound
|
||||||
|
func playSound(soundData []byte) {
|
||||||
|
streamer, format, err := wav.Decode(bytes.NewReader(soundData))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Could not decode sound data: %s\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer streamer.Close()
|
||||||
|
|
||||||
|
speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
|
||||||
|
done := make(chan bool)
|
||||||
|
speaker.Play(beep.Seq(streamer, beep.Callback(func() {
|
||||||
|
done <- true
|
||||||
|
})))
|
||||||
|
|
||||||
|
<-done
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter function to convert all typed input to uppercase for display
|
||||||
|
func uppercaseFilter(r rune) (rune, bool) {
|
||||||
|
if r >= 'a' && r <= 'z' {
|
||||||
|
return r - ('a' - 'A'), true // Convert to uppercase
|
||||||
|
}
|
||||||
|
return r, true // Keep other characters unchanged
|
||||||
|
}
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in new issue