diff options
author | xegineering <me@xegineering.eu> | 2024-12-11 20:03:29 +0100 |
---|---|---|
committer | xegineering <me@xegineering.eu> | 2024-12-15 12:36:51 +0100 |
commit | ca5ebc8a795114a72f4410f05b2270f24ead1d60 (patch) | |
tree | 5ca901ebc8365909e4fd2ec11a4cf1ff114f149d /soundbox/pipewire.go | |
parent | 62d3045df3283872628b0b8b8a8caeef1c226dfa (diff) | |
download | soundbox-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.go | 52 |
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 } |