func NewEncoder(sampleRate, channels int, application Application) (*Encoder, error) { encoder := &Encoder{} encoder.data = make([]byte, int(C.opus_encoder_get_size(C.int(channels)))) encoder.cEncoder = (*C.struct_OpusEncoder)(unsafe.Pointer(&encoder.data[0])) ret := C.opus_encoder_init(encoder.cEncoder, C.opus_int32(sampleRate), C.int(channels), C.int(application)) if err := getErr(ret); err != nil { return nil, err } return encoder, nil }
func (d *Decoder) Decode(data []byte, frameSize int, fec bool) ([]int16, error) { var dataPtr *C.uchar if len(data) > 0 { dataPtr = (*C.uchar)(unsafe.Pointer(&data[0])) } dataLen := C.opus_int32(len(data)) output := make([]int16, d.channels*frameSize) outputPtr := (*C.opus_int16)(unsafe.Pointer(&output[0])) var cFec C.int if fec { cFec = 1 } else { cFec = 0 } cRet := C.opus_decode(d.cDecoder, dataPtr, dataLen, outputPtr, C.int(frameSize), cFec) ret := int(cRet) if ret < 0 { return nil, getErr(cRet) } return output[:ret*d.channels], nil }
func (e *Encoder) ctl_int32(request, arg int32) int { return int(C.azul3d_opus_encoder_ctl_int32( e.cptr(), C.int(request), C.opus_int32(arg), )) }
// Decode decodes a single Opus frame to floating point format. Stereo // output will be interleaved. A null input frame indicates packet loss. func (dec *Decoder) Decode(frame []byte, pksize int, isFec bool) (pcm []float32, err error) { var input *C.uchar if frame != nil { input = (*C.uchar)(&frame[0]) } isfNum := 0 if isFec { isfNum = 1 } pcm = make([]float32, pksize*dec.chcnt) num := C.opus_decode_float(&dec.cee, input, C.opus_int32(len(frame)), (*C.float)(&pcm[0]), C.int(pksize), C.int(isfNum)) if num < 0 { pcm = nil err = ErrUnspecified switch num { case C.OPUS_BAD_ARG: fmt.Println("OPUS_BAD_ARG") case C.OPUS_BUFFER_TOO_SMALL: fmt.Println("OPUS_BUFFER_TOO_SMALL") case C.OPUS_INVALID_PACKET: fmt.Println("OPUS_INVALID_PACKET") } return } pcm = pcm[:num*C.int(dec.chcnt)] return }
func (this *Encoder) Init(sampleRate int, channels int, application Application) { C.opus_encoder_init( this.ptr, C.opus_int32(C.int(sampleRate)), C.int(channels), C.int(application), ) }
func CountFrames(data []byte) (int, error) { dataPtr := (*C.uchar)(unsafe.Pointer(&data[0])) cLen := C.opus_int32(len(data)) cRet := C.opus_packet_get_nb_frames(dataPtr, cLen) if err := getErr(cRet); err != nil { return 0, err } return int(cRet), nil }
func NewEncoder(sampleRate int, channels int, application Application) (*Encoder, error) { var err C.int encoder := C.opus_encoder_create( C.opus_int32(C.int(sampleRate)), C.int(channels), C.int(application), &err, ) return &Encoder{encoder}, toError(err) }
func NewDecoder(sampleRate, channels int) (*Decoder, error) { decoder := &Decoder{} decoder.data = make([]byte, int(C.opus_decoder_get_size(C.int(channels)))) decoder.cDecoder = (*C.struct_OpusDecoder)(unsafe.Pointer(&decoder.data[0])) ret := C.opus_decoder_init(decoder.cDecoder, C.opus_int32(sampleRate), C.int(channels)) if err := getErr(ret); err != nil { return nil, err } decoder.channels = channels return decoder, nil }
// NewDecoder creates a new Opus decoder with the given sample rate // and number of channels. func NewDecoder(sampleRate int, chanCount int) (dec *Decoder, err error) { dec = new(Decoder) // allocate Opus decoder ecode := C.opus_decoder_init(&dec.cee, C.opus_int32(sampleRate), C.int(chanCount)) if ecode != C.OPUS_OK { dec = nil err = ErrUnspecified } dec.chcnt = chanCount return }
// EncodeFloat encodes an Opus frame from floating point input. // // pcm: the 32-bit float PCM input signal (interleaved if 2 channels). Whose // length is frameSize*channels. Samples have a normal range of +/-1.0, but can // have a range beyond that (but they will be clipped by decoders using the // integer API and should only be used if it is known that the far end supports // extended dynamic range). // // frameSize: the number of samples per channel in the input signal. This must // be an Opus frame size for the encoder's sampling rate. For example at 48kHz // the permitted values are 120, 240, 480, 960, 1920, and 2880. Passing in a // duration of less than 10 ms (480 samples at 48 kHz) will prevent the encoder // from using the LPC or hybrid modes. // // data: the slice to store the output payload in, containing len(data) bytes // of space. The length of the slice may be used to impose an upper limit on // the instant bitrate, but should not be used as the only bitrate control. Use // SET_BITRATE to control the bitrate. // // returns: a slice of the data slice representing the encoded packet, OR nil // and an error. func (e *Encoder) EncodeFloat(pcm []float32, frameSize int, data []byte) ([]byte, error) { n := C.opus_encode_float( e.cptr(), (*C.float)(unsafe.Pointer(&pcm[0])), C.int(frameSize), (*C.uchar)(unsafe.Pointer(&data[0])), C.opus_int32(len(data)), ) if n > 0 { return data[:n], nil } return nil, opusError(C.int(-n)) }
// Allocates and initializes an encoder state. There are three coding modes: // // 1. APPLICATION_VOIP gives best quality at a given bitrate for voice // signals. It enhances the input signal by high-pass filtering and // emphasizing formants and harmonics. Optionally it includes in-band forward // error correction to protect against packet loss. Use this mode for typical // VoIP applications. Because of the enhancement, even at high bitrates the // output may sound different from the input. // // 2. APPLICATION_AUDIO gives best quality at a given bitrate for most // non-voice signals like music. Use this mode for music and mixed // (music/voice) content, broadcast, and applications requiring less than 15 // ms of coding delay. // // 3. APPLICATION_RESTRICTED_LOWDELAY configures low-delay mode that disables // the speech-optimized mode in exchange for slightly reduced delay. This mode // can only be set on an newly initialized or freshly reset encoder because it // changes the codec delay. This is useful when the caller knows that the // speech-optimized modes will not be needed (use with caution). // // Fs: Sampling rate of input signal (Hz). This must be one of 8000, 12000, // 16000, 24000, or 48000. // // channels: Number of channels (1 or 2) in input signal // // application: Coding mode (APPLICATION_VOIP/APPLICATION_AUDIO/APPLICATION_RESTRICTED_LOWDELAY) // // note: Regardless of the sampling rate and number channels selected, the Opus // encoder can switch to a lower audio bandwidth or number of channels if the // bitrate selected is too low. This also means that it is safe to always use // 48 kHz stereo input and let the encoder optimize the encoding. func NewEncoder(Fs, channels, application int) (*Encoder, error) { enc := new(Encoder) err := opusError(C.opus_encoder_init( enc.cptr(), C.opus_int32(Fs), C.int(channels), C.int(application), )) if err != nil { return nil, err } return enc, nil }
func (e *Encoder) Encode(pcm []int16, frameSize, maxDataBytes int) ([]byte, error) { pcmPtr := (*C.opus_int16)(unsafe.Pointer(&pcm[0])) data := make([]byte, maxDataBytes) dataPtr := (*C.uchar)(unsafe.Pointer(&data[0])) encodedC := C.opus_encode(e.cEncoder, pcmPtr, C.int(frameSize), dataPtr, C.opus_int32(len(data))) encoded := int(encodedC) if encoded < 0 { return nil, getErr(C.int(encodedC)) } return data[0:encoded], nil }
// 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 Application) error { if enc.p != nil { return fmt.Errorf("opus encoder already initialized") } if channels != 1 && channels != 2 { return fmt.Errorf("Number of channels must be 1 or 2: %d", channels) } size := C.opus_encoder_get_size(C.int(channels)) enc.mem = make([]byte, size) enc.p = (*C.OpusEncoder)(unsafe.Pointer(&enc.mem[0])) errno := int(C.opus_encoder_init( enc.p, C.opus_int32(sample_rate), C.int(channels), C.int(application))) if errno != 0 { return opuserr(int(errno)) } return nil }
func (dec *Decoder) Init(sample_rate int, channels int) error { if dec.p != nil { return fmt.Errorf("opus decoder already initialized") } if channels != 1 && channels != 2 { return fmt.Errorf("Number of channels must be 1 or 2: %d", channels) } size := C.opus_decoder_get_size(C.int(channels)) dec.sample_rate = sample_rate dec.mem = make([]byte, size) dec.p = (*C.OpusDecoder)(unsafe.Pointer(&dec.mem[0])) errno := C.opus_decoder_init( dec.p, C.opus_int32(sample_rate), C.int(channels)) if errno != 0 { return opuserr(int(errno)) } return nil }
// Encode raw PCM data and store the result in the supplied buffer. On success, // returns the number of bytes used up by the encoded data. func (enc *Encoder) EncodeFloat32(pcm []float32, data []byte) (int, error) { if enc.p == nil { return 0, errEncUninitialized } if len(pcm) == 0 { return 0, fmt.Errorf("opus: no data supplied") } if len(data) == 0 { return 0, fmt.Errorf("opus: no target buffer") } n := int(C.opus_encode_float( enc.p, (*C.float)(&pcm[0]), C.int(len(pcm)), (*C.uchar)(&data[0]), C.opus_int32(cap(data)))) if n < 0 { return 0, opuserr(n) } return n, nil }
// Decode encoded Opus data into the supplied buffer. On success, returns the // number of samples correctly written to the target buffer. func (dec *Decoder) DecodeFloat32(data []byte, pcm []float32) (int, error) { if dec.p == nil { return 0, errDecUninitialized } if len(data) == 0 { return 0, fmt.Errorf("opus: no data supplied") } if len(pcm) == 0 { return 0, fmt.Errorf("opus: target buffer empty") } n := int(C.opus_decode_float( dec.p, (*C.uchar)(&data[0]), C.opus_int32(len(data)), (*C.float)(&pcm[0]), C.int(cap(pcm)), 0)) if n < 0 { return 0, opuserr(n) } return n, nil }