From 3057bde44c07f3358551e0d44a909a9960cedcea Mon Sep 17 00:00:00 2001 From: WeebDataHoarder <57538841+WeebDataHoarder@users.noreply.github.com> Date: Sun, 17 Apr 2022 20:18:02 +0200 Subject: [PATCH] Implement read callbacks for encoder --- callbacks.c | 12 ++++++++++++ libflac.go | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/callbacks.c b/callbacks.c index ed0b53f..8818635 100644 --- a/callbacks.c +++ b/callbacks.c @@ -42,6 +42,18 @@ decoderReadCallback_cgo(const FLAC__StreamDecoder *decoder, bytes, data); } + + +FLAC__StreamEncoderReadStatus +encoderReadCallback_cgo(const FLAC__StreamEncoder *encoder, + const FLAC__byte buffer[], + size_t *bytes, + void *data) +{ + return encoderReadCallback((FLAC__StreamEncoder *)encoder, + (FLAC__byte *)buffer, bytes, data); +} + FLAC__StreamEncoderWriteStatus encoderWriteCallback_cgo(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], diff --git a/libflac.go b/libflac.go index 5b7deb3..915d13d 100644 --- a/libflac.go +++ b/libflac.go @@ -45,6 +45,12 @@ decoderReadCallback_cgo(const FLAC__StreamDecoder *, size_t *, void *); +FLAC__StreamEncoderReadStatus +encoderReadCallback_cgo(const FLAC__StreamEncoder *encoder, + const FLAC__byte *, + size_t *, + void *); + FLAC__StreamEncoderWriteStatus encoderWriteCallback_cgo(const FLAC__StreamEncoder *, const FLAC__byte *, @@ -423,6 +429,29 @@ func NewEncoderOgg(name string, channels int, depth int, rate int) (e *Encoder, return } +//export encoderReadCallback +func encoderReadCallback(e *C.FLAC__StreamEncoder, buffer *C.FLAC__byte, bytes *C.size_t, data unsafe.Pointer) C.FLAC__StreamEncoderReadStatus { + encoder := encoderPtrs.get(e) + numBytes := int(*bytes) + if numBytes <= 0 { + return C.FLAC__STREAM_ENCODER_READ_STATUS_ABORT + } + hdr := reflect.SliceHeader{ + Data: uintptr(unsafe.Pointer(buffer)), + Len: numBytes, + Cap: numBytes, + } + buf := *(*[]byte)(unsafe.Pointer(&hdr)) + n, err := encoder.writeSeeker.(io.Reader).Read(buf) + *bytes = C.size_t(n) + if err == io.EOF && n == 0 { + return C.FLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM + } else if err != nil && err != io.EOF { + return C.FLAC__STREAM_ENCODER_READ_STATUS_ABORT + } + return C.FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE +} + //export encoderWriteCallback func encoderWriteCallback(e *C.FLAC__StreamEncoder, buffer *C.FLAC__byte, bytes C.size_t, samples, current_frame C.unsigned, data unsafe.Pointer) C.FLAC__StreamEncoderWriteStatus { encoder := encoderPtrs.get(e) @@ -514,6 +543,10 @@ func NewEncoderWriteSeeker(writer FlacWriter, channels int, depth int, rate int, // NewEncoderWriteSeekerOgg creates a new Encoder object from a FlacWriter. func NewEncoderWriteSeekerOgg(writer FlacWriter, channels int, depth int, rate int, compressionLevel int, streamable bool, blockSize int) (e *Encoder, err error) { + if _, ok := writer.(io.Reader); !ok { + return nil, errors.New("writer must also implement io.Reader") + } + if channels == 0 { return nil, errors.New("channels must be greater than 0") } @@ -541,6 +574,7 @@ func NewEncoderWriteSeekerOgg(writer FlacWriter, channels int, depth int, rate i C.FLAC__stream_encoder_set_streamable_subset(e.e, C.FLAC__bool(0)) } status := C.FLAC__stream_encoder_init_ogg_stream(e.e, + (C.FLAC__StreamEncoderReadCallback)(unsafe.Pointer(C.encoderReadCallback_cgo)), (C.FLAC__StreamEncoderWriteCallback)(unsafe.Pointer(C.encoderWriteCallback_cgo)), (C.FLAC__StreamEncoderSeekCallback)(unsafe.Pointer(C.encoderSeekCallback_cgo)), (C.FLAC__StreamEncoderTellCallback)(unsafe.Pointer(C.encoderTellCallback_cgo)), @@ -621,6 +655,7 @@ func NewEncoderWriterOgg(writer io.WriteCloser, channels int, depth int, rate in C.FLAC__stream_encoder_set_streamable_subset(e.e, C.FLAC__bool(0)) } status := C.FLAC__stream_encoder_init_ogg_stream(e.e, + nil, (C.FLAC__StreamEncoderWriteCallback)(unsafe.Pointer(C.encoderWriteCallback_cgo)), nil, nil,