summaryrefslogtreecommitdiff
path: root/soundbox/pipewire.go
diff options
context:
space:
mode:
authorxegineering <me@xegineering.eu>2024-12-11 20:03:29 +0100
committerxegineering <me@xegineering.eu>2024-12-15 12:36:51 +0100
commitca5ebc8a795114a72f4410f05b2270f24ead1d60 (patch)
tree5ca901ebc8365909e4fd2ec11a4cf1ff114f149d /soundbox/pipewire.go
parent62d3045df3283872628b0b8b8a8caeef1c226dfa (diff)
downloadsoundbox-go-ca5ebc8a795114a72f4410f05b2270f24ead1d60.tar
soundbox-go-ca5ebc8a795114a72f4410f05b2270f24ead1d60.tar.zst
soundbox-go-ca5ebc8a795114a72f4410f05b2270f24ead1d60.zip
pipewire: Implement capture tear-down
This closes the PipeWire process properly to not leak memory and remove the PipeWire capture node of soundbox as soon as the context passed to StreamPipewireContext() is closed.
Diffstat (limited to 'soundbox/pipewire.go')
-rw-r--r--soundbox/pipewire.go52
1 files changed, 40 insertions, 12 deletions
diff --git a/soundbox/pipewire.go b/soundbox/pipewire.go
index 00bbe49..476d2e4 100644
--- a/soundbox/pipewire.go
+++ b/soundbox/pipewire.go
@@ -7,7 +7,6 @@ package soundbox
import "C"
import (
- "bytes"
"context"
"io"
"log"
@@ -16,7 +15,41 @@ import (
"unsafe"
)
-var pipewireAudio = make(chan []byte, 5)
+type pwCapture struct {
+ cdata unsafe.Pointer
+}
+
+var pwAudio chan []byte
+
+func newPWCapture(ctx context.Context) pwCapture {
+ pwc := pwCapture{}
+
+ pwAudio = make(chan []byte, 5)
+ pwc.cdata = unsafe.Pointer(C.pw_go_capture_init()) // TODO pass &pwc.audio here
+ go C.pw_go_capture_run(pwc.cdata)
+
+ go func() {
+ <-ctx.Done()
+ C.pw_go_capture_deinit(pwc.cdata)
+ }()
+
+ return pwc
+}
+
+func (pwc pwCapture) Read(p []byte) (int, error) {
+ select {
+ case chunk, ok := <-pwAudio:
+ if ok {
+ noSilence := s16leDropSilence(chunk)
+ i := copy(p, noSilence)
+ return i, nil
+ } else {
+ return 0, io.EOF
+ }
+ default:
+ return 0, nil
+ }
+}
func s16leDropSilence(input []byte) []byte {
output := make([]byte, 0)
@@ -61,16 +94,11 @@ func StreamPipewireContext(ctx context.Context, targets []net.HardwareAddr) erro
return err
}
- go C.pw_stdout()
-
+ pwc := newPWCapture(ctx)
go func() {
- for buffer := range pipewireAudio {
- tempReader := bytes.NewReader(s16leDropSilence(buffer))
- _, err := io.Copy(stdin, tempReader)
- if err != nil {
- log.Println("Failed to copy from PipeWire to ffmpeg.")
- break
- }
+ _, err := io.Copy(stdin, pwc)
+ if err != nil {
+ log.Println("Failed to copy from PipeWire to ffmpeg.")
}
}()
@@ -90,5 +118,5 @@ func StreamPipewireContext(ctx context.Context, targets []net.HardwareAddr) erro
//export goHandleData
func goHandleData(data *C.int16_t, size C.size_t) {
buf := C.GoBytes(unsafe.Pointer(data), C.int(size))
- pipewireAudio <- buf
+ pwAudio <- buf
}