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 }