package aacenc // Package aacenc implements cgo bindings for [VisualOn AAC encoder library](https://github.com/mstorsjo/vo-aacenc) library. //#include "voAAC.h" // VO_U32 encode(VO_HANDLE hCodec,void *pcm, int pcmlen, void *aac, int aacBufferSize, VO_U32 *err); import "C" import ( "errors" "unsafe" ) // Constants. const ( // AAC Param ID VoPidAacMdoule = 0x42211000 VoPidAacEncparam = VoPidAacMdoule | 0x0040 // AAC decoder error ID VoErrAacMdoule = 0x82210000 VoErrAacUnsfileformat = (VoErrAacMdoule | 0xF001) VoErrAacUnsprofile = (VoErrAacMdoule | 0xF002) // The base param ID for AUDIO codec VoPidAudioBase = 0x42000000 // The format data of audio in track VoPidAudioFormat = (VoPidAudioBase | 0x0001) // The sample rate of audio VoPidAudioSampleRate = (VoPidAudioBase | 0x0002) // The channel of audio VoPidAudioChannels = (VoPidAudioBase | 0x0003) // The bit rate of audio VoPidAudioBitrate = (VoPidAudioBase | 0x0004) // The channel mode of audio VoPidAudioChannelmode = (VoPidAudioBase | 0x0005) // The base of common param ID VoPidCommonBase = 0x40000000 // Query the memory needed; Reserved VoPidCommonQueryMem = (VoPidCommonBase | 0) // Set or get the input buffer type VoPidCommonInputType = (VoPidCommonBase | 0) // Query it has resource to be used VoPidCommonHasResource = (VoPidCommonBase | 0) // Decoder track header data VoPidCommonHeadData = (VoPidCommonBase | 0) // VoPidCommonFlush as defined in include/voIndex.h:182 VoPidCommonFlush = (VoPidCommonBase | 0) ) // Error codes. const ( VoErrNone = 0x00000000 VoErrFinish = 0x00000001 VoErrFailed = 0x80000001 VoErrOutofMemory = 0x80000002 VoErrNotImplement = 0x80000003 VoErrInvalidArg = 0x80000004 VoErrInputBufferSmall = 0x80000005 VoErrOutputBufferSmall = 0x80000006 VoErrWrongStatus = 0x80000007 VoErrWrongParamId = 0x80000008 VoErrLicenseError = 0x80000009 VoErrAudioBase = 0x82000000 VoErrAudioUnsChannel = VoErrAudioBase | 0x0001 VoErrAudioUnsSampleRate = VoErrAudioBase | 0x0002 VoErrAudioUnsFeature = VoErrAudioBase | 0x0003 ) // Enumeration used to define the possible audio coding formats. const ( // Placeholder value when coding is N/A VoAudioCodingUnused int32 = iota // Any variant of PCM coding VoAudioCodingPcm // Any variant of ADPCM encoded data VoAudioCodingAdpcm // Any variant of AMR encoded data VoAudioCodingAmrnb // Any variant of AMR encoded data VoAudioCodingAmrwb // Any variant of AMR encoded data VoAudioCodingAmrwbp // Any variant of QCELP 13kbps encoded data VoAudioCodingQcelp13 // Any variant of EVRC encoded data VoAudioCodingEvrc // Any variant of AAC encoded data, 0xA106 - ISO/MPEG-4 AAC, 0xFF - AAC VoAudioCodingAac // Any variant of AC3 encoded data VoAudioCodingAc3 // Any variant of FLAC encoded data VoAudioCodingFlac // Any variant of MP1 encoded data VoAudioCodingMp1 // Any variant of MP3 encoded data VoAudioCodingMp3 // Any variant of OGG encoded data VoAudioCodingOgg // Any variant of WMA encoded data VoAudioCodingWma // Any variant of RA encoded data VoAudioCodingRa // Any variant of MIDI encoded data VoAudioCodingMidi // Any variant of dra encoded data VoAudioCodingDra // Any variant of dra encoded data VoAudioCodingG729 ) // The frame type that the decoder supports. const ( // Contains only raw aac data in a frame VoAacRawdata int32 = iota // Contains ADTS header + raw AAC data in a frame VoAacAdts ) // The channel type value. const ( // Center channel VoChannelCenter int32 = 1 // Front left channel VoChannelFrontLeft = 1 << 1 // Front right channel VoChannelFrontRight = 1 << 2 // Side left channel VoChannelSideLeft = 1 << 3 // Side right channel VoChannelSideRight = 1 << 4 // Back left channel VoChannelBackLeft = 1 << 5 // Back right channel VoChannelBackRight = 1 << 6 // Back center channel VoChannelBackCenter = 1 << 7 // Low-frequency effects bass channel VoChannelLfeBass = 1 << 8 // Include all channels (default) VoChannelAll = 0xffff ) // Input stream format, Frame or Stream. const ( // Input contains completely frame(s) data VoInputFrame int32 = iota + 1 // Input is stream data. VoInputStream ) // VoAudioFormat - general audio format info. type VoAudioFormat struct { // Sample rate SampleRate int // Channel count Channels int // Bits per sample SampleBits int } // cptr return C pointer. func (v *VoAudioFormat) cptr() *C.VO_AUDIO_FORMAT { return (*C.VO_AUDIO_FORMAT)(unsafe.Pointer(v)) } // VoAudioOutputinfo - general audio output info. type VoAudioOutputinfo struct { // Sample rate Format VoAudioFormat // Channel count InputUsed uint // Reserved Reserve uint } // cptr return C pointer. func (v *VoAudioOutputinfo) cptr() *C.VO_AUDIO_OUTPUTINFO { return (*C.VO_AUDIO_OUTPUTINFO)(unsafe.Pointer(v)) } // VoCodecBuffer - general data buffer, used as input or output. type VoCodecBuffer struct { // Buffer pointer Buffer unsafe.Pointer // Buffer size in byte Length uint64 // The time of the buffer Time int64 } // cptr return C pointer. func (v *VoCodecBuffer) cptr() *C.VO_CODECBUFFER { return (*C.VO_CODECBUFFER)(unsafe.Pointer(v)) } // AacencParam - the structure for AAC encoder input parameter. type AacencParam struct { // Audio file sample rate SampleRate int32 // Encoder bit rate in bits/sec BitRate int32 // Number of channels on input (1,2) NChannels int16 // Whether write adts header AdtsUsed int16 } // Encoder Thread-safe type Encoder struct { handle C.VO_HANDLE outbuff [20480]byte blockSize int // size of block for encoding } // Errors. var ( ErrFinish = errors.New("aac: error finish") ErrFailed = errors.New("aac: process data failed") ErrOutOfMemory = errors.New("aac: out of memory") ErrNotImplement = errors.New("aac: feature not implemented") ErrInvalidArg = errors.New("aac: invalid argument") ErrInputBufferSmall = errors.New("aac: input buffer data too small") ErrOutputBufferSmall = errors.New("aac: output buffer size too small") ErrWrongStatus = errors.New("aac: wrong encoder run-time status") ErrWrongParamId = errors.New("aac: wrong parameter id") ErrLicenseError = errors.New("aac: license error") ErrAudioBase = errors.New("aac: error audio base") ErrAudioUnsChannel = errors.New("aac: unsupported number of channel") ErrAudioUnsSampleRate = errors.New("aac: unsupported sample rate") ErrAudioUnsFeature = errors.New("aac: unsupported feature") ) // ErrorFromResult returns error for result code func ErrorFromResult(r uint) error { switch r { case VoErrNone: return nil case VoErrFinish: return ErrFinish case VoErrFailed: return ErrFailed case VoErrOutofMemory: return ErrOutOfMemory case VoErrNotImplement: return ErrNotImplement case VoErrInvalidArg: return ErrInvalidArg case VoErrInputBufferSmall: return ErrInputBufferSmall case VoErrOutputBufferSmall: return ErrOutputBufferSmall case VoErrWrongStatus: return ErrWrongStatus case VoErrWrongParamId: return ErrWrongParamId case VoErrLicenseError: return ErrLicenseError case VoErrAudioBase: return ErrAudioBase case VoErrAudioUnsChannel: return ErrAudioUnsChannel case VoErrAudioUnsSampleRate: return ErrAudioUnsSampleRate case VoErrAudioUnsFeature: return ErrAudioUnsFeature default: return nil } } // New encoder func New() *Encoder { return &Encoder{} } // Init - init the audio codec module and return codec handle. func (e *Encoder) Init(vtype int32) uint { cvtype := (C.VO_AUDIO_CODINGTYPE)(vtype) ret := C.voAACEncInit(&e.handle, cvtype, nil) v := (uint)(ret) return v } // SetInputData - set input audio data. func (e *Encoder) SetInputData(pinput *VoCodecBuffer) uint { cpinput := pinput.cptr() ret := C.voAACEncSetInputData(e.handle, cpinput) v := (uint)(ret) return v } // GetOutputData - get the outut audio data. func (e *Encoder) GetOutputData(poutbuffer *VoCodecBuffer, poutinfo *VoAudioOutputinfo) uint { cpoutbuffer := poutbuffer.cptr() cpoutinfo := poutinfo.cptr() ret := C.voAACEncGetOutputData(e.handle, cpoutbuffer, cpoutinfo) v := (uint)(ret) return v } // SetParam - set the parameter for the specified param ID. func (e *Encoder) SetParam(uparamid int, pdata unsafe.Pointer) uint { cuparamid := (C.VO_S32)(uparamid) cpdata := (C.VO_PTR)(pdata) ret := C.voAACEncSetParam(e.handle, cuparamid, cpdata) v := (uint)(ret) return v } // GetParam - get the parameter for the specified param ID. func (e *Encoder) GetParam(uparamid int, pdata unsafe.Pointer) uint { cuparamid := (C.VO_S32)(uparamid) cpdata := (C.VO_PTR)(pdata) ret := C.voAACEncGetParam(e.handle, cuparamid, cpdata) v := (uint)(ret) return v } // Uninit - uninit the Codec. func (e *Encoder) Uninit() uint { ret := C.voAACEncUninit(e.handle) v := (uint)(ret) return v } // EncodePcmBlock - Encodes single interleaved block 1024 * numchannels // if buffer size is wrong returns VoErrInvalidArg func (e *Encoder) EncodePcmBlock(inPcm []int16) (aac []byte, err uint) { if len(inPcm) != e.blockSize { return nil, VoErrInvalidArg } var ret C.VO_U32 len := C.encode(e.handle, unsafe.Pointer(&inPcm[0]), C.int(len(inPcm)*2), // int16 unsafe.Pointer(&e.outbuff[0]), C.int(len(e.outbuff)), &ret) err = uint(ret) if err != VoErrNone { // error return nil, err } return e.outbuff[:len], err } // SetParamAac set Samplerate & numchannels for AAC encoding func (e *Encoder) SetParamAac(aacSamplerate, nChannels int) (err uint) { e.blockSize = 1024 * nChannels setParametersBlock := C.AACENC_PARAM{ sampleRate: C.int(aacSamplerate), /*! audio file sample rate */ bitRate: 64000, /*! encoder bit rate in bits/sec */ nChannels: C.short(nChannels), /*! number of channels on input (1,2) */ adtsUsed: 1, /*! whether write adts header */ } return uint(C.voAACEncSetParam(e.handle, VoPidAacEncparam, C.VO_PTR(&setParametersBlock))) }