From 008490cba00f47fbeb8d2d6d636112c6de399d76 Mon Sep 17 00:00:00 2001 From: dh1tw Date: Fri, 30 Dec 2016 18:55:25 +0100 Subject: [PATCH] reverted to using types for enums; added SetBitrateMax and SetBitrateAuto --- encoder.go | 57 +++++++++++++++++++++++++--------- encoder_test.go | 82 ++++++++++++++++++++++++++++++++++++++++++++++--- opus.go | 10 +++--- 3 files changed, 125 insertions(+), 24 deletions(-) diff --git a/encoder.go b/encoder.go index 3e07930..81a24ac 100644 --- a/encoder.go +++ b/encoder.go @@ -84,24 +84,32 @@ bridge_encoder_get_max_bandwidth(OpusEncoder *st, opus_int32 *max_bw) return res; } +// Access the preprocessor from CGO +const int CONST_BANDWIDTH_NARROWBAND = OPUS_BANDWIDTH_NARROWBAND; +const int CONST_BANDWIDTH_MEDIUMBAND = OPUS_BANDWIDTH_MEDIUMBAND; +const int CONST_BANDWIDTH_WIDEBAND = OPUS_BANDWIDTH_WIDEBAND; +const int CONST_BANDWIDTH_SUPERWIDEBAND = OPUS_BANDWIDTH_SUPERWIDEBAND; +const int CONST_BANDWIDTH_FULLBAND = OPUS_BANDWIDTH_FULLBAND; + +const int CONST_BITRATE_AUTO = OPUS_AUTO; +const int CONST_BITRATE_MAX = OPUS_BITRATE_MAX; + */ import "C" -const ( - // Auto bitrate - Auto = C.OPUS_AUTO - // Maximum bitrate - BitrateMax = C.OPUS_BITRATE_MAX +type Bandwidth int + +var ( //4 kHz passband - BandwidthNarrowband = C.OPUS_BANDWIDTH_NARROWBAND + Narrowband = Bandwidth(C.OPUS_BANDWIDTH_NARROWBAND) // 6 kHz passband - BandwidthMediumBand = C.OPUS_BANDWIDTH_MEDIUMBAND + MediumBand = Bandwidth(C.OPUS_BANDWIDTH_MEDIUMBAND) // 8 kHz passband - BandwidthWideBand = C.OPUS_BANDWIDTH_WIDEBAND + WideBand = Bandwidth(C.OPUS_BANDWIDTH_WIDEBAND) // 12 kHz passband - BandwidthSuperWideBand = C.OPUS_BANDWIDTH_SUPERWIDEBAND + SuperWideBand = Bandwidth(C.OPUS_BANDWIDTH_SUPERWIDEBAND) // 20 kHz passband - BandwidthFullband = C.OPUS_BANDWIDTH_FULLBAND + Fullband = Bandwidth(C.OPUS_BANDWIDTH_FULLBAND) ) var errEncUninitialized = fmt.Errorf("opus encoder uninitialized") @@ -117,7 +125,7 @@ type Encoder struct { // NewEncoder allocates a new Opus encoder and initializes it with the // appropriate parameters. All related memory is managed by the Go GC. -func NewEncoder(sample_rate int, channels int, application int) (*Encoder, error) { +func NewEncoder(sample_rate int, channels int, application Application) (*Encoder, error) { var enc Encoder err := enc.Init(sample_rate, channels, application) if err != nil { @@ -129,7 +137,7 @@ func NewEncoder(sample_rate int, channels int, application int) (*Encoder, error // Init initializes a pre-allocated opus encoder. Unless the encoder has been // created using NewEncoder, this method must be called exactly once in the // life-time of this object, before calling any other methods. -func (enc *Encoder) Init(sample_rate int, channels int, application int) error { +func (enc *Encoder) Init(sample_rate int, channels int, application Application) error { if enc.p != nil { return fmt.Errorf("opus encoder already initialized") } @@ -239,6 +247,25 @@ func (enc *Encoder) SetBitrate(bitrate int) error { return nil } +// SetBitrateAuto will allow the encoder to automatically set the bitrate +func (enc *Encoder) SetBitrateAuto() error { + res := C.bridge_encoder_set_bitrate(enc.p, C.opus_int32(C.CONST_BITRATE_AUTO)) + if res != C.OPUS_OK { + return Error(res) + } + return nil +} + +// SetBitrateMax causes the encoder to use as much rate as it can. This can be +// useful for controlling the rate by adjusting the output buffer size. +func (enc *Encoder) SetBitrateMax() error { + res := C.bridge_encoder_set_bitrate(enc.p, C.opus_int32(C.CONST_BITRATE_MAX)) + if res != C.OPUS_OK { + return Error(res) + } + return nil +} + // Bitrate returns the bitrate of the Encoder func (enc *Encoder) Bitrate() (int, error) { var bitrate C.opus_int32 @@ -270,7 +297,7 @@ func (enc *Encoder) Complexity() (int, error) { // SetMaxBandwidth configures the maximum bandpass that the encoder will select // automatically -func (enc *Encoder) SetMaxBandwidth(maxBw int) error { +func (enc *Encoder) SetMaxBandwidth(maxBw Bandwidth) error { res := C.bridge_encoder_set_max_bandwidth(enc.p, C.opus_int32(maxBw)) if res != C.OPUS_OK { return Error(res) @@ -279,11 +306,11 @@ func (enc *Encoder) SetMaxBandwidth(maxBw int) error { } // MaxBandwidth gets the encoder's configured maximum allowed bandpass. -func (enc *Encoder) MaxBandwidth() (int, error) { +func (enc *Encoder) MaxBandwidth() (Bandwidth, error) { var maxBw C.opus_int32 res := C.bridge_encoder_get_max_bandwidth(enc.p, &maxBw) if res != C.OPUS_OK { return 0, Error(res) } - return int(maxBw), nil + return Bandwidth(maxBw), nil } diff --git a/encoder_test.go b/encoder_test.go index ba13ea2..f1ffb68 100644 --- a/encoder_test.go +++ b/encoder_test.go @@ -79,6 +79,78 @@ func TestEncoder_SetGetBitrate(t *testing.T) { } } +func TestEncoder_SetBitrateAuto(t *testing.T) { + enc, err := NewEncoder(8000, 1, AppVoIP) + if err != nil || enc == nil { + t.Errorf("Error creating new encoder: %v", err) + } + + bitrate := 5000 + if err := enc.SetBitrate(bitrate); err != nil { + t.Error("Error setting bitrate:", err) + } + + br, err := enc.Bitrate() + if err != nil { + t.Error("Error getting bitrate", err) + } + + if br != bitrate { + t.Errorf("Unexpected bitrate. Got %d, but expected %d", br, bitrate) + } + + err = enc.SetBitrateAuto() + if err != nil { + t.Error("Error setting Auto bitrate:", err) + } + + br, err = enc.Bitrate() + if err != nil { + t.Error("Error getting bitrate", err) + } + + brDefault := 32000 //default start value + if br != brDefault { + t.Errorf("Unexpected bitrate. Got %d, but expected %d", br, brDefault) + } +} + +func TestEncoder_SetBitrateMax(t *testing.T) { + enc, err := NewEncoder(8000, 1, AppVoIP) + if err != nil || enc == nil { + t.Errorf("Error creating new encoder: %v", err) + } + + bitrate := 5000 + if err := enc.SetBitrate(bitrate); err != nil { + t.Error("Error setting bitrate:", err) + } + + br, err := enc.Bitrate() + if err != nil { + t.Error("Error getting bitrate", err) + } + + if br != bitrate { + t.Errorf("Unexpected bitrate. Got %d, but expected %d", br, bitrate) + } + + err = enc.SetBitrateMax() + if err != nil { + t.Error("Error setting Auto bitrate:", err) + } + + br, err = enc.Bitrate() + if err != nil { + t.Error("Error getting bitrate", err) + } + + brMax := 4083200 + if br != brMax { //default start value + t.Errorf("Unexpected bitrate. Got %d, but expected %d", br, brMax) + } +} + func TestEncoder_SetGetInvalidBitrate(t *testing.T) { enc, err := NewEncoder(8000, 1, AppVoIP) if err != nil || enc == nil { @@ -156,11 +228,11 @@ func TestEncoder_SetGetMaxBandwidth(t *testing.T) { if err != nil || enc == nil { t.Errorf("Error creating new encoder: %v", err) } - vals := []int{BandwidthNarrowband, - BandwidthMediumBand, - BandwidthWideBand, - BandwidthSuperWideBand, - BandwidthFullband, + vals := []Bandwidth{Narrowband, + MediumBand, + WideBand, + SuperWideBand, + Fullband, } for _, maxBw := range vals { err := enc.SetMaxBandwidth(maxBw) diff --git a/opus.go b/opus.go index c0ea7d3..9040d77 100644 --- a/opus.go +++ b/opus.go @@ -18,13 +18,15 @@ import "C" type Application int -const ( +// These variables should be constants, but for interoperability with CGO +// they're var. Don't change them, though! +var ( // Optimize encoding for VoIP - AppVoIP = C.OPUS_APPLICATION_VOIP + AppVoIP = Application(C.CONST_APPLICATION_VOIP) // Optimize encoding for non-voice signals like music - AppAudio = C.OPUS_APPLICATION_AUDIO + AppAudio = Application(C.CONST_APPLICATION_AUDIO) // Optimize encoding for low latency applications - AppRestrictedLowdelay = C.OPUS_APPLICATION_RESTRICTED_LOWDELAY + AppRestrictedLowdelay = Application(C.CONST_APPLICATION_RESTRICTED_LOWDELAY) ) // DEPRECATED -- Don't use these. Will be removed end of 2017. -- 2.48.1