github.com/wdvxdr1123/go-silk@v0.0.0-20210316130616-d47b553def60/silk.go (about)

     1  package silk
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  	"errors"
     7  	"fmt"
     8  	"io"
     9  	"unsafe"
    10  
    11  	"github.com/wdvxdr1123/go-silk/sdk"
    12  
    13  	"modernc.org/libc"
    14  	"modernc.org/libc/sys/types"
    15  )
    16  
    17  var (
    18  	ErrInvalid    = errors.New("not a silk stream")
    19  	ErrCodecError = errors.New("codec error")
    20  )
    21  
    22  func DecodeSilkBuffToPcm(src []byte, sampleRate int) (dst []byte, err error) {
    23  	var tls = libc.NewTLS()
    24  	reader := bytes.NewBuffer(src)
    25  	f, err := reader.ReadByte()
    26  	if err != nil {
    27  		return
    28  	}
    29  	header := make([]byte, 9)
    30  	var n int
    31  	if f == 2 {
    32  		n, err = reader.Read(header)
    33  		if err != nil {
    34  			return
    35  		}
    36  		if n != 9 {
    37  			err = ErrInvalid
    38  			return
    39  		}
    40  		if string(header) != "#!SILK_V3" {
    41  			err = ErrInvalid
    42  			return
    43  		}
    44  	} else if f == '#' {
    45  		n, err = reader.Read(header)
    46  		if err != nil {
    47  			return
    48  		}
    49  		if n != 8 {
    50  			err = ErrInvalid
    51  			return
    52  		}
    53  		if string(header) != "!SILK_V3" {
    54  			err = ErrInvalid
    55  			return
    56  		}
    57  	} else {
    58  		err = ErrInvalid
    59  		return
    60  	}
    61  	var decControl sdk.SKP_SILK_SDK_DecControlStruct
    62  	decControl.FAPI_sampleRate = int32(sampleRate)
    63  	decControl.FframesPerPacket = 1
    64  	var decSize int32
    65  	sdk.SKP_Silk_SDK_Get_Decoder_Size(tls, uintptr(unsafe.Pointer(&decSize)))
    66  	dec := libc.Xmalloc(tls, types.Size_t(decSize))
    67  	defer libc.Xfree(tls, dec)
    68  	if sdk.SKP_Silk_init_decoder(tls, dec) != 0 {
    69  		err = ErrCodecError
    70  		return
    71  	}
    72  	// 40ms
    73  	frameSize := sampleRate / 1000 * 40
    74  	in := make([]byte, frameSize)
    75  	buf := make([]byte, frameSize)
    76  	out := &bytes.Buffer{}
    77  	for {
    78  		var nByte int16
    79  		err = binary.Read(reader, binary.LittleEndian, &nByte)
    80  		if err != nil {
    81  			if err == io.EOF {
    82  				err = nil
    83  				break
    84  			}
    85  			return
    86  		}
    87  		if int(nByte) > frameSize {
    88  			err = ErrInvalid
    89  			return
    90  		}
    91  		n, err = reader.Read(in[:nByte])
    92  		if err != nil {
    93  			if err == io.EOF {
    94  				err = nil
    95  				break
    96  			}
    97  			return
    98  		}
    99  		if n != int(nByte) {
   100  			err = ErrInvalid
   101  			return
   102  		}
   103  		sdk.SKP_Silk_SDK_Decode(tls, dec, uintptr(unsafe.Pointer(&decControl)), 0,
   104  			uintptr(unsafe.Pointer(&in[0])), int32(n),
   105  			uintptr(unsafe.Pointer(&buf[0])),
   106  			uintptr(unsafe.Pointer(&nByte)))
   107  
   108  		_, _ = out.Write(buf[:nByte*2])
   109  
   110  	}
   111  	dst = out.Bytes()
   112  	return
   113  }
   114  
   115  func EncodePcmBuffToSilk(src []byte, sampleRate, bitRate int, tencent bool) (dst []byte, err error) {
   116  	var tls = libc.NewTLS()
   117  	var reader = bytes.NewBuffer(src)
   118  	var encControl sdk.SKP_SILK_SDK_EncControlStruct
   119  	var encStatus sdk.SKP_SILK_SDK_EncControlStruct
   120  	var packetSizeMs = int32(20)
   121  	{ // default setting
   122  		encControl.FAPI_sampleRate = int32(sampleRate)
   123  		encControl.FmaxInternalSampleRate = 24000
   124  		encControl.FpacketSize = (packetSizeMs * int32(sampleRate)) / 1000
   125  		encControl.FpacketLossPercentage = int32(0)
   126  		encControl.FuseInBandFEC = 0
   127  		encControl.FuseDTX = 0
   128  		encControl.Fcomplexity = 2
   129  		encControl.FbitRate = int32(bitRate)
   130  	}
   131  	var encSizeBytes int32
   132  	ret := sdk.SKP_Silk_SDK_Get_Encoder_Size(tls, uintptr(unsafe.Pointer(&encSizeBytes)))
   133  	if ret != 0 {
   134  		return nil, fmt.Errorf("SKP_Silk_create_encoder returned %d", ret)
   135  	}
   136  	psEnc := libc.Xmalloc(tls, types.Size_t(encSizeBytes))
   137  	defer libc.Xfree(tls, psEnc)
   138  	ret = sdk.SKP_Silk_SDK_InitEncoder(tls, psEnc, uintptr(unsafe.Pointer(&encStatus)))
   139  	if ret != 0 {
   140  		return nil, fmt.Errorf("SKP_Silk_reset_encoder returned %d", ret)
   141  	}
   142  	var frameSize = sampleRate / 1000 * 40
   143  	var (
   144  		nBytes  = int16(250 * 5)
   145  		in      = make([]byte, frameSize)
   146  		payload = make([]byte, nBytes)
   147  		out     = bytes.Buffer{}
   148  	)
   149  	if tencent {
   150  		_, _ = out.Write([]byte("\x02#!SILK_V3"))
   151  	} else {
   152  		_, _ = out.Write([]byte("#!SILK_V3"))
   153  	}
   154  	var counter int
   155  	for {
   156  		counter, err = reader.Read(in)
   157  		if err != nil {
   158  			if err == io.EOF {
   159  				err = nil
   160  				break
   161  			}
   162  			return
   163  		}
   164  		if counter < frameSize {
   165  			break
   166  		}
   167  		nBytes = int16(1250)
   168  		ret = sdk.SKP_Silk_SDK_Encode(
   169  			tls,
   170  			psEnc,
   171  			uintptr(unsafe.Pointer(&encControl)),
   172  			uintptr(unsafe.Pointer(&in[0])),
   173  			int32(counter)/2,
   174  			uintptr(unsafe.Pointer(&payload[0])),
   175  			uintptr(unsafe.Pointer(&nBytes)),
   176  		)
   177  
   178  		if ret != 0 {
   179  			return nil, fmt.Errorf("SKP_Silk_Encode returned %d", ret)
   180  		}
   181  		_ = binary.Write(&out, binary.LittleEndian, nBytes)
   182  		_, _ = out.Write(payload[:nBytes])
   183  	}
   184  	if !tencent {
   185  		_ = binary.Write(&out, binary.LittleEndian, int16(-1))
   186  	}
   187  	dst = out.Bytes()
   188  	return
   189  }