158 lines
3.6 KiB
C
158 lines
3.6 KiB
C
//go:build !nolibopusfile
|
|
// +build !nolibopusfile
|
|
|
|
// Copyright © Go Opus Authors (see AUTHORS file)
|
|
//
|
|
// License for use of this code is detailed in the LICENSE file
|
|
|
|
// Allocate callback struct in C to ensure it's not managed by the Go GC. This
|
|
// plays nice with the CGo rules and avoids any confusion.
|
|
|
|
#include <opusfile.h>
|
|
#include <opusenc.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
|
|
// Defined in Go. Uses the same signature as Go, no need for proxy function.
|
|
int go_readcallback(void *p, unsigned char *buf, int nbytes);
|
|
int go_writecallback(void *p, const unsigned char *buf, opus_int32 len);
|
|
|
|
int closecallback(void *p) {
|
|
return 0;
|
|
}
|
|
|
|
static struct OpusFileCallbacks callbacks = {
|
|
.read = go_readcallback,
|
|
};
|
|
|
|
static OpusEncCallbacks encodeCallbacks = {
|
|
.write = go_writecallback,
|
|
.close = closecallback,
|
|
};
|
|
|
|
static OggOpusComments* emptyComment = NULL;
|
|
|
|
// Proxy function for op_open_callbacks, because it takes a void * context but
|
|
// we want to pass it non-pointer data, namely an arbitrary uintptr_t
|
|
// value. This is legal C, but go test -race (-d=checkptr) complains anyway. So
|
|
// we have this wrapper function to shush it.
|
|
// https://groups.google.com/g/golang-nuts/c/995uZyRPKlU
|
|
OggOpusFile *
|
|
my_open_callbacks(uintptr_t p, int *error)
|
|
{
|
|
return op_open_callbacks((void *)p, &callbacks, NULL, 0, error);
|
|
}
|
|
|
|
OpusEncCallbacks *
|
|
my_write_callbacks()
|
|
{
|
|
return &encodeCallbacks;
|
|
}
|
|
|
|
OggOpusComments*
|
|
my_empty_comment()
|
|
{
|
|
if (emptyComment == NULL) {
|
|
emptyComment = ope_comments_create();
|
|
}
|
|
return emptyComment;
|
|
}
|
|
|
|
|
|
|
|
int
|
|
bridge_encoder_set_dtx(OggOpusEnc *st, opus_int32 use_dtx)
|
|
{
|
|
return ope_encoder_ctl(st, OPUS_SET_DTX(use_dtx));
|
|
}
|
|
|
|
int
|
|
bridge_encoder_set_application(OggOpusEnc *st, opus_int32 application)
|
|
{
|
|
return ope_encoder_ctl(st, OPUS_SET_APPLICATION(application));
|
|
}
|
|
|
|
int
|
|
bridge_encoder_get_dtx(OggOpusEnc *st, opus_int32 *dtx)
|
|
{
|
|
return ope_encoder_ctl(st, OPUS_GET_DTX(dtx));
|
|
}
|
|
|
|
int
|
|
bridge_encoder_get_sample_rate(OggOpusEnc *st, opus_int32 *sample_rate)
|
|
{
|
|
return ope_encoder_ctl(st, OPUS_GET_SAMPLE_RATE(sample_rate));
|
|
}
|
|
|
|
|
|
int
|
|
bridge_encoder_set_muxing_delay(OggOpusEnc *st, opus_int32 delay)
|
|
{
|
|
return ope_encoder_ctl(st, OPE_SET_MUXING_DELAY(delay));
|
|
}
|
|
|
|
int
|
|
bridge_encoder_get_muxing_delay(OggOpusEnc *st, opus_int32 *delay)
|
|
{
|
|
return ope_encoder_ctl(st, OPE_GET_MUXING_DELAY(delay));
|
|
}
|
|
|
|
int
|
|
bridge_encoder_set_bitrate(OggOpusEnc *st, opus_int32 bitrate)
|
|
{
|
|
return ope_encoder_ctl(st, OPUS_SET_BITRATE(bitrate));
|
|
}
|
|
|
|
int
|
|
bridge_encoder_get_bitrate(OggOpusEnc *st, opus_int32 *bitrate)
|
|
{
|
|
return ope_encoder_ctl(st, OPUS_GET_BITRATE(bitrate));
|
|
}
|
|
|
|
int
|
|
bridge_encoder_set_complexity(OggOpusEnc *st, opus_int32 complexity)
|
|
{
|
|
return ope_encoder_ctl(st, OPUS_SET_COMPLEXITY(complexity));
|
|
}
|
|
|
|
int
|
|
bridge_encoder_get_complexity(OggOpusEnc *st, opus_int32 *complexity)
|
|
{
|
|
return ope_encoder_ctl(st, OPUS_GET_COMPLEXITY(complexity));
|
|
}
|
|
|
|
int
|
|
bridge_encoder_set_max_bandwidth(OggOpusEnc *st, opus_int32 max_bw)
|
|
{
|
|
return ope_encoder_ctl(st, OPUS_SET_MAX_BANDWIDTH(max_bw));
|
|
}
|
|
|
|
int
|
|
bridge_encoder_get_max_bandwidth(OggOpusEnc *st, opus_int32 *max_bw)
|
|
{
|
|
return ope_encoder_ctl(st, OPUS_GET_MAX_BANDWIDTH(max_bw));
|
|
}
|
|
|
|
int
|
|
bridge_encoder_set_inband_fec(OggOpusEnc *st, opus_int32 fec)
|
|
{
|
|
return ope_encoder_ctl(st, OPUS_SET_INBAND_FEC(fec));
|
|
}
|
|
|
|
int
|
|
bridge_encoder_get_inband_fec(OggOpusEnc *st, opus_int32 *fec)
|
|
{
|
|
return ope_encoder_ctl(st, OPUS_GET_INBAND_FEC(fec));
|
|
}
|
|
|
|
int
|
|
bridge_encoder_set_packet_loss_perc(OggOpusEnc *st, opus_int32 loss_perc)
|
|
{
|
|
return ope_encoder_ctl(st, OPUS_SET_PACKET_LOSS_PERC(loss_perc));
|
|
}
|
|
|
|
int
|
|
bridge_encoder_get_packet_loss_perc(OggOpusEnc *st, opus_int32 *loss_perc)
|
|
{
|
|
return ope_encoder_ctl(st, OPUS_GET_PACKET_LOSS_PERC(loss_perc));
|
|
} |