dxc 1 рік тому
коміт
da185cc1c0
48 змінених файлів з 3512 додано та 0 видалено
  1. 1 0
      .gitignore
  2. 8 0
      .idea/.gitignore
  3. 9 0
      .idea/audio_transcoder.iml
  4. 8 0
      .idea/modules.xml
  5. 6 0
      .idea/vcs.xml
  6. 14 0
      etc/transcoder.yaml
  7. 52 0
      go.mod
  8. 180 0
      go.sum
  9. 6 0
      go.work
  10. 20 0
      internal/config/config.go
  11. 22 0
      internal/handler/routes.go
  12. 28 0
      internal/handler/transcoderhandler.go
  13. 126 0
      internal/logic/transcoderlogic.go
  14. 21 0
      internal/svc/servicecontext.go
  15. 11 0
      internal/types/types.go
  16. BIN
      pkg/baidu/16k.wav
  17. 118 0
      pkg/baidu/asr.go
  18. 31 0
      pkg/baidu/asr_test.go
  19. 28 0
      pkg/baidu/model.go
  20. 60 0
      pkg/oss/qiniu.go
  21. 16 0
      pkg/oss/qiniu_test.go
  22. BIN
      pkg/silk2audio/example/2020_08_20_12_15_38_829.silk
  23. 3 0
      pkg/silk2audio/go.mod
  24. 11 0
      pkg/silk2audio/main.go
  25. 486 0
      pkg/silk2audio/silk/Decoder.c
  26. 5 0
      pkg/silk2audio/silk/Decoder.h
  27. 278 0
      pkg/silk2audio/silk/SKP_Silk_Inlines.h
  28. 152 0
      pkg/silk2audio/silk/SKP_Silk_SDK_API.h
  29. 662 0
      pkg/silk2audio/silk/SKP_Silk_SigProc_FIX.h
  30. 91 0
      pkg/silk2audio/silk/SKP_Silk_control.h
  31. 89 0
      pkg/silk2audio/silk/SKP_Silk_errors.h
  32. 125 0
      pkg/silk2audio/silk/SKP_Silk_macros.h
  33. 80 0
      pkg/silk2audio/silk/SKP_Silk_resampler_structs.h
  34. 107 0
      pkg/silk2audio/silk/SKP_Silk_typedef.h
  35. BIN
      pkg/silk2audio/silk/libSKP_SILK_SDK.a.linux_bak
  36. BIN
      pkg/silk2audio/silk/libSKP_SILK_SDK.a.win_bak
  37. 75 0
      pkg/silk2audio/silk/silk.go
  38. 4 0
      pkg/silk2audio/transcoder/config.go
  39. 9 0
      pkg/silk2audio/transcoder/ffmpeg/config.go
  40. 283 0
      pkg/silk2audio/transcoder/ffmpeg/ffmpeg.go
  41. 187 0
      pkg/silk2audio/transcoder/ffmpeg/options.go
  42. 10 0
      pkg/silk2audio/transcoder/ffmpeg/progress.go
  43. 6 0
      pkg/silk2audio/transcoder/options.go
  44. 5 0
      pkg/silk2audio/transcoder/progress.go
  45. 13 0
      pkg/silk2audio/transcoder/transcoder.go
  46. 22 0
      pkg/silk2audio/transcoder/utils/utils.go
  47. 13 0
      transcoder.api
  48. 31 0
      transcoder.go

+ 1 - 0
.gitignore

@@ -0,0 +1 @@
+/pkg/silk2audio/silk/libSKP_SILK_SDK.a

+ 8 - 0
.idea/.gitignore

@@ -0,0 +1,8 @@
+# 默认忽略的文件
+/shelf/
+/workspace.xml
+# 基于编辑器的 HTTP 客户端请求
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml

+ 9 - 0
.idea/audio_transcoder.iml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="WEB_MODULE" version="4">
+  <component name="Go" enabled="true" />
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$" />
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

+ 8 - 0
.idea/modules.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/audio_transcoder.iml" filepath="$PROJECT_DIR$/.idea/audio_transcoder.iml" />
+    </modules>
+  </component>
+</project>

+ 6 - 0
.idea/vcs.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+  </component>
+</project>

+ 14 - 0
etc/transcoder.yaml

@@ -0,0 +1,14 @@
+Name: transcoder
+Host: 0.0.0.0
+Port: 8888
+
+QiNiuConf:
+  AccessKey: "B81Gsvry2StqKVE3txS-7v9GBBfqykC9zhebmxnW"
+  SecretKey: "YEZJuYcdeF7vRvzffxpopAVR-jMPZg9pZ-4IKTVW"
+  Bucket: "wechatcs"
+  HostUrl: "http://cs.wechat.kfzs.com"
+
+BaiduAsrConf:
+  AppID: "25050867"
+  APIKey: "ctBGhGGm88Hudge0iBCSiF7y"
+  SecretKey: "xyNcQfVtqxZMp20dqkDAyp6eGogfFbhV"

+ 52 - 0
go.mod

@@ -0,0 +1,52 @@
+module audio_transcoder
+
+go 1.20
+
+require (
+	github.com/google/uuid v1.6.0
+	github.com/qiniu/go-sdk/v7 v7.20.1
+	github.com/zeromicro/go-zero v1.6.5
+)
+
+require (
+	github.com/beorn7/perks v1.0.1 // indirect
+	github.com/cenkalti/backoff/v4 v4.2.1 // indirect
+	github.com/cespare/xxhash/v2 v2.2.0 // indirect
+	github.com/fatih/color v1.16.0 // indirect
+	github.com/go-logr/logr v1.3.0 // indirect
+	github.com/go-logr/stdr v1.2.2 // indirect
+	github.com/gofrs/flock v0.8.1 // indirect
+	github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
+	github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 // indirect
+	github.com/mattn/go-colorable v0.1.13 // indirect
+	github.com/mattn/go-isatty v0.0.20 // indirect
+	github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
+	github.com/openzipkin/zipkin-go v0.4.2 // indirect
+	github.com/pelletier/go-toml/v2 v2.2.2 // indirect
+	github.com/prometheus/client_golang v1.18.0 // indirect
+	github.com/prometheus/client_model v0.5.0 // indirect
+	github.com/prometheus/common v0.45.0 // indirect
+	github.com/prometheus/procfs v0.12.0 // indirect
+	github.com/spaolacci/murmur3 v1.1.0 // indirect
+	go.opentelemetry.io/otel v1.19.0 // indirect
+	go.opentelemetry.io/otel/exporters/jaeger v1.17.0 // indirect
+	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 // indirect
+	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 // indirect
+	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 // indirect
+	go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.19.0 // indirect
+	go.opentelemetry.io/otel/exporters/zipkin v1.19.0 // indirect
+	go.opentelemetry.io/otel/metric v1.19.0 // indirect
+	go.opentelemetry.io/otel/sdk v1.19.0 // indirect
+	go.opentelemetry.io/otel/trace v1.19.0 // indirect
+	go.opentelemetry.io/proto/otlp v1.0.0 // indirect
+	go.uber.org/automaxprocs v1.5.3 // indirect
+	golang.org/x/net v0.25.0 // indirect
+	golang.org/x/sync v0.6.0 // indirect
+	golang.org/x/sys v0.20.0 // indirect
+	golang.org/x/text v0.15.0 // indirect
+	google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect
+	google.golang.org/grpc v1.63.2 // indirect
+	google.golang.org/protobuf v1.34.1 // indirect
+	gopkg.in/yaml.v2 v2.4.0 // indirect
+)

+ 180 - 0
go.sum

@@ -0,0 +1,180 @@
+github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
+github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
+github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
+github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
+github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
+github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
+github.com/dave/jennifer v1.6.1/go.mod h1:nXbxhEmQfOZhWml3D1cDK5M1FLnMSozpbFN/m3RmGZc=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
+github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
+github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
+github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
+github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
+github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
+github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
+github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
+github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
+github.com/go-playground/validator/v10 v10.8.0/go.mod h1:9JhgTzTaE31GZDpH/HSvHiRJrJ3iKAgqqH0Bl/Ocjdk=
+github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
+github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
+github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
+github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
+github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 h1:RtRsiaGvWxcwd8y3BiRZxsylPT8hLWZ5SPcfI+3IDNk=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0/go.mod h1:TzP6duP4Py2pHLVPPQp42aoYI92+PCrVotyR5e8Vqlk=
+github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
+github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
+github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
+github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
+github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
+github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
+github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg=
+github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k=
+github.com/openzipkin/zipkin-go v0.4.2 h1:zjqfqHjUpPmB3c1GlCvvgsM1G4LkvqQbBDueDOCg/jA=
+github.com/openzipkin/zipkin-go v0.4.2/go.mod h1:ZeVkFjuuBiSy13y8vpSDCjMi9GoI3hPpCJSBx/EYFhY=
+github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
+github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
+github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
+github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk=
+github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA=
+github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
+github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
+github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM=
+github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY=
+github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
+github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
+github.com/qiniu/dyn v1.3.0/go.mod h1:E8oERcm8TtwJiZvkQPbcAh0RL8jO1G0VXJMW3FAWdkk=
+github.com/qiniu/go-sdk/v7 v7.20.1 h1:LYlFgL4b7xaifQoqw0uYZeseyQLxCzRYz9DNBSutkbk=
+github.com/qiniu/go-sdk/v7 v7.20.1/go.mod h1:ZnEP1rOOi7weF+yzM2qZMHI0z1ht+KjVuNAuKTQW3aM=
+github.com/qiniu/x v1.10.5/go.mod h1:03Ni9tj+N2h2aKnAz+6N0Xfl8FwMEDRC2PAlxekASDs=
+github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
+github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
+github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
+github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
+github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
+github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
+github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
+github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+github.com/zeromicro/go-zero v1.6.5 h1:JgsBa25/knnEL7+KQksbwktudIkNQvaAin0nisVgnSA=
+github.com/zeromicro/go-zero v1.6.5/go.mod h1:XjbssEVEzFKueAh0Fie5kNf+cRqFlQQk46fY9WgEGaM=
+go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs=
+go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY=
+go.opentelemetry.io/otel/exporters/jaeger v1.17.0 h1:D7UpUy2Xc2wsi1Ras6V40q806WM07rqoCWzXu7Sqy+4=
+go.opentelemetry.io/otel/exporters/jaeger v1.17.0/go.mod h1:nPCqOnEH9rNLKqH/+rrUjiMzHJdV1BlpKcTwRTyKkKI=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 h1:3d+S281UTjM+AbF31XSOYn1qXn3BgIdWl8HNEpx08Jk=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0/go.mod h1:0+KuTDyKL4gjKCF75pHOX4wuzYDUZYfAQdSu43o+Z2I=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU=
+go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.19.0 h1:Nw7Dv4lwvGrI68+wULbcq7su9K2cebeCUrDjVrUJHxM=
+go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.19.0/go.mod h1:1MsF6Y7gTqosgoZvHlzcaaM8DIMNZgJh87ykokoNH7Y=
+go.opentelemetry.io/otel/exporters/zipkin v1.19.0 h1:EGY0h5mGliP9o/nIkVuLI0vRiQqmsYOcbwCuotksO1o=
+go.opentelemetry.io/otel/exporters/zipkin v1.19.0/go.mod h1:JQgTGJP11yi3o4GHzIWYodhPisxANdqxF1eHwDSnJrI=
+go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE=
+go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8=
+go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o=
+go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A=
+go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg=
+go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo=
+go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
+go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=
+go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8=
+go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
+go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
+golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
+golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
+golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
+golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
+golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY=
+google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de h1:jFNzHPIeuzhdRwVhbZdiym9q0ory/xY3sA+v2wPg8I0=
+google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:5iCWqnniDlqZHrd3neWVTOwvh/v6s3232omMecelax8=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY=
+google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM=
+google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA=
+google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
+google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
+gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=

+ 6 - 0
go.work

@@ -0,0 +1,6 @@
+go 1.20
+
+use (
+	.
+	pkg/silk2audio
+)

+ 20 - 0
internal/config/config.go

@@ -0,0 +1,20 @@
+package config
+
+import (
+	"github.com/zeromicro/go-zero/rest"
+)
+
+type Config struct {
+	rest.RestConf
+	QiNiuConf struct {
+		AccessKey string
+		SecretKey string
+		Bucket    string
+		HostUrl   string
+	}
+	BaiduAsrConf struct {
+		AppID     string
+		APIKey    string
+		SecretKey string
+	}
+}

+ 22 - 0
internal/handler/routes.go

@@ -0,0 +1,22 @@
+// Code generated by goctl. DO NOT EDIT.
+package handler
+
+import (
+	"net/http"
+
+	"audio_transcoder/internal/svc"
+
+	"github.com/zeromicro/go-zero/rest"
+)
+
+func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
+	server.AddRoutes(
+		[]rest.Route{
+			{
+				Method:  http.MethodGet,
+				Path:    "/v1/transcoder",
+				Handler: TranscoderHandler(serverCtx),
+			},
+		},
+	)
+}

+ 28 - 0
internal/handler/transcoderhandler.go

@@ -0,0 +1,28 @@
+package handler
+
+import (
+	"net/http"
+
+	"audio_transcoder/internal/logic"
+	"audio_transcoder/internal/svc"
+	"audio_transcoder/internal/types"
+	"github.com/zeromicro/go-zero/rest/httpx"
+)
+
+func TranscoderHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.Request
+		if err := httpx.Parse(r, &req); err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+			return
+		}
+
+		l := logic.NewTranscoderLogic(r.Context(), svcCtx)
+		resp, err := l.Transcoder(&req)
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 126 - 0
internal/logic/transcoderlogic.go

@@ -0,0 +1,126 @@
+package logic
+
+import (
+	"context"
+	"errors"
+	"github.com/google/uuid"
+	"io"
+	"net/http"
+	"os"
+	"silk2audio/silk"
+	"strings"
+	"sync"
+
+	"audio_transcoder/internal/svc"
+	"audio_transcoder/internal/types"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type TranscoderLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewTranscoderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *TranscoderLogic {
+	return &TranscoderLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx,
+	}
+}
+
+func (l *TranscoderLogic) Transcoder(req *types.Request) (resp *types.Response, err error) {
+	if req.Path == "" {
+		err = errors.New("path is empty")
+		return
+	}
+	// 发起HTTP GET请求
+	resp1, err := http.Get(req.Path)
+	if err != nil {
+		logx.Errorf("下载文件失败 error:", err.Error())
+		return
+	}
+	defer resp1.Body.Close()
+	if resp1.StatusCode != http.StatusOK {
+		err = errors.New("download file failed")
+		logx.Errorf("下载文件失败 error:", resp1.StatusCode)
+		return
+	}
+	// 读取响应体内容
+	silkPath := uuid.NewString() + ".silk" // 本地保存的文件路径
+	silkFile, err := os.Create(silkPath)
+	if err != nil {
+		logx.Errorf("读取silk文件失败 error:", err.Error())
+		return
+	}
+	defer func() {
+		silkFile.Close()
+		silk.FileRemove(silkPath)
+	}()
+	_, err = io.Copy(silkFile, resp1.Body)
+	if err != nil {
+		logx.Errorf("读取文件失败 error:", err.Error())
+		return
+	}
+	// 转码
+	wavPath, pcmPath := silk.TransSilkToWav(silkPath)
+	wavFile, err := os.Open(wavPath)
+	if err != nil {
+		logx.Errorf("读取wav文件失败 error:", err.Error())
+		return
+	}
+	defer func() {
+		wavFile.Close()
+		silk.FileRemove(wavPath)
+	}()
+	pcmFile, err := os.Open(pcmPath)
+	if err != nil {
+		logx.Errorf("读取pcm文件失败 error:", err.Error())
+		return
+	}
+	defer func() {
+		pcmFile.Close()
+		silk.FileRemove(pcmPath)
+	}()
+	//多线程处理上传录音和语音识别
+	var wg sync.WaitGroup
+	wg.Add(2)
+	//构建返回数据
+	resp = &types.Response{}
+	var err1, err2 error
+	//上传录音
+	go func() {
+		defer wg.Done()
+		bts, _ := io.ReadAll(wavFile)
+		url, err := l.svcCtx.QiNiuSdk.Upload(bts, int64(len(bts)), wavPath)
+		if err != nil {
+			logx.Errorf("上传七牛云失败 error:", err.Error())
+			return
+		}
+		err1 = err
+		resp.Path = url
+	}()
+	//识别录音
+	go func() {
+		defer wg.Done()
+		bts, _ := io.ReadAll(pcmFile)
+		asrResp, err := l.svcCtx.AsrSdk.Asr(bts, "pcm", 16000)
+		if err != nil {
+			logx.Errorf("语音识别失败 error:", err.Error())
+			return
+		}
+		err2 = err
+		resp.Message = strings.Join(asrResp.Result, "\n")
+	}()
+	wg.Wait()
+	//返回数据
+	if err1 != nil {
+		return nil, err1
+	}
+	if err2 != nil {
+		return nil, err2
+	}
+	return
+}

+ 21 - 0
internal/svc/servicecontext.go

@@ -0,0 +1,21 @@
+package svc
+
+import (
+	"audio_transcoder/internal/config"
+	"audio_transcoder/pkg/baidu"
+	"audio_transcoder/pkg/oss"
+)
+
+type ServiceContext struct {
+	Config   config.Config
+	QiNiuSdk *oss.QiNiuSdk
+	AsrSdk   *baidu.AsrSdk
+}
+
+func NewServiceContext(c config.Config) *ServiceContext {
+	return &ServiceContext{
+		Config:   c,
+		QiNiuSdk: oss.NewQiNiuSdk(c.QiNiuConf.AccessKey, c.QiNiuConf.SecretKey, c.QiNiuConf.Bucket, c.QiNiuConf.HostUrl),
+		AsrSdk:   baidu.NewAsrSdk(c.BaiduAsrConf.AppID, c.BaiduAsrConf.APIKey, c.BaiduAsrConf.SecretKey),
+	}
+}

+ 11 - 0
internal/types/types.go

@@ -0,0 +1,11 @@
+// Code generated by goctl. DO NOT EDIT.
+package types
+
+type Request struct {
+	Path string `form:"path"`
+}
+
+type Response struct {
+	Path    string `json:"path"`
+	Message string `json:"message"`
+}

BIN
pkg/baidu/16k.wav


+ 118 - 0
pkg/baidu/asr.go

@@ -0,0 +1,118 @@
+package baidu
+
+import (
+	"bytes"
+	"encoding/base64"
+	"encoding/json"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"strings"
+)
+
+type AsrSdk struct {
+	appID     string
+	apiKey    string
+	secretKey string
+	token     *Token
+}
+
+func NewAsrSdk(AppID, APIKey, SecretKey string) *AsrSdk {
+	return &AsrSdk{
+		appID:     AppID,
+		apiKey:    APIKey,
+		secretKey: SecretKey,
+	}
+}
+
+func (s *AsrSdk) GetToken() (err error) {
+	url := "https://aip.baidubce.com/oauth/2.0/token?client_id=%v&client_secret=%v&grant_type=client_credentials"
+	url = fmt.Sprintf(url, s.apiKey, s.secretKey)
+	payload := strings.NewReader(``)
+	client := &http.Client{}
+	req, err := http.NewRequest("POST", url, payload)
+
+	if err != nil {
+		fmt.Println(err)
+		return
+	}
+	req.Header.Add("Content-Type", "application/json")
+	req.Header.Add("Accept", "application/json")
+
+	res, err := client.Do(req)
+	if err != nil {
+		fmt.Println(err)
+		return
+	}
+	defer res.Body.Close()
+
+	body, err := ioutil.ReadAll(res.Body)
+	if err != nil {
+		fmt.Println(err)
+		return
+	}
+	var token Token
+	err = json.Unmarshal(body, &token)
+	if err != nil {
+		fmt.Println(err)
+		return
+	}
+	s.token = &token
+	return
+}
+
+func (s *AsrSdk) RefreshToken() {
+	if s.token == nil || s.token.ExpiresIn < 60*60*24 {
+		err := s.GetToken()
+		if err != nil {
+			fmt.Println(err)
+			return
+		}
+	}
+}
+
+// Asr
+//
+//	@Description: ASR语音识别文字
+//	@receiver s
+//	@param resource
+//	@param format pcm/wav/amr/m4a
+//	@param rate 16000、8000
+//	@return d
+//	@return err
+func (s *AsrSdk) Asr(src []byte, format string, rate int) (d *AsrResp, err error) {
+	s.RefreshToken()
+	url := "http://vop.baidu.com/server_api"
+	var req AsrReq
+	req.Format = format
+	req.Rate = rate
+	req.Channel = 1
+	req.Cuid = "small_sheep_asr"
+	req.Token = s.token.AccessToken
+	req.Speech = base64.StdEncoding.EncodeToString(src)
+	req.Len = len(src)
+	bts, err := json.Marshal(req)
+	if err != nil {
+		fmt.Println(err)
+		return
+	}
+	res, err := http.Post(url, "application/json", bytes.NewBuffer(bts))
+	if err != nil {
+		fmt.Println(err)
+		return
+	}
+	defer res.Body.Close()
+
+	body, err := ioutil.ReadAll(res.Body)
+	if err != nil {
+		fmt.Println(err)
+		return
+	}
+	var resp AsrResp
+	err = json.Unmarshal(body, &resp)
+	if err != nil {
+		fmt.Println(err)
+		return
+	}
+	return &resp, nil
+}

+ 31 - 0
pkg/baidu/asr_test.go

@@ -0,0 +1,31 @@
+package baidu
+
+import (
+	"fmt"
+	"io/ioutil"
+	"os"
+	"testing"
+)
+
+func TestGetToken(t *testing.T) {
+	AppID := "25050867"
+	APIKey := "ctBGhGGm88Hudge0iBCSiF7y"
+	SecretKey := "xyNcQfVtqxZMp20dqkDAyp6eGogfFbhV"
+	sdk := NewAsrSdk(AppID, APIKey, SecretKey)
+	sdk.GetToken()
+}
+
+func TestAsr(t *testing.T) {
+	AppID := "25050867"
+	APIKey := "ctBGhGGm88Hudge0iBCSiF7y"
+	SecretKey := "xyNcQfVtqxZMp20dqkDAyp6eGogfFbhV"
+	sdk := NewAsrSdk(AppID, APIKey, SecretKey)
+	file, err := os.Open("./16k.wav")
+	if err != nil {
+		fmt.Println(err.Error())
+		return
+	}
+	all, _ := ioutil.ReadAll(file)
+	asr, err := sdk.Asr(all, "wav", 16000)
+	fmt.Println(asr, err)
+}

+ 28 - 0
pkg/baidu/model.go

@@ -0,0 +1,28 @@
+package baidu
+
+type Token struct {
+	AccessToken   string `json:"access_token"`
+	RefreshToken  string `json:"refresh_token"`
+	ExpiresIn     int    `json:"expires_in"`
+	Scope         string `json:"scope"`
+	SessionKey    string `json:"session_key"`
+	SessionSecret string `json:"session_secret"`
+}
+
+type AsrReq struct {
+	Format  string `json:"format"`  //语音文件的格式,pcm/wav/amr/m4a。不区分大小写。推荐pcm文件
+	Rate    int    `json:"rate"`    //采样率,16000、8000,固定值
+	Channel int    `json:"channel"` //声道数,仅支持单声道,请填写固定值 1
+	Cuid    string `json:"cuid"`    //用户唯一标识,用来区分用户,计算UV值。建议填写能区分用户的机器 MAC 地址或 IMEI 码,长度为60字符以内。
+	Token   string `json:"token"`   //开放平台获取到的开发者[access_token]获取 Access Token "access_token")
+	Speech  string `json:"speech"`  //本地语音文件的二进制语音数据 ,需要进行base64 编码。与len参数连一起使用。
+	Len     int    `json:"len"`     //本地语音文件的的字节数,单位字节
+}
+
+type AsrResp struct {
+	CorpusNo string   `json:"corpus_no"`
+	ErrMsg   string   `json:"err_msg"`
+	ErrNo    int      `json:"err_no"`
+	Result   []string `json:"result"` //识别结果
+	Sn       string   `json:"sn"`
+}

+ 60 - 0
pkg/oss/qiniu.go

@@ -0,0 +1,60 @@
+package oss
+
+import (
+	"bytes"
+	"context"
+	"github.com/qiniu/go-sdk/v7/auth/qbox"
+	"github.com/qiniu/go-sdk/v7/storage"
+)
+
+type QiNiuSdk struct {
+	accessKey string
+	secretKey string
+	bucket    string
+	hostUrl   string
+}
+
+func NewQiNiuSdk(AccessKey, SecretKey, Bucket, HostUrl string) *QiNiuSdk {
+	return &QiNiuSdk{
+		accessKey: AccessKey,
+		secretKey: SecretKey,
+		bucket:    Bucket,
+		hostUrl:   HostUrl,
+	}
+}
+
+func (s *QiNiuSdk) Upload(data []byte, dataLen int64, filename string) (url string, err error) {
+	var (
+		putPolicy = storage.PutPolicy{
+			Scope: s.bucket,
+		}
+		mac     = qbox.NewMac(s.accessKey, s.secretKey)
+		upToken = putPolicy.UploadToken(mac)
+		cfg     = storage.Config{}
+	)
+	// 空间对应的机房
+	cfg.Zone = &storage.ZoneHuabei
+	cfg.UseHTTPS = false
+	cfg.UseCdnDomains = false
+	var (
+		formUploader = storage.NewFormUploader(&cfg)
+		ret          = storage.PutRet{}
+		putExtra     = storage.PutExtra{}
+	)
+	if err = formUploader.Put(context.Background(), &ret, upToken, filename, bytes.NewReader(data), dataLen, &putExtra); err == nil {
+		url = s.hostUrl + "/" + ret.Key
+	}
+	return
+}
+
+func (s *QiNiuSdk) GetUpToken() (upToken, hostUrl string) {
+	var (
+		putPolicy = storage.PutPolicy{
+			Scope: s.bucket,
+		}
+		mac = qbox.NewMac(s.accessKey, s.secretKey)
+	)
+	upToken = putPolicy.UploadToken(mac)
+	hostUrl = s.hostUrl
+	return
+}

+ 16 - 0
pkg/oss/qiniu_test.go

@@ -0,0 +1,16 @@
+package oss
+
+import (
+	"fmt"
+	"testing"
+)
+
+func TestUpload(t *testing.T) {
+	AccessKey := "B81Gsvry2StqKVE3txS-7v9GBBfqykC9zhebmxnW"
+	SecretKey := "YEZJuYcdeF7vRvzffxpopAVR-jMPZg9pZ-4IKTVW"
+	Bucket := "wechatcs"
+	HostUrl := "http://cs.wechat.kfzs.com"
+	sdk := NewQiNiuSdk(AccessKey, SecretKey, Bucket, HostUrl)
+	url, err := sdk.Upload([]byte("hello world"), 11, "test.txt")
+	fmt.Printf("url:%s,err:%v", url, err)
+}

BIN
pkg/silk2audio/example/2020_08_20_12_15_38_829.silk


+ 3 - 0
pkg/silk2audio/go.mod

@@ -0,0 +1,3 @@
+module silk2audio
+
+go 1.14

+ 11 - 0
pkg/silk2audio/main.go

@@ -0,0 +1,11 @@
+package main
+
+import (
+	"fmt"
+	"silk2audio/silk"
+)
+
+func main() {
+	wav, pcm := silk.TransSilkToWav("example/2020_08_20_12_15_38_829.silk")
+	fmt.Println(wav, pcm)
+}

+ 486 - 0
pkg/silk2audio/silk/Decoder.c

@@ -0,0 +1,486 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+
+/*****************************/
+/* Silk decoder test program */
+/*****************************/
+
+#ifdef _WIN32
+#define _CRT_SECURE_NO_DEPRECATE    1
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "SKP_Silk_SDK_API.h"
+#include "SKP_Silk_SigProc_FIX.h"
+
+/* Define codec specific settings should be moved to h file */
+#define MAX_BYTES_PER_FRAME     1024
+#define MAX_INPUT_FRAMES        5
+#define MAX_FRAME_LENGTH        480
+#define FRAME_LENGTH_MS         20
+#define MAX_API_FS_KHZ          48
+#define MAX_LBRR_DELAY          2
+
+#ifdef _SYSTEM_IS_BIG_ENDIAN
+/* Function to convert a little endian int16 to a */
+/* big endian int16 or vica verca                 */
+void swap_endian(
+    SKP_int16       vec[],
+    SKP_int         len
+)
+{
+    SKP_int i;
+    SKP_int16 tmp;
+    SKP_uint8 *p1, *p2;
+
+    for( i = 0; i < len; i++ ){
+        tmp = vec[ i ];
+        p1 = (SKP_uint8 *)&vec[ i ]; p2 = (SKP_uint8 *)&tmp;
+        p1[ 0 ] = p2[ 1 ]; p1[ 1 ] = p2[ 0 ];
+    }
+}
+#endif
+
+#if (defined(_WIN32) || defined(_WINCE))
+#include <windows.h>	/* timer */
+#else    // Linux or Mac
+#include <sys/time.h>
+#endif
+
+#ifdef _WIN32
+
+unsigned long GetHighResolutionTime() /* O: time in usec*/
+{
+    /* Returns a time counter in microsec	*/
+    /* the resolution is platform dependent */
+    /* but is typically 1.62 us resolution  */
+    LARGE_INTEGER lpPerformanceCount;
+    LARGE_INTEGER lpFrequency;
+    QueryPerformanceCounter(&lpPerformanceCount);
+    QueryPerformanceFrequency(&lpFrequency);
+    return (unsigned long)((1000000*(lpPerformanceCount.QuadPart)) / lpFrequency.QuadPart);
+}
+#else    // Linux or Mac
+unsigned long GetHighResolutionTime() /* O: time in usec*/
+{
+    struct timeval tv;
+    gettimeofday(&tv, 0);
+    return((tv.tv_sec*1000000)+(tv.tv_usec));
+}
+#endif // _WIN32
+
+/* Seed for the random number generator, which is used for simulating packet loss */
+static SKP_int32 rand_seed = 1;
+
+static void print_usage(char* argv[]) {
+    printf( "\nVersion:20160922    Build By kn007 (kn007.net)");
+    printf( "\nGithub: https://github.com/kn007/silk-v3-decoder\n");
+    printf( "\nusage: %s in.bit out.pcm [settings]\n", argv[ 0 ] );
+    printf( "\nin.bit       : Bitstream input to decoder" );
+    printf( "\nout.pcm      : Speech output from decoder" );
+    printf( "\n   settings:" );
+    printf( "\n-Fs_API <Hz> : Sampling rate of output signal in Hz; default: 24000" );
+    printf( "\n-loss <perc> : Simulated packet loss percentage (0-100); default: 0" );
+    printf( "\n-quiet       : Print out just some basic values" );
+    printf( "\n" );
+}
+
+int Decoder(char* inputPath,char* outPath)
+{
+    unsigned long tottime, starttime;
+    double    filetime;
+    size_t    counter;
+    SKP_int32 args, totPackets, i, k;
+    SKP_int16 ret, len, tot_len;
+    SKP_int16 nBytes;
+    SKP_uint8 payload[    MAX_BYTES_PER_FRAME * MAX_INPUT_FRAMES * ( MAX_LBRR_DELAY + 1 ) ];
+    SKP_uint8 *payloadEnd = NULL, *payloadToDec = NULL;
+    SKP_uint8 FECpayload[ MAX_BYTES_PER_FRAME * MAX_INPUT_FRAMES ], *payloadPtr;
+    SKP_int16 nBytesFEC;
+    SKP_int16 nBytesPerPacket[ MAX_LBRR_DELAY + 1 ], totBytes;
+    SKP_int16 out[ ( ( FRAME_LENGTH_MS * MAX_API_FS_KHZ ) << 1 ) * MAX_INPUT_FRAMES ], *outPtr;
+    char      speechOutFileName[ 150 ], bitInFileName[ 150 ];
+    FILE      *bitInFile, *speechOutFile;
+    SKP_int32 packetSize_ms=0, API_Fs_Hz = 0;
+    SKP_int32 decSizeBytes;
+    void      *psDec;
+    SKP_float loss_prob;
+    SKP_int32 frames, lost, quiet;
+    SKP_SILK_SDK_DecControlStruct DecControl;
+
+//    if( argc < 3 ) {
+//        print_usage( argv );
+//        exit( 0 );
+//    }
+
+    /* default settings */
+    quiet     = 1;
+    loss_prob = 0.0f;
+
+    /* get arguments */
+    args = 1;
+    strcpy( bitInFileName,inputPath);
+    args++;
+    strcpy( speechOutFileName, outPath);
+    args++;
+//    while( args < argc ) {
+//        if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-loss" ) == 0 ) {
+//            sscanf( argv[ args + 1 ], "%f", &loss_prob );
+//            args += 2;
+//        } else if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-Fs_API" ) == 0 ) {
+//            sscanf( argv[ args + 1 ], "%d", &API_Fs_Hz );
+//            args += 2;
+//        } else if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-quiet" ) == 0 ) {
+//            quiet = 1;
+//            args++;
+//        } else {
+//            printf( "Error: unrecognized setting: %s\n\n", argv[ args ] );
+//            print_usage( argv );
+//            exit( 0 );
+//        }
+//    }
+
+    if( !quiet ) {
+        printf("********** Silk Decoder (Fixed Point) v %s ********************\n", SKP_Silk_SDK_get_version());
+        printf("********** Compiled for %d bit cpu *******************************\n", (int)sizeof(void*) * 8 );
+        printf( "Input:                       %s\n", bitInFileName );
+        printf( "Output:                      %s\n", speechOutFileName );
+    }
+
+    /* Open files */
+    bitInFile = fopen( bitInFileName, "rb" );
+    if( bitInFile == NULL ) {
+        printf( "Error: could not open input file %s\n", bitInFileName );
+        exit( 0 );
+    }
+
+    /* Check Silk header */
+    {
+        char header_buf[ 50 ];
+       counter = fread(header_buf, sizeof(char), 1, bitInFile);
+        header_buf[ strlen( "" ) ] = '\0'; /* Terminate with a null character */
+        if( strcmp( header_buf, "" ) != 0 ) {
+           counter = fread( header_buf, sizeof( char ), strlen( "!SILK_V3" ), bitInFile );
+           header_buf[ strlen( "!SILK_V3" ) ] = '\0'; /* Terminate with a null character */
+           if( strcmp( header_buf, "!SILK_V3" ) != 0 ) {
+               /* Non-equal strings */
+               printf( "Error: Wrong Header %s\n", header_buf );
+               exit( 0 );
+           }
+        } else {
+           counter = fread( header_buf, sizeof( char ), strlen( "#!SILK_V3" ), bitInFile );
+           header_buf[ strlen( "#!SILK_V3" ) ] = '\0'; /* Terminate with a null character */
+           if( strcmp( header_buf, "#!SILK_V3" ) != 0 ) {
+               /* Non-equal strings */
+               printf( "Error: Wrong Header %s\n", header_buf );
+               exit( 0 );
+           }
+        }
+    }
+
+    speechOutFile = fopen( speechOutFileName, "wb" );
+    if( speechOutFile == NULL ) {
+        printf( "Error: could not open output file %s\n", speechOutFileName );
+        exit( 0 );
+    }
+
+    /* Set the samplingrate that is requested for the output */
+    if( API_Fs_Hz == 0 ) {
+        DecControl.API_sampleRate = 24000;
+    } else {
+        DecControl.API_sampleRate = API_Fs_Hz;
+    }
+
+    /* Initialize to one frame per packet, for proper concealment before first packet arrives */
+    DecControl.framesPerPacket = 1;
+
+    /* Create decoder */
+    ret = SKP_Silk_SDK_Get_Decoder_Size( &decSizeBytes );
+    if( ret ) {
+        printf( "\nSKP_Silk_SDK_Get_Decoder_Size returned %d", ret );
+    }
+    psDec = malloc( decSizeBytes );
+
+    /* Reset decoder */
+    ret = SKP_Silk_SDK_InitDecoder( psDec );
+    if( ret ) {
+        printf( "\nSKP_Silk_InitDecoder returned %d", ret );
+    }
+
+    totPackets = 0;
+    tottime    = 0;
+    payloadEnd = payload;
+
+    /* Simulate the jitter buffer holding MAX_FEC_DELAY packets */
+    for( i = 0; i < MAX_LBRR_DELAY; i++ ) {
+        /* Read payload size */
+        counter = fread( &nBytes, sizeof( SKP_int16 ), 1, bitInFile );
+#ifdef _SYSTEM_IS_BIG_ENDIAN
+        swap_endian( &nBytes, 1 );
+#endif
+        /* Read payload */
+        counter = fread( payloadEnd, sizeof( SKP_uint8 ), nBytes, bitInFile );
+
+        if( ( SKP_int16 )counter < nBytes ) {
+            break;
+        }
+        nBytesPerPacket[ i ] = nBytes;
+        payloadEnd          += nBytes;
+        totPackets++;
+    }
+
+    while( 1 ) {
+        /* Read payload size */
+        counter = fread( &nBytes, sizeof( SKP_int16 ), 1, bitInFile );
+#ifdef _SYSTEM_IS_BIG_ENDIAN
+        swap_endian( &nBytes, 1 );
+#endif
+        if( nBytes < 0 || counter < 1 ) {
+            break;
+        }
+
+        /* Read payload */
+        counter = fread( payloadEnd, sizeof( SKP_uint8 ), nBytes, bitInFile );
+        if( ( SKP_int16 )counter < nBytes ) {
+            break;
+        }
+
+        /* Simulate losses */
+        rand_seed = SKP_RAND( rand_seed );
+        if( ( ( ( float )( ( rand_seed >> 16 ) + ( 1 << 15 ) ) ) / 65535.0f >= ( loss_prob / 100.0f ) ) && ( counter > 0 ) ) {
+            nBytesPerPacket[ MAX_LBRR_DELAY ] = nBytes;
+            payloadEnd                       += nBytes;
+        } else {
+            nBytesPerPacket[ MAX_LBRR_DELAY ] = 0;
+        }
+
+        if( nBytesPerPacket[ 0 ] == 0 ) {
+            /* Indicate lost packet */
+            lost = 1;
+
+            /* Packet loss. Search after FEC in next packets. Should be done in the jitter buffer */
+            payloadPtr = payload;
+            for( i = 0; i < MAX_LBRR_DELAY; i++ ) {
+                if( nBytesPerPacket[ i + 1 ] > 0 ) {
+                    starttime = GetHighResolutionTime();
+                    SKP_Silk_SDK_search_for_LBRR( payloadPtr, nBytesPerPacket[ i + 1 ], ( i + 1 ), FECpayload, &nBytesFEC );
+                    tottime += GetHighResolutionTime() - starttime;
+                    if( nBytesFEC > 0 ) {
+                        payloadToDec = FECpayload;
+                        nBytes = nBytesFEC;
+                        lost = 0;
+                        break;
+                    }
+                }
+                payloadPtr += nBytesPerPacket[ i + 1 ];
+            }
+        } else {
+            lost = 0;
+            nBytes = nBytesPerPacket[ 0 ];
+            payloadToDec = payload;
+        }
+
+        /* Silk decoder */
+        outPtr = out;
+        tot_len = 0;
+        starttime = GetHighResolutionTime();
+
+        if( lost == 0 ) {
+            /* No Loss: Decode all frames in the packet */
+            frames = 0;
+            do {
+                /* Decode 20 ms */
+                ret = SKP_Silk_SDK_Decode( psDec, &DecControl, 0, payloadToDec, nBytes, outPtr, &len );
+                if( ret ) {
+                    printf( "\nSKP_Silk_SDK_Decode returned %d", ret );
+                }
+
+                frames++;
+                outPtr  += len;
+                tot_len += len;
+                if( frames > MAX_INPUT_FRAMES ) {
+                    /* Hack for corrupt stream that could generate too many frames */
+                    outPtr  = out;
+                    tot_len = 0;
+                    frames  = 0;
+                }
+                /* Until last 20 ms frame of packet has been decoded */
+            } while( DecControl.moreInternalDecoderFrames );
+        } else {
+            /* Loss: Decode enough frames to cover one packet duration */
+            for( i = 0; i < DecControl.framesPerPacket; i++ ) {
+                /* Generate 20 ms */
+                ret = SKP_Silk_SDK_Decode( psDec, &DecControl, 1, payloadToDec, nBytes, outPtr, &len );
+                if( ret ) {
+                    printf( "\nSKP_Silk_Decode returned %d", ret );
+                }
+                outPtr  += len;
+                tot_len += len;
+            }
+        }
+
+        packetSize_ms = tot_len / ( DecControl.API_sampleRate / 1000 );
+        tottime += GetHighResolutionTime() - starttime;
+        totPackets++;
+
+        /* Write output to file */
+#ifdef _SYSTEM_IS_BIG_ENDIAN
+        swap_endian( out, tot_len );
+#endif
+        fwrite( out, sizeof( SKP_int16 ), tot_len, speechOutFile );
+
+        /* Update buffer */
+        totBytes = 0;
+        for( i = 0; i < MAX_LBRR_DELAY; i++ ) {
+            totBytes += nBytesPerPacket[ i + 1 ];
+        }
+        SKP_memmove( payload, &payload[ nBytesPerPacket[ 0 ] ], totBytes * sizeof( SKP_uint8 ) );
+        payloadEnd -= nBytesPerPacket[ 0 ];
+        SKP_memmove( nBytesPerPacket, &nBytesPerPacket[ 1 ], MAX_LBRR_DELAY * sizeof( SKP_int16 ) );
+
+        if( !quiet ) {
+            fprintf( stderr, "\rPackets decoded:             %d", totPackets );
+        }
+    }
+
+    /* Empty the recieve buffer */
+    for( k = 0; k < MAX_LBRR_DELAY; k++ ) {
+        if( nBytesPerPacket[ 0 ] == 0 ) {
+            /* Indicate lost packet */
+            lost = 1;
+
+            /* Packet loss. Search after FEC in next packets. Should be done in the jitter buffer */
+            payloadPtr = payload;
+            for( i = 0; i < MAX_LBRR_DELAY; i++ ) {
+                if( nBytesPerPacket[ i + 1 ] > 0 ) {
+                    starttime = GetHighResolutionTime();
+                    SKP_Silk_SDK_search_for_LBRR( payloadPtr, nBytesPerPacket[ i + 1 ], ( i + 1 ), FECpayload, &nBytesFEC );
+                    tottime += GetHighResolutionTime() - starttime;
+                    if( nBytesFEC > 0 ) {
+                        payloadToDec = FECpayload;
+                        nBytes = nBytesFEC;
+                        lost = 0;
+                        break;
+                    }
+                }
+                payloadPtr += nBytesPerPacket[ i + 1 ];
+            }
+        } else {
+            lost = 0;
+            nBytes = nBytesPerPacket[ 0 ];
+            payloadToDec = payload;
+        }
+
+        /* Silk decoder */
+        outPtr  = out;
+        tot_len = 0;
+        starttime = GetHighResolutionTime();
+
+        if( lost == 0 ) {
+            /* No loss: Decode all frames in the packet */
+            frames = 0;
+            do {
+                /* Decode 20 ms */
+                ret = SKP_Silk_SDK_Decode( psDec, &DecControl, 0, payloadToDec, nBytes, outPtr, &len );
+                if( ret ) {
+                    printf( "\nSKP_Silk_SDK_Decode returned %d", ret );
+                }
+
+                frames++;
+                outPtr  += len;
+                tot_len += len;
+                if( frames > MAX_INPUT_FRAMES ) {
+                    /* Hack for corrupt stream that could generate too many frames */
+                    outPtr  = out;
+                    tot_len = 0;
+                    frames  = 0;
+                }
+            /* Until last 20 ms frame of packet has been decoded */
+            } while( DecControl.moreInternalDecoderFrames );
+        } else {
+            /* Loss: Decode enough frames to cover one packet duration */
+
+            /* Generate 20 ms */
+            for( i = 0; i < DecControl.framesPerPacket; i++ ) {
+                ret = SKP_Silk_SDK_Decode( psDec, &DecControl, 1, payloadToDec, nBytes, outPtr, &len );
+                if( ret ) {
+                    printf( "\nSKP_Silk_Decode returned %d", ret );
+                }
+                outPtr  += len;
+                tot_len += len;
+            }
+        }
+
+        packetSize_ms = tot_len / ( DecControl.API_sampleRate / 1000 );
+        tottime += GetHighResolutionTime() - starttime;
+        totPackets++;
+
+        /* Write output to file */
+#ifdef _SYSTEM_IS_BIG_ENDIAN
+        swap_endian( out, tot_len );
+#endif
+        fwrite( out, sizeof( SKP_int16 ), tot_len, speechOutFile );
+
+        /* Update Buffer */
+        totBytes = 0;
+        for( i = 0; i < MAX_LBRR_DELAY; i++ ) {
+            totBytes += nBytesPerPacket[ i + 1 ];
+        }
+        SKP_memmove( payload, &payload[ nBytesPerPacket[ 0 ] ], totBytes * sizeof( SKP_uint8 ) );
+        payloadEnd -= nBytesPerPacket[ 0 ];
+        SKP_memmove( nBytesPerPacket, &nBytesPerPacket[ 1 ], MAX_LBRR_DELAY * sizeof( SKP_int16 ) );
+
+        if( !quiet ) {
+            fprintf( stderr, "\rPackets decoded:              %d", totPackets );
+        }
+    }
+
+    if( !quiet ) {
+        printf( "\nDecoding Finished \n" );
+    }
+
+    /* Free decoder */
+    free( psDec );
+
+    /* Close files */
+    fclose( speechOutFile );
+    fclose( bitInFile );
+
+    filetime = totPackets * 1e-3 * packetSize_ms;
+    if( !quiet ) {
+        printf("\nFile length:                 %.3f s", filetime);
+        printf("\nTime for decoding:           %.3f s (%.3f%% of realtime)", 1e-6 * tottime, 1e-4 * tottime / filetime);
+        printf("\n\n");
+    } else {
+        /* print time and % of realtime */
+        printf( "%.3f %.3f %d\n", 1e-6 * tottime, 1e-4 * tottime / filetime, totPackets );
+    }
+    return 0;
+}

+ 5 - 0
pkg/silk2audio/silk/Decoder.h

@@ -0,0 +1,5 @@
+#ifndef HELLO_H
+#define HELLO_H
+
+int Decoder(char* inputPath,char* outPath);
+#endif

+ 278 - 0
pkg/silk2audio/silk/SKP_Silk_Inlines.h

@@ -0,0 +1,278 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved. 
+Redistribution and use in source and binary forms, with or without 
+modification, (subject to the limitations in the disclaimer below) 
+are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright 
+notice, this list of conditions and the following disclaimer in the 
+documentation and/or other materials provided with the distribution.
+- Neither the name of Skype Limited, nor the names of specific 
+contributors, may be used to endorse or promote products derived from 
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED 
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+/*! \file SKP_Silk_Inlines.h
+ *  \brief SKP_Silk_Inlines.h defines inline signal processing functions.
+ */
+
+#ifndef _SKP_SILK_FIX_INLINES_H_
+#define _SKP_SILK_FIX_INLINES_H_
+
+#include <assert.h>
+
+#ifdef  __cplusplus
+extern "C"
+{
+#endif
+
+/* count leading zeros of SKP_int64 */
+SKP_INLINE SKP_int32 SKP_Silk_CLZ64(SKP_int64 in)
+{
+    SKP_int32 in_upper;
+
+    in_upper = (SKP_int32)SKP_RSHIFT64(in, 32);
+    if (in_upper == 0) {
+        /* Search in the lower 32 bits */
+        return 32 + SKP_Silk_CLZ32( (SKP_int32) in );
+    } else {
+        /* Search in the upper 32 bits */
+        return SKP_Silk_CLZ32( in_upper );
+    }
+}
+
+/* get number of leading zeros and fractional part (the bits right after the leading one */
+SKP_INLINE void SKP_Silk_CLZ_FRAC(SKP_int32 in,            /* I: input */
+                                    SKP_int32 *lz,           /* O: number of leading zeros */
+                                    SKP_int32 *frac_Q7)      /* O: the 7 bits right after the leading one */
+{
+    SKP_int32 lzeros = SKP_Silk_CLZ32(in);
+
+    * lz = lzeros;
+    * frac_Q7 = SKP_ROR32(in, 24 - lzeros) & 0x7f;
+}
+
+/* Approximation of square root                                          */
+/* Accuracy: < +/- 10%  for output values > 15                           */
+/*           < +/- 2.5% for output values > 120                          */
+SKP_INLINE SKP_int32 SKP_Silk_SQRT_APPROX(SKP_int32 x)
+{
+    SKP_int32 y, lz, frac_Q7;
+
+    if( x <= 0 ) {
+        return 0;
+    }
+
+    SKP_Silk_CLZ_FRAC(x, &lz, &frac_Q7);
+
+    if( lz & 1 ) {
+        y = 32768;
+    } else {
+        y = 46214;        /* 46214 = sqrt(2) * 32768 */
+    }
+
+    /* get scaling right */
+    y >>= SKP_RSHIFT(lz, 1);
+
+    /* increment using fractional part of input */
+    y = SKP_SMLAWB(y, y, SKP_SMULBB(213, frac_Q7));
+
+    return y;
+}
+
+/* returns the number of left shifts before overflow for a 16 bit number (ITU definition with norm(0)=0) */
+SKP_INLINE SKP_int32 SKP_Silk_norm16(SKP_int16 a) {
+
+  SKP_int32 a32;
+
+  /* if ((a == 0) || (a == SKP_int16_MIN)) return(0); */
+  if ((a << 1) == 0) return(0);
+
+  a32 = a;
+  /* if (a32 < 0) a32 = -a32 - 1; */
+  a32 ^= SKP_RSHIFT(a32, 31);
+
+  return SKP_Silk_CLZ32(a32) - 17;
+}
+
+/* returns the number of left shifts before overflow for a 32 bit number (ITU definition with norm(0)=0) */
+SKP_INLINE SKP_int32 SKP_Silk_norm32(SKP_int32 a) {
+  
+  /* if ((a == 0) || (a == SKP_int32_MIN)) return(0); */
+  if ((a << 1) == 0) return(0);
+
+  /* if (a < 0) a = -a - 1; */
+  a ^= SKP_RSHIFT(a, 31);
+
+  return SKP_Silk_CLZ32(a) - 1;
+}
+
+/* Divide two int32 values and return result as int32 in a given Q-domain */
+SKP_INLINE SKP_int32 SKP_DIV32_varQ(    /* O    returns a good approximation of "(a32 << Qres) / b32" */
+    const SKP_int32     a32,            /* I    numerator (Q0)                  */
+    const SKP_int32     b32,            /* I    denominator (Q0)                */
+    const SKP_int       Qres            /* I    Q-domain of result (>= 0)       */
+)
+{
+    SKP_int   a_headrm, b_headrm, lshift;
+    SKP_int32 b32_inv, a32_nrm, b32_nrm, result;
+
+    SKP_assert( b32 != 0 );
+    SKP_assert( Qres >= 0 );
+
+    /* Compute number of bits head room and normalize inputs */
+    a_headrm = SKP_Silk_CLZ32( SKP_abs(a32) ) - 1;
+    a32_nrm = SKP_LSHIFT(a32, a_headrm);                                    /* Q: a_headrm                    */
+    b_headrm = SKP_Silk_CLZ32( SKP_abs(b32) ) - 1;
+    b32_nrm = SKP_LSHIFT(b32, b_headrm);                                    /* Q: b_headrm                    */
+
+    /* Inverse of b32, with 14 bits of precision */
+    b32_inv = SKP_DIV32_16( SKP_int32_MAX >> 2, SKP_RSHIFT(b32_nrm, 16) );  /* Q: 29 + 16 - b_headrm        */
+
+    /* First approximation */
+    result = SKP_SMULWB(a32_nrm, b32_inv);                                  /* Q: 29 + a_headrm - b_headrm    */
+
+    /* Compute residual by subtracting product of denominator and first approximation */
+    a32_nrm -= SKP_LSHIFT_ovflw( SKP_SMMUL(b32_nrm, result), 3 );           /* Q: a_headrm                    */
+
+    /* Refinement */
+    result = SKP_SMLAWB(result, a32_nrm, b32_inv);                          /* Q: 29 + a_headrm - b_headrm    */
+
+    /* Convert to Qres domain */
+    lshift = 29 + a_headrm - b_headrm - Qres;
+    if( lshift <= 0 ) {
+        return SKP_LSHIFT_SAT32(result, -lshift);
+    } else {
+        if( lshift < 32){
+            return SKP_RSHIFT(result, lshift);
+        } else {
+            /* Avoid undefined result */
+            return 0;
+        }
+    }
+}
+
+/* Invert int32 value and return result as int32 in a given Q-domain */
+SKP_INLINE SKP_int32 SKP_INVERSE32_varQ(    /* O    returns a good approximation of "(1 << Qres) / b32" */
+    const SKP_int32     b32,                /* I    denominator (Q0)                */
+    const SKP_int       Qres                /* I    Q-domain of result (> 0)        */
+)
+{
+    SKP_int   b_headrm, lshift;
+    SKP_int32 b32_inv, b32_nrm, err_Q32, result;
+
+    SKP_assert( b32 != 0 );
+    SKP_assert( b32 != SKP_int32_MIN ); /* SKP_int32_MIN is not handled by SKP_abs */
+    SKP_assert( Qres > 0 );
+
+    /* Compute number of bits head room and normalize input */
+    b_headrm = SKP_Silk_CLZ32( SKP_abs(b32) ) - 1;
+    b32_nrm = SKP_LSHIFT(b32, b_headrm);                                    /* Q: b_headrm                */
+
+    /* Inverse of b32, with 14 bits of precision */
+    b32_inv = SKP_DIV32_16( SKP_int32_MAX >> 2, SKP_RSHIFT(b32_nrm, 16) );  /* Q: 29 + 16 - b_headrm    */
+
+    /* First approximation */
+    result = SKP_LSHIFT(b32_inv, 16);                                       /* Q: 61 - b_headrm            */
+
+    /* Compute residual by subtracting product of denominator and first approximation from one */
+    err_Q32 = SKP_LSHIFT_ovflw( -SKP_SMULWB(b32_nrm, b32_inv), 3 );         /* Q32                        */
+
+    /* Refinement */
+    result = SKP_SMLAWW(result, err_Q32, b32_inv);                          /* Q: 61 - b_headrm            */
+
+    /* Convert to Qres domain */
+    lshift = 61 - b_headrm - Qres;
+    if( lshift <= 0 ) {
+        return SKP_LSHIFT_SAT32(result, -lshift);
+    } else {
+        if( lshift < 32){
+            return SKP_RSHIFT(result, lshift);
+        }else{
+            /* Avoid undefined result */
+            return 0;
+        }
+    }
+}
+
+#define SKP_SIN_APPROX_CONST0       (1073735400)
+#define SKP_SIN_APPROX_CONST1        (-82778932)
+#define SKP_SIN_APPROX_CONST2          (1059577)
+#define SKP_SIN_APPROX_CONST3            (-5013)
+
+/* Sine approximation; an input of 65536 corresponds to 2 * pi */
+/* Uses polynomial expansion of the input to the power 0, 2, 4 and 6 */
+/* The relative error is below 1e-5 */
+SKP_INLINE SKP_int32 SKP_Silk_SIN_APPROX_Q24(        /* O    returns approximately 2^24 * sin(x * 2 * pi / 65536) */
+    SKP_int32        x
+)
+{
+    SKP_int y_Q30;
+
+    /* Keep only bottom 16 bits (the function repeats itself with period 65536) */
+    x &= 65535;
+
+    /* Split range in four quadrants */
+    if( x <= 32768 ) {
+        if( x < 16384 ) {
+            /* Return cos(pi/2 - x) */
+            x = 16384 - x;
+        } else {
+            /* Return cos(x - pi/2) */
+            x -= 16384;
+        }
+        if( x < 1100 ) {
+            /* Special case: high accuracy */
+            return SKP_SMLAWB( 1 << 24, SKP_MUL( x, x ), -5053 );
+        }
+        x = SKP_SMULWB( SKP_LSHIFT( x, 8 ), x );        /* contains x^2 in Q20 */
+        y_Q30 = SKP_SMLAWB( SKP_SIN_APPROX_CONST2, x, SKP_SIN_APPROX_CONST3 );
+        y_Q30 = SKP_SMLAWW( SKP_SIN_APPROX_CONST1, x, y_Q30 );
+        y_Q30 = SKP_SMLAWW( SKP_SIN_APPROX_CONST0 + 66, x, y_Q30 );
+    } else {
+        if( x < 49152 ) {
+            /* Return -cos(3*pi/2 - x) */
+            x = 49152 - x;
+        } else {
+            /* Return -cos(x - 3*pi/2) */
+            x -= 49152;
+        }
+        if( x < 1100 ) {
+            /* Special case: high accuracy */
+            return SKP_SMLAWB( -1 << 24, SKP_MUL( x, x ), 5053 );
+        }
+        x = SKP_SMULWB( SKP_LSHIFT( x, 8 ), x );        /* contains x^2 in Q20 */
+        y_Q30 = SKP_SMLAWB( -SKP_SIN_APPROX_CONST2, x, -SKP_SIN_APPROX_CONST3 );
+        y_Q30 = SKP_SMLAWW( -SKP_SIN_APPROX_CONST1, x, y_Q30 );
+        y_Q30 = SKP_SMLAWW( -SKP_SIN_APPROX_CONST0, x, y_Q30 );
+    }
+    return SKP_RSHIFT_ROUND( y_Q30, 6 );
+}
+
+/* Cosine approximation; an input of 65536 corresponds to 2 * pi */
+/* The relative error is below 1e-5 */
+SKP_INLINE SKP_int32 SKP_Silk_COS_APPROX_Q24(        /* O    returns approximately 2^24 * cos(x * 2 * pi / 65536) */
+    SKP_int32        x
+)
+{
+    return SKP_Silk_SIN_APPROX_Q24( x + 16384 );
+}
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /*_SKP_SILK_FIX_INLINES_H_*/

+ 152 - 0
pkg/silk2audio/silk/SKP_Silk_SDK_API.h

@@ -0,0 +1,152 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved. 
+Redistribution and use in source and binary forms, with or without 
+modification, (subject to the limitations in the disclaimer below) 
+are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright 
+notice, this list of conditions and the following disclaimer in the 
+documentation and/or other materials provided with the distribution.
+- Neither the name of Skype Limited, nor the names of specific 
+contributors, may be used to endorse or promote products derived from 
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED 
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+#ifndef SKP_SILK_SDK_API_H
+#define SKP_SILK_SDK_API_H
+
+#include "SKP_Silk_control.h"
+#include "SKP_Silk_typedef.h"
+#include "SKP_Silk_errors.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define SILK_MAX_FRAMES_PER_PACKET  5
+
+/* Struct for TOC (Table of Contents) */
+typedef struct {
+    SKP_int     framesInPacket;                             /* Number of 20 ms frames in packet     */
+    SKP_int     fs_kHz;                                     /* Sampling frequency in packet         */
+    SKP_int     inbandLBRR;                                 /* Does packet contain LBRR information */
+    SKP_int     corrupt;                                    /* Packet is corrupt                    */
+    SKP_int     vadFlags[     SILK_MAX_FRAMES_PER_PACKET ]; /* VAD flag for each frame in packet    */
+    SKP_int     sigtypeFlags[ SILK_MAX_FRAMES_PER_PACKET ]; /* Signal type for each frame in packet */
+} SKP_Silk_TOC_struct;
+
+/****************************************/
+/* Encoder functions                    */
+/****************************************/
+
+/***********************************************/
+/* Get size in bytes of the Silk encoder state */
+/***********************************************/
+SKP_int SKP_Silk_SDK_Get_Encoder_Size( 
+    SKP_int32                           *encSizeBytes   /* O:   Number of bytes in SILK encoder state           */
+);
+
+/*************************/
+/* Init or reset encoder */
+/*************************/
+SKP_int SKP_Silk_SDK_InitEncoder(
+    void                                *encState,      /* I/O: State                                           */
+    SKP_SILK_SDK_EncControlStruct       *encStatus      /* O:   Encoder Status                                  */
+);
+
+/***************************************/
+/* Read control structure from encoder */
+/***************************************/
+SKP_int SKP_Silk_SDK_QueryEncoder(
+    const void                          *encState,      /* I:   State                                           */
+    SKP_SILK_SDK_EncControlStruct       *encStatus      /* O:   Encoder Status                                  */
+);
+
+/**************************/
+/* Encode frame with Silk */
+/**************************/
+SKP_int SKP_Silk_SDK_Encode( 
+    void                                *encState,      /* I/O: State                                           */
+    const SKP_SILK_SDK_EncControlStruct *encControl,    /* I:   Control status                                  */
+    const SKP_int16                     *samplesIn,     /* I:   Speech sample input vector                      */
+    SKP_int                             nSamplesIn,     /* I:   Number of samples in input vector               */
+    SKP_uint8                           *outData,       /* O:   Encoded output vector                           */
+    SKP_int16                           *nBytesOut      /* I/O: Number of bytes in outData (input: Max bytes)   */
+);
+
+/****************************************/
+/* Decoder functions                    */
+/****************************************/
+
+/***********************************************/
+/* Get size in bytes of the Silk decoder state */
+/***********************************************/
+SKP_int SKP_Silk_SDK_Get_Decoder_Size( 
+    SKP_int32                           *decSizeBytes   /* O:   Number of bytes in SILK decoder state           */
+);
+
+/*************************/
+/* Init or Reset decoder */
+/*************************/
+SKP_int SKP_Silk_SDK_InitDecoder( 
+    void                                *decState       /* I/O: State                                           */
+);
+
+/******************/
+/* Decode a frame */
+/******************/
+SKP_int SKP_Silk_SDK_Decode(
+    void*                               decState,       /* I/O: State                                           */
+    SKP_SILK_SDK_DecControlStruct*      decControl,     /* I/O: Control Structure                               */
+    SKP_int                             lostFlag,       /* I:   0: no loss, 1 loss                              */
+    const SKP_uint8                     *inData,        /* I:   Encoded input vector                            */
+    const SKP_int                       nBytesIn,       /* I:   Number of input bytes                           */
+    SKP_int16                           *samplesOut,    /* O:   Decoded output speech vector                    */
+    SKP_int16                           *nSamplesOut    /* I/O: Number of samples (vector/decoded)              */
+);
+
+/***************************************************************/
+/* Find Low Bit Rate Redundancy (LBRR) information in a packet */
+/***************************************************************/
+void SKP_Silk_SDK_search_for_LBRR(
+    const SKP_uint8                     *inData,        /* I:   Encoded input vector                            */
+    const SKP_int                       nBytesIn,       /* I:   Number of input Bytes                           */
+    SKP_int                             lost_offset,    /* I:   Offset from lost packet                         */
+    SKP_uint8                           *LBRRData,      /* O:   LBRR payload                                    */
+    SKP_int16                           *nLBRRBytes     /* O:   Number of LBRR Bytes                            */
+);
+
+/**************************************/
+/* Get table of contents for a packet */
+/**************************************/
+void SKP_Silk_SDK_get_TOC(
+    const SKP_uint8                     *inData,        /* I:   Encoded input vector                            */
+    const SKP_int                       nBytesIn,       /* I:   Number of input bytes                           */
+    SKP_Silk_TOC_struct                 *Silk_TOC       /* O:   Table of contents                               */
+);
+
+/**************************/
+/* Get the version number */
+/**************************/
+/* Return a pointer to string specifying the version */ 
+const char *SKP_Silk_SDK_get_version();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 662 - 0
pkg/silk2audio/silk/SKP_Silk_SigProc_FIX.h

@@ -0,0 +1,662 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved. 
+Redistribution and use in source and binary forms, with or without 
+modification, (subject to the limitations in the disclaimer below) 
+are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright 
+notice, this list of conditions and the following disclaimer in the 
+documentation and/or other materials provided with the distribution.
+- Neither the name of Skype Limited, nor the names of specific 
+contributors, may be used to endorse or promote products derived from 
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED 
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+#ifndef _SKP_SILK_SIGPROC_FIX_H_
+#define _SKP_SILK_SIGPROC_FIX_H_
+
+#ifdef  __cplusplus
+extern "C"
+{
+#endif
+
+#define SKP_Silk_MAX_ORDER_LPC            16                    /* max order of the LPC analysis in schur() and k2a()    */
+#define SKP_Silk_MAX_CORRELATION_LENGTH   640                   /* max input length to the correlation                    */
+#include "SKP_Silk_typedef.h"
+#include <string.h>
+#include <stdlib.h>                                            /* for abs() */
+#include "SKP_Silk_resampler_structs.h"
+
+#ifndef NO_ASM
+#	if defined (__ARM_ARCH_4__) || defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_5__) || defined (__ARM_ARCH_5T__)
+#		define EMBEDDED_ARM 4
+#		define EMBEDDED_ARMv4
+#		include "SKP_Silk_macros_arm.h"
+#	elif defined (__ARM_ARCH_5TE__) || defined (__ARM_ARCH_5TEJ__)
+#		define EMBEDDED_ARM 5
+#		define EMBEDDED_ARMv5
+#		include "SKP_Silk_macros_arm.h"	
+#	elif defined (__ARM_ARCH_6__) ||defined (__ARM_ARCH_6J__) || defined (__ARM_ARCH_6Z__) || defined (__ARM_ARCH_6K__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__)
+#		define EMBEDDED_ARM 6
+#		define EMBEDDED_ARMv6
+#		include "SKP_Silk_macros_arm.h"
+#	elif defined (__ARM_ARCH_7A__) && defined (__ARM_NEON__)
+#		define EMBEDDED_ARM 7
+#		define EMBEDDED_ARMv6
+#		include "SKP_Silk_macros_arm.h"
+#	elif defined (__ARM_ARCH_7A__)
+#		define EMBEDDED_ARM 6
+#		define EMBEDDED_ARMv6
+#		include "SKP_Silk_macros_arm.h"
+#	else
+#		include "SKP_Silk_macros.h"
+#	endif
+#else
+#	include "SKP_Silk_macros.h"
+#endif
+
+
+
+/********************************************************************/
+/*                    SIGNAL PROCESSING FUNCTIONS                   */
+/********************************************************************/
+
+/*!
+ * Initialize/reset the resampler state for a given pair of input/output sampling rates 
+*/
+SKP_int SKP_Silk_resampler_init( 
+	SKP_Silk_resampler_state_struct	*S,		    /* I/O: Resampler state 			*/
+	SKP_int32							Fs_Hz_in,	/* I:	Input sampling rate (Hz)	*/
+	SKP_int32							Fs_Hz_out	/* I:	Output sampling rate (Hz)	*/
+);
+
+
+/*!
+ * Clear the states of all resampling filters, without resetting sampling rate ratio 
+ */
+SKP_int SKP_Silk_resampler_clear( 
+	SKP_Silk_resampler_state_struct	*S		    /* I/O: Resampler state 			*/
+);
+
+/*!
+ * Resampler: convert from one sampling rate to another
+ */
+SKP_int SKP_Silk_resampler( 
+	SKP_Silk_resampler_state_struct	*S,		    /* I/O: Resampler state 			*/
+	SKP_int16							out[],	    /* O:	Output signal 				*/
+	const SKP_int16						in[],	    /* I:	Input signal				*/
+	SKP_int32							inLen	    /* I:	Number of input samples		*/
+);
+
+/*!
+ Upsample 2x, low quality 
+ */
+void SKP_Silk_resampler_up2(
+    SKP_int32                           *S,         /* I/O: State vector [ 2 ]                  */
+    SKP_int16                           *out,       /* O:   Output signal [ 2 * len ]           */
+    const SKP_int16                     *in,        /* I:   Input signal [ len ]                */
+    SKP_int32                           len         /* I:   Number of input samples             */
+);
+
+/*!
+* Downsample 2x, mediocre quality 
+*/
+void SKP_Silk_resampler_down2(
+    SKP_int32                           *S,         /* I/O: State vector [ 2 ]                  */
+    SKP_int16                           *out,       /* O:   Output signal [ len ]               */
+    const SKP_int16                     *in,        /* I:   Input signal [ floor(len/2) ]       */
+    SKP_int32                           inLen       /* I:   Number of input samples             */
+);
+
+
+/*!
+ * Downsample by a factor 2/3, low quality
+*/
+void SKP_Silk_resampler_down2_3(
+    SKP_int32                           *S,         /* I/O: State vector [ 6 ]                  */
+    SKP_int16                           *out,       /* O:   Output signal [ floor(2*inLen/3) ]  */
+    const SKP_int16                     *in,        /* I:   Input signal [ inLen ]              */
+    SKP_int32                           inLen       /* I:   Number of input samples             */
+);
+
+/*!
+ * Downsample by a factor 3, low quality
+*/
+void SKP_Silk_resampler_down3(
+    SKP_int32                           *S,         /* I/O: State vector [ 8 ]                  */
+    SKP_int16                           *out,       /* O:   Output signal [ floor(inLen/3) ]    */
+    const SKP_int16                     *in,        /* I:   Input signal [ inLen ]              */
+    SKP_int32                           inLen       /* I:   Number of input samples             */
+);
+
+/*! 
+ * second order ARMA filter
+ * can handle (slowly) varying coefficients 
+ */
+void SKP_Silk_biquad(
+    const SKP_int16      *in,          /* I:   input signal                */
+    const SKP_int16      *B,           /* I:   MA coefficients, Q13 [3]    */
+    const SKP_int16      *A,           /* I:   AR coefficients, Q13 [2]    */
+          SKP_int32      *S,           /* I/O: state vector [2]            */
+          SKP_int16      *out,         /* O:   output signal               */
+    const SKP_int32      len           /* I:   signal length               */
+);
+/*!
+ * Second order ARMA filter; 
+ * slower than biquad() but uses more precise coefficients
+ * can handle (slowly) varying coefficients 
+ */
+void SKP_Silk_biquad_alt(
+    const SKP_int16     *in,           /* I:    Input signal                 */
+    const SKP_int32     *B_Q28,        /* I:    MA coefficients [3]          */
+    const SKP_int32     *A_Q28,        /* I:    AR coefficients [2]          */
+    SKP_int32           *S,            /* I/O:  State vector [2]             */
+    SKP_int16           *out,          /* O:    Output signal                */
+    const SKP_int32     len            /* I:    Signal length (must be even) */
+);
+
+/*! 
+ * variable order MA filter. Prediction error filter implementation. Coeficients negated and starting with coef to x[n - 1]
+ */
+void SKP_Silk_MA_Prediction(
+    const SKP_int16      *in,          /* I:   Input signal                                */
+    const SKP_int16      *B,           /* I:   MA prediction coefficients, Q12 [order]     */
+    SKP_int32            *S,           /* I/O: State vector [order]                        */
+    SKP_int16            *out,         /* O:   Output signal                               */
+    const SKP_int32      len,          /* I:   Signal length                               */
+    const SKP_int32      order         /* I:   Filter order                                */
+);
+
+/*!
+ * 16th order AR filter for LPC synthesis, coefficients are in Q12
+ */
+void SKP_Silk_LPC_synthesis_order16(
+    const SKP_int16      *in,          /* I:   excitation signal                            */
+    const SKP_int16      *A_Q12,       /* I:   AR coefficients [16], between -8_Q0 and 8_Q0 */
+    const SKP_int32      Gain_Q26,     /* I:   gain                                         */
+          SKP_int32      *S,           /* I/O: state vector [16]                            */
+          SKP_int16      *out,         /* O:   output signal                                */
+    const SKP_int32      len           /* I:   signal length, must be multiple of 16        */
+);
+
+/* variable order MA prediction error filter. */
+/* Inverse filter of SKP_Silk_LPC_synthesis_filter */
+void SKP_Silk_LPC_analysis_filter(
+    const SKP_int16      *in,          /* I:   Input signal                                */
+    const SKP_int16      *B,           /* I:   MA prediction coefficients, Q12 [order]     */
+    SKP_int16            *S,           /* I/O: State vector [order]                        */
+    SKP_int16            *out,         /* O:   Output signal                               */
+    const SKP_int32      len,          /* I:   Signal length                               */
+    const SKP_int32      Order         /* I:   Filter order                                */
+);
+
+/* even order AR filter */
+void SKP_Silk_LPC_synthesis_filter(
+    const SKP_int16      *in,          /* I:   excitation signal                               */
+    const SKP_int16      *A_Q12,       /* I:   AR coefficients [Order], between -8_Q0 and 8_Q0 */
+    const SKP_int32      Gain_Q26,     /* I:   gain                                            */
+    SKP_int32            *S,           /* I/O: state vector [Order]                            */
+    SKP_int16            *out,         /* O:   output signal                                   */
+    const SKP_int32      len,          /* I:   signal length                                   */
+    const SKP_int        Order         /* I:   filter order, must be even                      */
+);
+
+/* Chirp (bandwidth expand) LP AR filter */
+void SKP_Silk_bwexpander( 
+    SKP_int16            *ar,          /* I/O  AR filter to be expanded (without leading 1)    */
+    const SKP_int        d,            /* I    Length of ar                                    */
+    SKP_int32            chirp_Q16     /* I    Chirp factor (typically in the range 0 to 1)    */
+);
+
+/* Chirp (bandwidth expand) LP AR filter */
+void SKP_Silk_bwexpander_32( 
+    SKP_int32            *ar,          /* I/O  AR filter to be expanded (without leading 1)    */
+    const SKP_int        d,            /* I    Length of ar                                    */
+    SKP_int32            chirp_Q16     /* I    Chirp factor in Q16                             */
+);
+
+/* Compute inverse of LPC prediction gain, and                           */
+/* test if LPC coefficients are stable (all poles within unit circle)    */
+SKP_int SKP_Silk_LPC_inverse_pred_gain( /* O:  Returns 1 if unstable, otherwise 0          */
+    SKP_int32            *invGain_Q30,  /* O:  Inverse prediction gain, Q30 energy domain  */
+    const SKP_int16      *A_Q12,        /* I:  Prediction coefficients, Q12 [order]        */
+    const SKP_int        order          /* I:  Prediction order                            */
+);
+
+SKP_int SKP_Silk_LPC_inverse_pred_gain_Q24( /* O:   Returns 1 if unstable, otherwise 0      */
+    SKP_int32           *invGain_Q30,   /* O:   Inverse prediction gain, Q30 energy domain  */
+    const SKP_int32     *A_Q24,         /* I:   Prediction coefficients, Q24 [order]        */
+    const SKP_int       order           /* I:   Prediction order                            */
+);
+
+/* split signal in two decimated bands using first-order allpass filters */
+void SKP_Silk_ana_filt_bank_1(
+    const SKP_int16      *in,           /* I:   Input signal [N]        */
+    SKP_int32            *S,            /* I/O: State vector [2]        */
+    SKP_int16            *outL,         /* O:   Low band [N/2]          */
+    SKP_int16            *outH,         /* O:   High band [N/2]         */
+    SKP_int32            *scratch,      /* I:   Scratch memory [3*N/2]  */
+    const SKP_int32      N              /* I:   Number of input samples */
+);
+
+/********************************************************************/
+/*                        SCALAR FUNCTIONS                          */
+/********************************************************************/
+
+/* Approximation of 128 * log2() (very close inverse of approx 2^() below) */
+/* Convert input to a log scale    */
+SKP_int32 SKP_Silk_lin2log(const SKP_int32 inLin);        /* I: Input in linear scale        */
+
+/* Approximation of a sigmoid function */
+SKP_int SKP_Silk_sigm_Q15(SKP_int in_Q5);
+
+/* approximation of 2^() (exact inverse of approx log2() above) */
+/* convert input to a linear scale    */ 
+SKP_int32 SKP_Silk_log2lin(const SKP_int32 inLog_Q7);    /* I: input on log scale */ 
+
+/* Function that returns the maximum absolut value of the input vector */
+SKP_int16 SKP_Silk_int16_array_maxabs(  /* O   Maximum absolute value, max: 2^15-1   */
+    const SKP_int16     *vec,           /* I   Input vector  [len]                   */ 
+    const SKP_int32     len             /* I   Length of input vector                */
+);
+
+/* Compute number of bits to right shift the sum of squares of a vector    */
+/* of int16s to make it fit in an int32                                    */
+void SKP_Silk_sum_sqr_shift(
+    SKP_int32           *energy,        /* O   Energy of x, after shifting to the right            */
+    SKP_int             *shift,         /* O   Number of bits right shift applied to energy        */
+    const SKP_int16     *x,             /* I   Input vector                                        */
+    SKP_int             len             /* I   Length of input vector                              */
+);
+
+/* Calculates the reflection coefficients from the correlation sequence    */
+/* Faster than schur64(), but much less accurate.                          */
+/* Uses SMLAWB(), requiring armv5E and higher.                             */ 
+SKP_int32 SKP_Silk_schur(               /* O:    Returns residual energy                   */
+    SKP_int16            *rc_Q15,       /* O:    reflection coefficients [order] Q15       */
+    const SKP_int32      *c,            /* I:    correlations [order+1]                    */
+    const SKP_int32      order          /* I:    prediction order                          */
+);
+
+/* Calculates the reflection coefficients from the correlation sequence    */
+/* Slower than schur(), but more accurate.                                 */
+/* Uses SMULL(), available on armv4                                        */
+SKP_int32 SKP_Silk_schur64(             /* O:  returns residual energy                     */
+    SKP_int32           rc_Q16[],       /* O:  Reflection coefficients [order] Q16         */
+    const SKP_int32     c[],            /* I:  Correlations [order+1]                      */
+    SKP_int32           order           /* I:  Prediction order                            */
+);
+
+/* Step up function, converts reflection coefficients to prediction coefficients */
+void SKP_Silk_k2a(
+    SKP_int32           *A_Q24,         /* O:  Prediction coefficients [order] Q24         */
+    const SKP_int16     *rc_Q15,        /* I:  Reflection coefficients [order] Q15         */
+    const SKP_int32     order           /* I:  Prediction order                            */
+);
+
+/* Step up function, converts reflection coefficients to prediction coefficients */
+void SKP_Silk_k2a_Q16(
+    SKP_int32           *A_Q24,         /* O:  Prediction coefficients [order] Q24         */
+    const SKP_int32     *rc_Q16,        /* I:  Reflection coefficients [order] Q16         */
+    const SKP_int32     order           /* I:  Prediction order                            */
+);
+
+/* Apply sine window to signal vector.                                      */
+/* Window types:                                                            */
+/*    1 -> sine window from 0 to pi/2                                       */
+/*    2 -> sine window from pi/2 to pi                                      */
+/* Every other sample is linearly interpolated, for speed.                  */
+void SKP_Silk_apply_sine_window(
+    SKP_int16                        px_win[],            /* O    Pointer to windowed signal                  */
+    const SKP_int16                  px[],                /* I    Pointer to input signal                     */
+    const SKP_int                    win_type,            /* I    Selects a window type                       */
+    const SKP_int                    length               /* I    Window length, multiple of 4                */
+);
+
+/* Compute autocorrelation */
+void SKP_Silk_autocorr( 
+    SKP_int32           *results,       /* O  Result (length correlationCount)            */
+    SKP_int             *scale,         /* O  Scaling of the correlation vector           */
+    const SKP_int16     *inputData,     /* I  Input data to correlate                     */
+    const SKP_int       inputDataSize,  /* I  Length of input                             */
+    const SKP_int       correlationCount /* I  Number of correlation taps to compute      */
+);
+
+/* Pitch estimator */
+#define SKP_Silk_PITCH_EST_MIN_COMPLEX        0
+#define SKP_Silk_PITCH_EST_MID_COMPLEX        1
+#define SKP_Silk_PITCH_EST_MAX_COMPLEX        2
+
+void SKP_Silk_decode_pitch(
+    SKP_int            lagIndex,        /* I                                              */
+    SKP_int            contourIndex,    /* O                                              */
+    SKP_int            pitch_lags[],    /* O 4 pitch values                               */
+    SKP_int            Fs_kHz           /* I sampling frequency (kHz)                     */
+);
+
+SKP_int SKP_Silk_pitch_analysis_core(    /* O    Voicing estimate: 0 voiced, 1 unvoiced                      */
+    const SKP_int16  *signal,            /* I    Signal of length PITCH_EST_FRAME_LENGTH_MS*Fs_kHz           */
+    SKP_int          *pitch_out,         /* O    4 pitch lag values                                          */
+    SKP_int          *lagIndex,          /* O    Lag Index                                                   */
+    SKP_int          *contourIndex,      /* O    Pitch contour Index                                         */
+    SKP_int          *LTPCorr_Q15,       /* I/O  Normalized correlation; input: value from previous frame    */
+    SKP_int          prevLag,            /* I    Last lag of previous frame; set to zero is unvoiced         */
+    const SKP_int32  search_thres1_Q16,  /* I    First stage threshold for lag candidates 0 - 1              */
+    const SKP_int    search_thres2_Q15,  /* I    Final threshold for lag candidates 0 - 1                    */
+    const SKP_int    Fs_kHz,             /* I    Sample frequency (kHz)                                      */
+    const SKP_int    complexity,         /* I    Complexity setting, 0-2, where 2 is highest                 */
+	const SKP_int	 forLJC			     /* I	 1 if this function is called from LJC code, 0 otherwise.    */
+);
+
+/* parameter defining the size and accuracy of the piecewise linear    */
+/* cosine approximatin table.                                        */
+
+#define LSF_COS_TAB_SZ_FIX      128
+/* rom table with cosine values */
+extern const SKP_int SKP_Silk_LSFCosTab_FIX_Q12[ LSF_COS_TAB_SZ_FIX + 1 ];
+
+/* Compute Normalized Line Spectral Frequencies (NLSFs) from whitening filter coefficients        */
+/* If not all roots are found, the a_Q16 coefficients are bandwidth expanded until convergence.    */
+void SKP_Silk_A2NLSF(
+    SKP_int            *NLSF,            /* O    Normalized Line Spectral Frequencies, Q15 (0 - (2^15-1)), [d] */
+    SKP_int32          *a_Q16,           /* I/O  Monic whitening filter coefficients in Q16 [d]                */
+    const SKP_int      d                 /* I    Filter order (must be even)                                   */
+);
+
+/* compute whitening filter coefficients from normalized line spectral frequencies */
+void SKP_Silk_NLSF2A(
+    SKP_int16          *a,               /* o    monic whitening filter coefficients in Q12,  [d]    */
+    const SKP_int      *NLSF,            /* i    normalized line spectral frequencies in Q15, [d]    */
+    const SKP_int      d                 /* i    filter order (should be even)                       */
+);
+
+void SKP_Silk_insertion_sort_increasing(
+    SKP_int32            *a,            /* I/O   Unsorted / Sorted vector                */
+    SKP_int              *index,        /* O:    Index vector for the sorted elements    */
+    const SKP_int        L,             /* I:    Vector length                           */
+    const SKP_int        K              /* I:    Number of correctly sorted positions    */
+);
+
+void SKP_Silk_insertion_sort_decreasing_int16(
+    SKP_int16            *a,            /* I/O:  Unsorted / Sorted vector                */
+    SKP_int              *index,        /* O:    Index vector for the sorted elements    */
+    const SKP_int        L,             /* I:    Vector length                           */
+    const SKP_int        K              /* I:    Number of correctly sorted positions    */
+);
+
+void SKP_Silk_insertion_sort_increasing_all_values(
+     SKP_int             *a,            /* I/O:  Unsorted / Sorted vector                */
+     const SKP_int       L              /* I:    Vector length                           */
+);
+
+/* NLSF stabilizer, for a single input data vector */
+void SKP_Silk_NLSF_stabilize(
+          SKP_int        *NLSF_Q15,      /* I/O:  Unstable/stabilized normalized LSF vector in Q15 [L]                    */
+    const SKP_int        *NDeltaMin_Q15, /* I:    Normalized delta min vector in Q15, NDeltaMin_Q15[L] must be >= 1 [L+1] */
+    const SKP_int        L               /* I:    Number of NLSF parameters in the input vector                           */
+);
+
+/* Laroia low complexity NLSF weights */
+void SKP_Silk_NLSF_VQ_weights_laroia(
+    SKP_int              *pNLSFW_Q6,     /* O:    Pointer to input vector weights            [D x 1]       */
+    const SKP_int        *pNLSF_Q15,     /* I:    Pointer to input vector                    [D x 1]       */
+    const SKP_int        D               /* I:    Input vector dimension (even)                            */
+);
+
+/* Compute reflection coefficients from input signal */
+void SKP_Silk_burg_modified(        
+    SKP_int32            *res_nrg,           /* O   residual energy                                                 */
+    SKP_int              *res_nrgQ,          /* O   residual energy Q value                                         */
+    SKP_int32            A_Q16[],            /* O   prediction coefficients (length order)                          */
+    const SKP_int16      x[],                /* I   input signal, length: nb_subfr * ( D + subfr_length )           */
+    const SKP_int        subfr_length,       /* I   input signal subframe length (including D preceeding samples)   */
+    const SKP_int        nb_subfr,           /* I   number of subframes stacked in x                                */
+    const SKP_int32      WhiteNoiseFrac_Q32, /* I   fraction added to zero-lag autocorrelation                      */
+    const SKP_int        D                   /* I   order                                                           */
+);
+
+/* Copy and multiply a vector by a constant */
+void SKP_Silk_scale_copy_vector16( 
+    SKP_int16            *data_out, 
+    const SKP_int16      *data_in, 
+    SKP_int32            gain_Q16,           /* I:   gain in Q16   */
+    const SKP_int        dataSize            /* I:   length        */
+);
+
+/* Some for the LTP related function requires Q26 to work.*/
+void SKP_Silk_scale_vector32_Q26_lshift_18( 
+    SKP_int32            *data1,             /* I/O: Q0/Q18        */
+    SKP_int32            gain_Q26,           /* I:   Q26           */
+    SKP_int              dataSize            /* I:   length        */
+);
+
+/********************************************************************/
+/*                        INLINE ARM MATH                             */
+/********************************************************************/
+
+/*    return sum(inVec1[i]*inVec2[i])    */
+/*    inVec1 and inVec2 should be increasing ordered, and starting address should be 4 byte aligned. (a factor of 4)*/
+SKP_int32 SKP_Silk_inner_prod_aligned(
+    const SKP_int16* const inVec1,           /* I   input vector 1    */ 
+    const SKP_int16* const inVec2,           /* I   input vector 2    */
+    const SKP_int          len               /* I   vector lengths    */
+);
+
+SKP_int64 SKP_Silk_inner_prod16_aligned_64(
+    const SKP_int16        *inVec1,          /* I   input vector 1    */
+    const SKP_int16        *inVec2,          /* I   input vector 2    */
+    const SKP_int          len               /* I   vector lengths    */
+);
+/********************************************************************/
+/*                                MACROS                            */
+/********************************************************************/
+
+/* Rotate a32 right by 'rot' bits. Negative rot values result in rotating
+   left. Output is 32bit int.
+   Note: contemporary compilers recognize the C expressions below and
+   compile them into 'ror' instructions if available. No need for inline ASM! */
+#if defined(EMBEDDED_MIPS)
+/* For MIPS (and most likely for ARM! and >=i486) we don't have to handle
+   negative rot's as only 5 bits of rot are encoded into ROR instructions. */
+SKP_INLINE SKP_int32 SKP_ROR32(SKP_int32 a32, SKP_int rot)
+{
+    SKP_uint32 _x = (SKP_uint32) a32;
+    SKP_uint32 _r = (SKP_uint32) rot;
+    return (SKP_int32) ((_x << (32 - _r)) | (_x >> _r));
+}
+#else
+/* PPC must use this generic implementation. */
+SKP_INLINE SKP_int32 SKP_ROR32( SKP_int32 a32, SKP_int rot )
+{
+    SKP_uint32 x = (SKP_uint32) a32;
+    SKP_uint32 r = (SKP_uint32) rot;
+    SKP_uint32 m = (SKP_uint32) -rot;
+    if(rot <= 0)
+        return (SKP_int32) ((x << m) | (x >> (32 - m)));
+    else
+        return (SKP_int32) ((x << (32 - r)) | (x >> r));
+}
+#endif
+
+/* Allocate SKP_int16 alligned to 4-byte memory address */
+#if EMBEDDED_ARM
+#if defined(_WIN32) && defined(_M_ARM)
+#define SKP_DWORD_ALIGN __declspec(align(4))
+#else
+#define SKP_DWORD_ALIGN __attribute__((aligned(4)))
+#endif
+#else
+#define SKP_DWORD_ALIGN
+#endif
+
+/* Useful Macros that can be adjusted to other platforms */
+#define SKP_memcpy(a, b, c)                memcpy((a), (b), (c))    /* Dest, Src, ByteCount */
+#define SKP_memset(a, b, c)                memset((a), (b), (c))    /* Dest, value, ByteCount */
+#define SKP_memmove(a, b, c)               memmove((a), (b), (c))    /* Dest, Src, ByteCount */
+/* fixed point macros */
+
+// (a32 * b32) output have to be 32bit int
+#define SKP_MUL(a32, b32)                  ((a32) * (b32))
+
+// (a32 * b32) output have to be 32bit uint
+#define SKP_MUL_uint(a32, b32)             SKP_MUL(a32, b32)
+
+// a32 + (b32 * c32) output have to be 32bit int
+#define SKP_MLA(a32, b32, c32)             SKP_ADD32((a32),((b32) * (c32)))
+
+/* ((a32 >> 16)  * (b32 >> 16)) output have to be 32bit int */
+#define SKP_SMULTT(a32, b32)			(((a32) >> 16) * ((b32) >> 16))
+
+/* a32 + ((a32 >> 16)  * (b32 >> 16)) output have to be 32bit int */
+#define SKP_SMLATT(a32, b32, c32)          SKP_ADD32((a32),((b32) >> 16) * ((c32) >> 16))
+
+#define SKP_SMLALBB(a64, b16, c16)         SKP_ADD64((a64),(SKP_int64)((SKP_int32)(b16) * (SKP_int32)(c16)))
+
+// (a32 * b32)
+#define SKP_SMULL(a32, b32)                ((SKP_int64)(a32) * /*(SKP_int64)*/(b32))
+
+/* Adds two signed 32-bit values in a way that can overflow, while not relying on undefined behaviour
+   (just standard two's complement implementation-specific behaviour) */
+#define SKP_ADD32_ovflw(a, b)               ((SKP_int32)((SKP_uint32)(a) + (SKP_uint32)(b)))
+/* Subtractss two signed 32-bit values in a way that can overflow, while not relying on undefined behaviour
+   (just standard two's complement implementation-specific behaviour) */
+#define SKP_SUB32_ovflw(a, b)               ((SKP_int32)((SKP_uint32)(a) - (SKP_uint32)(b)))
+
+/* Multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode) */
+#define SKP_MLA_ovflw(a32, b32, c32)        SKP_ADD32_ovflw((a32), (SKP_uint32)(b32) * (SKP_uint32)(c32))
+#ifndef SKP_SMLABB_ovflw
+ #define SKP_SMLABB_ovflw(a32, b32, c32)    SKP_ADD32_ovflw((a32), SKP_SMULBB((b32),(c32)))
+#endif
+#define SKP_SMLATT_ovflw(a32, b32, c32) 	SKP_ADD32_ovflw((a32), SKP_SMULTT((b32),(c32)))
+#define SKP_SMLAWB_ovflw(a32, b32, c32)	    SKP_ADD32_ovflw((a32), SKP_SMULWB((b32),(c32)))
+#define SKP_SMLAWT_ovflw(a32, b32, c32)	    SKP_ADD32_ovflw((a32), SKP_SMULWT((b32),(c32)))
+#define SKP_DIV32_16(a32, b16)             ((SKP_int32)((a32) / (b16)))
+#define SKP_DIV32(a32, b32)                ((SKP_int32)((a32) / (b32)))
+
+#define SKP_ADD32(a, b)                    ((a) + (b))
+#define SKP_ADD64(a, b)                    ((a) + (b))
+
+#define SKP_SUB32(a, b)                    ((a) - (b))
+
+#define SKP_SAT16(a)                       ((a) > SKP_int16_MAX ? SKP_int16_MAX : \
+                                           ((a) < SKP_int16_MIN ? SKP_int16_MIN : (a)))
+#define SKP_SAT32(a)                       ((a) > SKP_int32_MAX ? SKP_int32_MAX : \
+                                           ((a) < SKP_int32_MIN ? SKP_int32_MIN : (a)))
+
+#define SKP_CHECK_FIT16(a)                 (a)
+#define SKP_CHECK_FIT32(a)                 (a)
+
+#define SKP_ADD_SAT16(a, b)                (SKP_int16)SKP_SAT16( SKP_ADD32( (SKP_int32)(a), (b) ) )
+
+/* Add with saturation for positive input values */ 
+#define SKP_ADD_POS_SAT32(a, b)            ((((a)+(b)) & 0x80000000)           ? SKP_int32_MAX : ((a)+(b)))
+
+#define SKP_LSHIFT32(a, shift)             ((a)<<(shift))                // shift >= 0, shift < 32
+#define SKP_LSHIFT64(a, shift)             ((a)<<(shift))                // shift >= 0, shift < 64
+#define SKP_LSHIFT(a, shift)               SKP_LSHIFT32(a, shift)        // shift >= 0, shift < 32
+
+#define SKP_RSHIFT32(a, shift)             ((a)>>(shift))                // shift >= 0, shift < 32
+#define SKP_RSHIFT64(a, shift)             ((a)>>(shift))                // shift >= 0, shift < 64
+#define SKP_RSHIFT(a, shift)               SKP_RSHIFT32(a, shift)        // shift >= 0, shift < 32
+
+/* saturates before shifting */
+#define SKP_LSHIFT_SAT32(a, shift)         (SKP_LSHIFT32( SKP_LIMIT_32( (a), SKP_RSHIFT32( SKP_int32_MIN, (shift) ),    \
+                                                                          SKP_RSHIFT32( SKP_int32_MAX, (shift) ) ), (shift) ))
+
+#define SKP_LSHIFT_ovflw(a, shift)        ((a)<<(shift))        // shift >= 0, allowed to overflow
+#define SKP_LSHIFT_uint(a, shift)         ((a)<<(shift))        // shift >= 0
+#define SKP_RSHIFT_uint(a, shift)         ((a)>>(shift))        // shift >= 0
+
+#define SKP_ADD_LSHIFT(a, b, shift)       ((a) + SKP_LSHIFT((b), (shift)))            // shift >= 0
+#define SKP_ADD_LSHIFT32(a, b, shift)     SKP_ADD32((a), SKP_LSHIFT32((b), (shift)))    // shift >= 0
+#define SKP_ADD_RSHIFT(a, b, shift)       ((a) + SKP_RSHIFT((b), (shift)))            // shift >= 0
+#define SKP_ADD_RSHIFT32(a, b, shift)     SKP_ADD32((a), SKP_RSHIFT32((b), (shift)))    // shift >= 0
+#define SKP_ADD_RSHIFT_uint(a, b, shift)  ((a) + SKP_RSHIFT_uint((b), (shift)))        // shift >= 0
+#define SKP_SUB_LSHIFT32(a, b, shift)     SKP_SUB32((a), SKP_LSHIFT32((b), (shift)))    // shift >= 0
+#define SKP_SUB_RSHIFT32(a, b, shift)     SKP_SUB32((a), SKP_RSHIFT32((b), (shift)))    // shift >= 0
+
+/* Requires that shift > 0 */
+#define SKP_RSHIFT_ROUND(a, shift)        ((shift) == 1 ? ((a) >> 1) + ((a) & 1) : (((a) >> ((shift) - 1)) + 1) >> 1)
+#define SKP_RSHIFT_ROUND64(a, shift)      ((shift) == 1 ? ((a) >> 1) + ((a) & 1) : (((a) >> ((shift) - 1)) + 1) >> 1)
+
+/* Number of rightshift required to fit the multiplication */
+#define SKP_NSHIFT_MUL_32_32(a, b)        ( -(31- (32-SKP_Silk_CLZ32(SKP_abs(a)) + (32-SKP_Silk_CLZ32(SKP_abs(b))))) )
+
+#define SKP_min(a, b)                     (((a) < (b)) ? (a) : (b)) 
+#define SKP_max(a, b)                     (((a) > (b)) ? (a) : (b))
+
+/* Macro to convert floating-point constants to fixed-point */
+#define SKP_FIX_CONST( C, Q )           ((SKP_int32)((C) * ((SKP_int64)1 << (Q)) + 0.5))
+
+/* SKP_min() versions with typecast in the function call */
+SKP_INLINE SKP_int SKP_min_int(SKP_int a, SKP_int b)
+{
+    return (((a) < (b)) ? (a) : (b));
+}
+
+SKP_INLINE SKP_int32 SKP_min_32(SKP_int32 a, SKP_int32 b)
+{
+    return (((a) < (b)) ? (a) : (b));
+}
+
+/* SKP_min() versions with typecast in the function call */
+SKP_INLINE SKP_int SKP_max_int(SKP_int a, SKP_int b)
+{
+    return (((a) > (b)) ? (a) : (b));
+}
+SKP_INLINE SKP_int16 SKP_max_16(SKP_int16 a, SKP_int16 b)
+{
+    return (((a) > (b)) ? (a) : (b));
+}
+SKP_INLINE SKP_int32 SKP_max_32(SKP_int32 a, SKP_int32 b)
+{
+    return (((a) > (b)) ? (a) : (b));
+}
+
+#define SKP_LIMIT( a, limit1, limit2)    ((limit1) > (limit2) ? ((a) > (limit1) ? (limit1) : ((a) < (limit2) ? (limit2) : (a))) \
+                                                             : ((a) > (limit2) ? (limit2) : ((a) < (limit1) ? (limit1) : (a))))
+
+#define SKP_LIMIT_int SKP_LIMIT
+#define SKP_LIMIT_32 SKP_LIMIT
+
+//#define SKP_non_neg(a)                 ((a) & ((-(a)) >> (8 * sizeof(a) - 1)))   /* doesn't seem faster than SKP_max(0, a);
+
+#define SKP_abs(a)                       (((a) >  0)  ? (a) : -(a))            // Be careful, SKP_abs returns wrong when input equals to SKP_intXX_MIN
+#define SKP_abs_int32(a)                 (((a) ^ ((a) >> 31)) - ((a) >> 31))
+
+/* PSEUDO-RANDOM GENERATOR                                                          */
+/* Make sure to store the result as the seed for the next call (also in between     */
+/* frames), otherwise result won't be random at all. When only using some of the    */
+/* bits, take the most significant bits by right-shifting. Do not just mask off     */
+/* the lowest bits.                                                                 */
+#define SKP_RAND(seed)                   (SKP_MLA_ovflw(907633515, (seed), 196314165))
+
+// Add some multiplication functions that can be easily mapped to ARM.
+
+//    SKP_SMMUL: Signed top word multiply. 
+//        ARMv6        2 instruction cycles. 
+//        ARMv3M+        3 instruction cycles. use SMULL and ignore LSB registers.(except xM) 
+//#define SKP_SMMUL(a32, b32)            (SKP_int32)SKP_RSHIFT(SKP_SMLAL(SKP_SMULWB((a32), (b32)), (a32), SKP_RSHIFT_ROUND((b32), 16)), 16)
+// the following seems faster on x86
+//#define SKP_SMMUL(a32, b32)              (SKP_int32)SKP_RSHIFT64(SKP_SMULL((a32), (b32)), 32)
+
+#include "SKP_Silk_Inlines.h"
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif

+ 91 - 0
pkg/silk2audio/silk/SKP_Silk_control.h

@@ -0,0 +1,91 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved. 
+Redistribution and use in source and binary forms, with or without 
+modification, (subject to the limitations in the disclaimer below) 
+are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright 
+notice, this list of conditions and the following disclaimer in the 
+documentation and/or other materials provided with the distribution.
+- Neither the name of Skype Limited, nor the names of specific 
+contributors, may be used to endorse or promote products derived from 
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED 
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+#ifndef SKP_SILK_CONTROL_H
+#define SKP_SILK_CONTROL_H
+
+#include "SKP_Silk_typedef.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/***********************************************/
+/* Structure for controlling encoder operation */
+/***********************************************/
+typedef struct {
+    /* I:   Input signal sampling rate in Hertz; 8000/12000/16000/24000                     */
+    SKP_int32 API_sampleRate;
+
+    /* I:   Maximum internal sampling rate in Hertz; 8000/12000/16000/24000                 */
+    SKP_int32 maxInternalSampleRate;
+
+    /* I:   Number of samples per packet; must be equivalent of 20, 40, 60, 80 or 100 ms    */
+    SKP_int packetSize;
+
+    /* I:   Bitrate during active speech in bits/second; internally limited                 */
+    SKP_int32 bitRate;                        
+
+    /* I:   Uplink packet loss in percent (0-100)                                           */
+    SKP_int packetLossPercentage;
+    
+    /* I:   Complexity mode; 0 is lowest; 1 is medium and 2 is highest complexity           */
+    SKP_int complexity;
+
+    /* I:   Flag to enable in-band Forward Error Correction (FEC); 0/1                      */
+    SKP_int useInBandFEC;
+
+    /* I:   Flag to enable discontinuous transmission (DTX); 0/1                            */
+    SKP_int useDTX;
+} SKP_SILK_SDK_EncControlStruct;
+
+/**************************************************************************/
+/* Structure for controlling decoder operation and reading decoder status */
+/**************************************************************************/
+typedef struct {
+    /* I:   Output signal sampling rate in Hertz; 8000/12000/16000/24000                    */
+    SKP_int32 API_sampleRate;
+
+    /* O:   Number of samples per frame                                                     */
+    SKP_int frameSize;
+
+    /* O:   Frames per packet 1, 2, 3, 4, 5                                                 */
+    SKP_int framesPerPacket;
+
+    /* O:   Flag to indicate that the decoder has remaining payloads internally             */
+    SKP_int moreInternalDecoderFrames;
+
+    /* O:   Distance between main payload and redundant payload in packets                  */
+    SKP_int inBandFECOffset;
+} SKP_SILK_SDK_DecControlStruct;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 89 - 0
pkg/silk2audio/silk/SKP_Silk_errors.h

@@ -0,0 +1,89 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved. 
+Redistribution and use in source and binary forms, with or without 
+modification, (subject to the limitations in the disclaimer below) 
+are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright 
+notice, this list of conditions and the following disclaimer in the 
+documentation and/or other materials provided with the distribution.
+- Neither the name of Skype Limited, nor the names of specific 
+contributors, may be used to endorse or promote products derived from 
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED 
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+#ifndef SKP_SILK_ERRORS_H
+#define SKP_SILK_ERRORS_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/******************/
+/* Error messages */
+/******************/
+#define SKP_SILK_NO_ERROR                               0
+
+/**************************/
+/* Encoder error messages */
+/**************************/
+
+/* Input length is not a multiplum of 10 ms, or length is longer than the packet length */
+#define SKP_SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES        -1
+
+/* Sampling frequency not 8000, 12000, 16000 or 24000 Hertz */
+#define SKP_SILK_ENC_FS_NOT_SUPPORTED                   -2
+
+/* Packet size not 20, 40, 60, 80 or 100 ms */
+#define SKP_SILK_ENC_PACKET_SIZE_NOT_SUPPORTED          -3
+
+/* Allocated payload buffer too short */
+#define SKP_SILK_ENC_PAYLOAD_BUF_TOO_SHORT              -4
+
+/* Loss rate not between 0 and 100 percent */
+#define SKP_SILK_ENC_INVALID_LOSS_RATE                  -5
+
+/* Complexity setting not valid, use 0, 1 or 2 */
+#define SKP_SILK_ENC_INVALID_COMPLEXITY_SETTING         -6
+
+/* Inband FEC setting not valid, use 0 or 1 */
+#define SKP_SILK_ENC_INVALID_INBAND_FEC_SETTING         -7
+
+/* DTX setting not valid, use 0 or 1 */
+#define SKP_SILK_ENC_INVALID_DTX_SETTING                -8
+
+/* Internal encoder error */
+#define SKP_SILK_ENC_INTERNAL_ERROR                     -9
+
+/**************************/
+/* Decoder error messages */
+/**************************/
+
+/* Output sampling frequency lower than internal decoded sampling frequency */
+#define SKP_SILK_DEC_INVALID_SAMPLING_FREQUENCY         -10
+
+/* Payload size exceeded the maximum allowed 1024 bytes */
+#define SKP_SILK_DEC_PAYLOAD_TOO_LARGE                  -11
+
+/* Payload has bit errors */
+#define SKP_SILK_DEC_PAYLOAD_ERROR                      -12
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 125 - 0
pkg/silk2audio/silk/SKP_Silk_macros.h

@@ -0,0 +1,125 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved. 
+Redistribution and use in source and binary forms, with or without 
+modification, (subject to the limitations in the disclaimer below) 
+are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright 
+notice, this list of conditions and the following disclaimer in the 
+documentation and/or other materials provided with the distribution.
+- Neither the name of Skype Limited, nor the names of specific 
+contributors, may be used to endorse or promote products derived from 
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED 
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+#ifndef _SKP_SILK_API_C_H_
+#define _SKP_SILK_API_C_H_
+
+// This is an inline header file for general platform.
+
+// (a32 * (SKP_int32)((SKP_int16)(b32))) >> 16 output have to be 32bit int
+#define SKP_SMULWB(a32, b32)            ((((a32) >> 16) * (SKP_int32)((SKP_int16)(b32))) + ((((a32) & 0x0000FFFF) * (SKP_int32)((SKP_int16)(b32))) >> 16))
+
+// a32 + (b32 * (SKP_int32)((SKP_int16)(c32))) >> 16 output have to be 32bit int
+#define SKP_SMLAWB(a32, b32, c32)       ((a32) + ((((b32) >> 16) * (SKP_int32)((SKP_int16)(c32))) + ((((b32) & 0x0000FFFF) * (SKP_int32)((SKP_int16)(c32))) >> 16)))
+
+// (a32 * (b32 >> 16)) >> 16
+#define SKP_SMULWT(a32, b32)            (((a32) >> 16) * ((b32) >> 16) + ((((a32) & 0x0000FFFF) * ((b32) >> 16)) >> 16))
+
+// a32 + (b32 * (c32 >> 16)) >> 16
+#define SKP_SMLAWT(a32, b32, c32)       ((a32) + (((b32) >> 16) * ((c32) >> 16)) + ((((b32) & 0x0000FFFF) * ((c32) >> 16)) >> 16))
+
+// (SKP_int32)((SKP_int16)(a3))) * (SKP_int32)((SKP_int16)(b32)) output have to be 32bit int
+#define SKP_SMULBB(a32, b32)            ((SKP_int32)((SKP_int16)(a32)) * (SKP_int32)((SKP_int16)(b32)))
+
+// a32 + (SKP_int32)((SKP_int16)(b32)) * (SKP_int32)((SKP_int16)(c32)) output have to be 32bit int
+#define SKP_SMLABB(a32, b32, c32)       ((a32) + ((SKP_int32)((SKP_int16)(b32))) * (SKP_int32)((SKP_int16)(c32)))
+
+// (SKP_int32)((SKP_int16)(a32)) * (b32 >> 16)
+#define SKP_SMULBT(a32, b32)            ((SKP_int32)((SKP_int16)(a32)) * ((b32) >> 16))
+
+// a32 + (SKP_int32)((SKP_int16)(b32)) * (c32 >> 16)
+#define SKP_SMLABT(a32, b32, c32)       ((a32) + ((SKP_int32)((SKP_int16)(b32))) * ((c32) >> 16))
+
+// a64 + (b32 * c32)
+#define SKP_SMLAL(a64, b32, c32)        (SKP_ADD64((a64), ((SKP_int64)(b32) * (SKP_int64)(c32))))
+
+// (a32 * b32) >> 16
+#define SKP_SMULWW(a32, b32)            SKP_MLA(SKP_SMULWB((a32), (b32)), (a32), SKP_RSHIFT_ROUND((b32), 16))
+
+// a32 + ((b32 * c32) >> 16)
+#define SKP_SMLAWW(a32, b32, c32)       SKP_MLA(SKP_SMLAWB((a32), (b32), (c32)), (b32), SKP_RSHIFT_ROUND((c32), 16))
+
+// (SKP_int32)(((SKP_int64)a32 * b32) >> 32)
+#define SKP_SMMUL(a32, b32)             (SKP_int32)SKP_RSHIFT64(SKP_SMULL((a32), (b32)), 32)
+
+/* add/subtract with output saturated */
+#define SKP_ADD_SAT32(a, b)             ((((a) + (b)) & 0x80000000) == 0 ?                              \
+                                        ((((a) & (b)) & 0x80000000) != 0 ? SKP_int32_MIN : (a)+(b)) :   \
+                                        ((((a) | (b)) & 0x80000000) == 0 ? SKP_int32_MAX : (a)+(b)) )
+
+#define SKP_SUB_SAT32(a, b)             ((((a)-(b)) & 0x80000000) == 0 ?                                        \
+                                        (( (a) & ((b)^0x80000000) & 0x80000000) ? SKP_int32_MIN : (a)-(b)) :    \
+                                        ((((a)^0x80000000) & (b)  & 0x80000000) ? SKP_int32_MAX : (a)-(b)) )
+    
+SKP_INLINE SKP_int32 SKP_Silk_CLZ16(SKP_int16 in16)
+{
+    SKP_int32 out32 = 0;
+    if( in16 == 0 ) {
+        return 16;
+    }
+    /* test nibbles */
+    if( in16 & 0xFF00 ) {
+        if( in16 & 0xF000 ) {
+            in16 >>= 12;
+        } else {
+            out32 += 4;
+            in16 >>= 8;
+        }
+    } else {
+        if( in16 & 0xFFF0 ) {
+            out32 += 8;
+            in16 >>= 4;
+        } else {
+            out32 += 12;
+        }
+    }
+    /* test bits and return */
+    if( in16 & 0xC ) {
+        if( in16 & 0x8 )
+            return out32 + 0;
+        else
+            return out32 + 1;
+    } else {
+        if( in16 & 0xE )
+            return out32 + 2;
+        else
+            return out32 + 3;
+    }
+}
+
+SKP_INLINE SKP_int32 SKP_Silk_CLZ32(SKP_int32 in32)
+{
+    /* test highest 16 bits and convert to SKP_int16 */
+    if( in32 & 0xFFFF0000 ) {
+        return SKP_Silk_CLZ16((SKP_int16)(in32 >> 16));
+    } else {
+        return SKP_Silk_CLZ16((SKP_int16)in32) + 16;
+    }
+}
+
+#endif //_SKP_SILK_API_C_H_
+

+ 80 - 0
pkg/silk2audio/silk/SKP_Silk_resampler_structs.h

@@ -0,0 +1,80 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved. 
+Redistribution and use in source and binary forms, with or without 
+modification, (subject to the limitations in the disclaimer below) 
+are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright 
+notice, this list of conditions and the following disclaimer in the 
+documentation and/or other materials provided with the distribution.
+- Neither the name of Skype Limited, nor the names of specific 
+contributors, may be used to endorse or promote products derived from 
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED 
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+/*																		*
+ * File Name:	SKP_Silk_resampler_structs.h							*
+ *																		*
+ * Description: Structs for IIR/FIR resamplers							*
+ *                                                                      *
+ * Copyright 2010 (c), Skype Limited                                    *
+ * All rights reserved.													*
+ *																		*
+ *                                                                      */
+
+#ifndef SKP_Silk_RESAMPLER_STRUCTS_H
+#define SKP_Silk_RESAMPLER_STRUCTS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Flag to enable support for input/output sampling rates above 48 kHz. Turn off for embedded devices */
+#define RESAMPLER_SUPPORT_ABOVE_48KHZ                   1
+
+#define SKP_Silk_RESAMPLER_MAX_FIR_ORDER                 16
+#define SKP_Silk_RESAMPLER_MAX_IIR_ORDER                 6
+
+
+typedef struct _SKP_Silk_resampler_state_struct{
+	SKP_int32       sIIR[ SKP_Silk_RESAMPLER_MAX_IIR_ORDER ];        /* this must be the first element of this struct */
+	SKP_int32       sFIR[ SKP_Silk_RESAMPLER_MAX_FIR_ORDER ];
+	SKP_int32       sDown2[ 2 ];
+	void            (*resampler_function)( void *, SKP_int16 *, const SKP_int16 *, SKP_int32 );
+	void            (*up2_function)(  SKP_int32 *, SKP_int16 *, const SKP_int16 *, SKP_int32 );
+    SKP_int32       batchSize;
+	SKP_int32       invRatio_Q16;
+	SKP_int32       FIR_Fracs;
+    SKP_int32       input2x;
+	const SKP_int16	*Coefs;
+#if RESAMPLER_SUPPORT_ABOVE_48KHZ
+	SKP_int32       sDownPre[ 2 ];
+	SKP_int32       sUpPost[ 2 ];
+	void            (*down_pre_function)( SKP_int32 *, SKP_int16 *, const SKP_int16 *, SKP_int32 );
+	void            (*up_post_function)(  SKP_int32 *, SKP_int16 *, const SKP_int16 *, SKP_int32 );
+	SKP_int32       batchSizePrePost;
+	SKP_int32       ratio_Q16;
+	SKP_int32       nPreDownsamplers;
+	SKP_int32       nPostUpsamplers;
+#endif
+	SKP_int32 magic_number;
+} SKP_Silk_resampler_state_struct;
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* SKP_Silk_RESAMPLER_STRUCTS_H */
+

+ 107 - 0
pkg/silk2audio/silk/SKP_Silk_typedef.h

@@ -0,0 +1,107 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved. 
+Redistribution and use in source and binary forms, with or without 
+modification, (subject to the limitations in the disclaimer below) 
+are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright 
+notice, this list of conditions and the following disclaimer in the 
+documentation and/or other materials provided with the distribution.
+- Neither the name of Skype Limited, nor the names of specific 
+contributors, may be used to endorse or promote products derived from 
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED 
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+#ifndef _SKP_SILK_API_TYPDEF_H_
+#define _SKP_SILK_API_TYPDEF_H_
+
+#ifndef SKP_USE_DOUBLE_PRECISION_FLOATS
+#define SKP_USE_DOUBLE_PRECISION_FLOATS		0
+#endif
+
+#include <float.h>
+#if defined( __GNUC__ )
+#include <stdint.h>
+#endif
+
+#define SKP_int         int                     /* used for counters etc; at least 16 bits */
+#ifdef __GNUC__
+# define SKP_int64      int64_t
+#else
+# define SKP_int64      long long
+#endif
+#define SKP_int32       int
+#define SKP_int16       short
+#define SKP_int8        signed char
+
+#define SKP_uint        unsigned int            /* used for counters etc; at least 16 bits */
+#ifdef __GNUC__
+# define SKP_uint64     uint64_t
+#else
+# define SKP_uint64     unsigned long long
+#endif
+#define SKP_uint32      unsigned int
+#define SKP_uint16      unsigned short
+#define SKP_uint8       unsigned char
+
+#define SKP_int_ptr_size intptr_t
+
+#if SKP_USE_DOUBLE_PRECISION_FLOATS
+# define SKP_float      double
+# define SKP_float_MAX  DBL_MAX
+#else
+# define SKP_float      float
+# define SKP_float_MAX  FLT_MAX
+#endif
+
+#define SKP_INLINE      static __inline
+
+#ifdef _WIN32
+# define SKP_STR_CASEINSENSITIVE_COMPARE(x, y) _stricmp(x, y)
+#else
+# define SKP_STR_CASEINSENSITIVE_COMPARE(x, y) strcasecmp(x, y)
+#endif 
+
+#define	SKP_int64_MAX	((SKP_int64)0x7FFFFFFFFFFFFFFFLL)	/*  2^63 - 1  */
+#define SKP_int64_MIN	((SKP_int64)0x8000000000000000LL)	/* -2^63	 */
+#define	SKP_int32_MAX	0x7FFFFFFF							/*  2^31 - 1 =  2147483647*/
+#define SKP_int32_MIN	((SKP_int32)0x80000000)				/* -2^31	 = -2147483648*/
+#define	SKP_int16_MAX	0x7FFF								/*	2^15 - 1 =	32767*/
+#define SKP_int16_MIN	((SKP_int16)0x8000)					/* -2^15	 = -32768*/
+#define	SKP_int8_MAX	0x7F								/*	2^7 - 1  =  127*/
+#define SKP_int8_MIN	((SKP_int8)0x80)					/* -2^7 	 = -128*/
+
+#define SKP_uint32_MAX	0xFFFFFFFF	/* 2^32 - 1 = 4294967295 */
+#define SKP_uint32_MIN	0x00000000
+#define SKP_uint16_MAX	0xFFFF		/* 2^16 - 1 = 65535 */
+#define SKP_uint16_MIN	0x0000
+#define SKP_uint8_MAX	0xFF		/*  2^8 - 1 = 255 */
+#define SKP_uint8_MIN	0x00
+
+#define SKP_TRUE		1
+#define SKP_FALSE		0
+
+/* assertions */
+#if (defined _WIN32 && !defined _WINCE && !defined(__GNUC__) && !defined(NO_ASSERTS))
+# ifndef SKP_assert
+#  include <crtdbg.h>      /* ASSERTE() */
+#  define SKP_assert(COND)   _ASSERTE(COND)
+# endif
+#else
+# define SKP_assert(COND)
+#endif
+
+#endif

BIN
pkg/silk2audio/silk/libSKP_SILK_SDK.a.linux_bak


BIN
pkg/silk2audio/silk/libSKP_SILK_SDK.a.win_bak


+ 75 - 0
pkg/silk2audio/silk/silk.go

@@ -0,0 +1,75 @@
+package silk
+
+/*
+#cgo LDFLAGS: -L . -lSKP_SILK_SDK
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+
+#include "SKP_Silk_SDK_API.h"
+#include "Decoder.h"
+static void print_usage() {
+     printf("********** Silk Decoder (Fixed Point) v %s ********************\n", SKP_Silk_SDK_get_version());
+}
+*/
+import "C"
+import (
+	"fmt"
+	"os"
+	"silk2audio/transcoder/ffmpeg"
+	"strings"
+	"unsafe"
+)
+
+func TransSilkToWav(inputPath string) (string, string) {
+	var outputPath = strings.Replace(inputPath, ".silk", ".pcm", -1)
+	var wavPath = strings.Replace(inputPath, ".silk", ".wav", -1)
+
+	inputPathC := C.CString(inputPath)
+	outPathC := C.CString(outputPath)
+	var _ = C.Decoder(inputPathC, outPathC) //调用C函数
+	C.free(unsafe.Pointer(inputPathC))
+	C.free(unsafe.Pointer(outPathC))
+	//ffmpeg pcm转码音频
+	transPcmToAudio(outputPath, wavPath)
+
+	//_ = FileRemove(outputPath)
+	return wavPath, outputPath
+}
+
+func transPcmToAudio(inputPath, OutputPath string) {
+	format := "s16le"
+	overwrite := true
+	audioCodec := "pcm_s16le"
+	audioChannels := 2
+	audioRate := 12000
+	opts := ffmpeg.Options{
+		Overwrite:     &overwrite,
+		OutputFormat:  &format,
+		AudioChannels: &audioChannels,
+		AudioRate:     &audioRate,
+		AudioCodec:    &audioCodec,
+	}
+	ffmpegConf := &ffmpeg.Config{
+		FfmpegBinPath: "ffmpeg",
+	}
+	_, err := ffmpeg.
+		New(ffmpegConf).
+		Input(inputPath).
+		Output(OutputPath).
+		WithOptions(opts).
+		Start(opts)
+	if err != nil {
+		fmt.Println(err.Error())
+	} else {
+		fmt.Println(OutputPath)
+	}
+}
+
+func FileRemove(logFile string) error {
+	_, err := os.Stat(logFile)
+	if err == nil {
+		return os.Remove(logFile)
+	}
+	return nil
+}

+ 4 - 0
pkg/silk2audio/transcoder/config.go

@@ -0,0 +1,4 @@
+package transcoder
+
+// Config ...
+type Config interface{}

+ 9 - 0
pkg/silk2audio/transcoder/ffmpeg/config.go

@@ -0,0 +1,9 @@
+package ffmpeg
+
+// Config ...
+type Config struct {
+	FfmpegBinPath   string
+	FfprobeBinPath  string
+	ProgressEnabled bool
+	Verbose         bool
+}

+ 283 - 0
pkg/silk2audio/transcoder/ffmpeg/ffmpeg.go

@@ -0,0 +1,283 @@
+package ffmpeg
+
+import (
+	"bufio"
+	"bytes"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"io"
+	"os"
+	"os/exec"
+	"regexp"
+	"silk2audio/transcoder"
+	"silk2audio/transcoder/utils"
+	"strconv"
+	"strings"
+)
+
+// Transcoder ...
+type Transcoder struct {
+	config           *Config
+	input            string
+	output           string
+	options          []string
+	metadata         *Metadata
+	inputPipeReader  *io.ReadCloser
+	outputPipeReader *io.ReadCloser
+	inputPipeWriter  *io.WriteCloser
+	outputPipeWriter *io.WriteCloser
+}
+
+// New ...
+func New(cfg *Config) transcoder.Transcoder {
+	return &Transcoder{config: cfg}
+}
+
+// Start ...
+func (t *Transcoder) Start(opts transcoder.Options) (<-chan transcoder.Progress, error) {
+
+	var stderrIn io.ReadCloser
+
+	out := make(chan transcoder.Progress)
+
+	defer t.closePipes()
+
+	// Validates config
+	if err := t.validate(); err != nil {
+		return nil, err
+	}
+
+	// Get file metadata
+	//_, err := t.getMetadata()
+	//if err != nil {
+	//	return nil, err
+	//}
+	var err error
+	// Get executable flags
+	args := append(opts.GetStrArguments())
+	// Append output flag
+	args = append(args, []string{"-i", t.input, t.output}...)
+
+	// Initialize command
+	cmd := exec.Command(t.config.FfmpegBinPath, args...)
+
+	// If progresss enabled, get stderr pipe and start progress process
+	if t.config.ProgressEnabled && !t.config.Verbose {
+		stderrIn, err = cmd.StderrPipe()
+		if err != nil {
+			return nil, fmt.Errorf("Failed getting transcoding progress (%s) with args (%s) with error %s", t.config.FfmpegBinPath, args, err)
+		}
+	}
+
+	if t.config.Verbose {
+		cmd.Stderr = os.Stdout
+	}
+
+	// Start process
+	err = cmd.Start()
+
+	if err != nil {
+		return nil, fmt.Errorf("Failed starting transcoding (%s) with args (%s) with error %s", t.config.FfmpegBinPath, args, err)
+	}
+
+	if t.config.ProgressEnabled && !t.config.Verbose {
+		go func() {
+			t.progress(stderrIn, out)
+		}()
+
+		go func() {
+			defer close(out)
+			err = cmd.Wait()
+		}()
+	} else {
+		err = cmd.Wait()
+	}
+	return out, nil
+}
+
+// Input ...
+func (t *Transcoder) Input(arg string) transcoder.Transcoder {
+	t.input = arg
+	return t
+}
+
+// Output ...
+func (t *Transcoder) Output(arg string) transcoder.Transcoder {
+	t.output = arg
+	return t
+}
+
+// InputPipe ...
+func (t *Transcoder) InputPipe(w *io.WriteCloser, r *io.ReadCloser) transcoder.Transcoder {
+	if &t.input == nil {
+		t.inputPipeWriter = w
+		t.inputPipeReader = r
+	}
+	return t
+}
+
+// OutputPipe ...
+func (t *Transcoder) OutputPipe(w *io.WriteCloser, r *io.ReadCloser) transcoder.Transcoder {
+	if &t.output == nil {
+		t.outputPipeWriter = w
+		t.outputPipeReader = r
+	}
+	return t
+}
+
+// WithOptions ...
+func (t *Transcoder) WithOptions(opts transcoder.Options) transcoder.Transcoder {
+	t.options = opts.GetStrArguments()
+	return t
+}
+
+// validate ...
+func (t *Transcoder) validate() error {
+	if t.config.FfmpegBinPath == "" {
+		return errors.New("ffmpeg binary path not found")
+	}
+
+	if t.input == "" {
+		return errors.New("missing input option")
+	}
+
+	if t.output == "" {
+		return errors.New("missing output option")
+	}
+
+	return nil
+}
+
+func (t *Transcoder) getMetadata() (metadata *Metadata, err error) {
+
+	if t.config.FfprobeBinPath != "" {
+		var outb, errb bytes.Buffer
+
+		input := t.input
+
+		if t.inputPipeReader != nil {
+			input = "pipe:"
+		}
+
+		args := []string{"-i", input, "-print_format", "json", "-show_format", "-show_streams", "-show_error"}
+
+		cmd := exec.Command(t.config.FfprobeBinPath, args...)
+		cmd.Stdout = &outb
+		cmd.Stderr = &errb
+
+		err := cmd.Run()
+		if err != nil {
+			return nil, fmt.Errorf("error executing (%s) with args (%s) | error: %s | message: %s %s", t.config.FfprobeBinPath, args, err, outb.String(), errb.String())
+		}
+
+		if err = json.Unmarshal([]byte(outb.String()), &metadata); err != nil {
+			return nil, err
+		}
+
+		t.metadata = metadata
+
+		return metadata, nil
+	}
+
+	return nil, errors.New("ffprobe binary not found")
+}
+
+// progress sends through given channel the transcoding status
+func (t *Transcoder) progress(stream io.ReadCloser, out chan transcoder.Progress) {
+
+	defer stream.Close()
+
+	split := func(data []byte, atEOF bool) (advance int, token []byte, spliterror error) {
+		if atEOF && len(data) == 0 {
+			return 0, nil, nil
+		}
+		if i := bytes.IndexByte(data, '\n'); i >= 0 {
+			// We have a full newline-terminated line.
+			return i + 1, data[0:i], nil
+		}
+		if i := bytes.IndexByte(data, '\r'); i >= 0 {
+			// We have a cr terminated line
+			return i + 1, data[0:i], nil
+		}
+		if atEOF {
+			return len(data), data, nil
+		}
+
+		return 0, nil, nil
+	}
+
+	scanner := bufio.NewScanner(stream)
+	scanner.Split(split)
+
+	buf := make([]byte, 2)
+	scanner.Buffer(buf, bufio.MaxScanTokenSize)
+
+	for scanner.Scan() {
+		Progress := new(Progress)
+		line := scanner.Text()
+
+		if strings.Contains(line, "frame=") && strings.Contains(line, "time=") && strings.Contains(line, "bitrate=") {
+			var re = regexp.MustCompile(`=\s+`)
+			st := re.ReplaceAllString(line, `=`)
+
+			f := strings.Fields(st)
+
+			var framesProcessed string
+			var currentTime string
+			var currentBitrate string
+			var currentSpeed string
+
+			for j := 0; j < len(f); j++ {
+				field := f[j]
+				fieldSplit := strings.Split(field, "=")
+
+				if len(fieldSplit) > 1 {
+					fieldname := strings.Split(field, "=")[0]
+					fieldvalue := strings.Split(field, "=")[1]
+
+					if fieldname == "frame" {
+						framesProcessed = fieldvalue
+					}
+
+					if fieldname == "time" {
+						currentTime = fieldvalue
+					}
+
+					if fieldname == "bitrate" {
+						currentBitrate = fieldvalue
+					}
+					if fieldname == "speed" {
+						currentSpeed = fieldvalue
+					}
+				}
+			}
+
+			timesec := utils.DurToSec(currentTime)
+			dursec, _ := strconv.ParseFloat(t.metadata.Format.Duration, 64)
+
+			progress := (timesec * 100) / dursec
+			Progress.Progress = progress
+
+			Progress.CurrentBitrate = currentBitrate
+			Progress.FramesProcessed = framesProcessed
+			Progress.CurrentTime = currentTime
+			Progress.Speed = currentSpeed
+
+			out <- *Progress
+		}
+	}
+}
+
+// closePipes Closes pipes if opened
+func (t *Transcoder) closePipes() {
+	if t.inputPipeReader != nil {
+		ipr := *t.inputPipeReader
+		ipr.Close()
+	}
+
+	if t.outputPipeWriter != nil {
+		opr := *t.outputPipeWriter
+		opr.Close()
+	}
+}

+ 187 - 0
pkg/silk2audio/transcoder/ffmpeg/options.go

@@ -0,0 +1,187 @@
+package ffmpeg
+
+import (
+	"fmt"
+	"reflect"
+	"strconv"
+)
+
+// Options defines allowed FFmpeg arguments
+type Options struct {
+	Aspect                *string           `flag:"-aspect"`
+	Resolution            *string           `flag:"-s"`
+	VideoBitRate          *string           `flag:"-b:v"`
+	VideoBitRateTolerance *int              `flag:"-bt"`
+	VideoMaxBitRate       *int              `flag:"-maxrate"`
+	VideoMinBitrate       *int              `flag:"-minrate"`
+	VideoCodec            *string           `flag:"--c:v"`
+	Vframes               *int              `flag:"-vframes"`
+	FrameRate             *int              `flag:"-r"`
+	AudioRate             *int              `flag:"-ar"`
+	KeyframeInterval      *int              `flag:"-g"`
+	AudioCodec            *string           `flag:"-c:a"`
+	AudioBitrate          *string           `flag:"-ab"`
+	AudioChannels         *int              `flag:"-ac"`
+	AudioVariableBitrate  *bool             `flag:"-q:a"`
+	BufferSize            *int              `flag:"-bufsize"`
+	Threadset             *bool             `flag:"-threads"`
+	Threads               *int              `flag:"-threads"`
+	Preset                *string           `flag:"-preset"`
+	Tune                  *string           `flag:"-tune"`
+	AudioProfile          *string           `flag:"-profile:a"`
+	VideoProfile          *string           `flag:"-profile:v"`
+	Target                *string           `flag:"-target"`
+	Duration              *string           `flag:"-t"`
+	Qscale                *uint32           `flag:"-qscale"`
+	Crf                   *uint32           `flag:"-crf"`
+	Strict                *int              `flag:"-strict"`
+	MuxDelay              *string           `flag:"-muxdelay"`
+	SeekTime              *string           `flag:"-ss"`
+	SeekUsingTimestamp    *bool             `flag:"-seek_timestamp"`
+	MovFlags              *string           `flag:"-movflags"`
+	HideBanner            *bool             `flag:"-hide_banner"`
+	OutputFormat          *string           `flag:"-f"`
+	CopyTs                *bool             `flag:"-copyts"`
+	NativeFramerateInput  *bool             `flag:"-re"`
+	InputInitialOffset    *string           `flag:"-itsoffset"`
+	RtmpLive              *string           `flag:"-rtmp_live"`
+	HlsPlaylistType       *string           `flag:"-hls_playlist_type"`
+	HlsListSize           *int              `flag:"-hls_list_size"`
+	HlsSegmentDuration    *int              `flag:"-hls_time"`
+	HlsMasterPlaylistName *string           `flag:"-master_pl_name"`
+	HlsSegmentFilename    *string           `flag:"-hls_segment_filename"`
+	HTTPMethod            *string           `flag:"-method"`
+	HTTPKeepAlive         *bool             `flag:"-multiple_requests"`
+	Hwaccel               *string           `flag:"-hwaccel"`
+	StreamIds             map[string]string `flag:"-streamid"`
+	VideoFilter           *string           `flag:"-vf"`
+	AudioFilter           *string           `flag:"-af"`
+	SkipVideo             *bool             `flag:"-vn"`
+	SkipAudio             *bool             `flag:"-an"`
+	CompressionLevel      *int              `flag:"-compression_level"`
+	MapMetadata           *string           `flag:"-map_metadata"`
+	Metadata              map[string]string `flag:"-metadata"`
+	EncryptionKey         *string           `flag:"-hls_key_info_file"`
+	Bframe                *int              `flag:"-bf"`
+	PixFmt                *string           `flag:"-pix_fmt"`
+	WhiteListProtocols    []string          `flag:"-protocol_whitelist"`
+	Overwrite             *bool             `flag:"-y"`
+	ExtraArgs             map[string]interface{}
+}
+
+// GetStrArguments ...
+func (opts Options) GetStrArguments() []string {
+	f := reflect.TypeOf(opts)
+	v := reflect.ValueOf(opts)
+
+	values := []string{}
+
+	for i := 0; i < f.NumField(); i++ {
+		flag := f.Field(i).Tag.Get("flag")
+		value := v.Field(i).Interface()
+
+		if !v.Field(i).IsNil() {
+
+			if _, ok := value.(*bool); ok {
+				values = append(values, flag)
+			}
+
+			if vs, ok := value.(*string); ok {
+				values = append(values, flag, *vs)
+			}
+
+			if vs, ok := value.(*int); ok {
+				values = append(values, flag, strconv.Itoa(*vs))
+			}
+
+			if va, ok := value.([]string); ok {
+
+				for i := 0; i < len(va); i++ {
+					item := va[i]
+					values = append(values, flag, item)
+				}
+			}
+
+			if vm, ok := value.(map[string]string); ok {
+				for k, v := range vm {
+					values = append(values, flag, fmt.Sprintf("%v:%v", k, v))
+				}
+			}
+
+		}
+	}
+
+	return values
+}
+
+// Metadata ...
+type Metadata struct {
+	Streams []Streams `json:"streams"`
+	Format  Format    `json:"format"`
+}
+
+// Streams defines allowed stream options
+type Streams struct {
+	Index              int
+	ID                 string      `json:"id"`
+	CodecName          string      `json:"codec_name"`
+	CodecLongName      string      `json:"codec_long_name"`
+	Profile            string      `json:"profile"`
+	CodecType          string      `json:"codec_type"`
+	CodecTimeBase      string      `json:"codec_time_base"`
+	CodecTagString     string      `json:"codec_tag_string"`
+	CodecTag           string      `json:"codec_tag"`
+	Width              int         `json:"width"`
+	Height             int         `json:"height"`
+	CodedWidth         int         `json:"coded_width"`
+	CodedHeight        int         `json:"coded_height"`
+	HasBFrames         int         `json:"has_b_frames"`
+	SampleAspectRatio  string      `json:"sample_aspect_ratio"`
+	DisplayAspectRatio string      `json:"display_aspect_ratio"`
+	PixFmt             string      `json:"pix_fmt"`
+	Level              int         `json:"level"`
+	ChromaLocation     string      `json:"chroma_location"`
+	Refs               int         `json:"refs"`
+	QuarterSample      string      `json:"quarter_sample"`
+	DivxPacked         string      `json:"divx_packed"`
+	RFrameRrate        string      `json:"r_frame_rate"`
+	AvgFrameRate       string      `json:"avg_frame_rate"`
+	TimeBase           string      `json:"time_base"`
+	DurationTs         int         `json:"duration_ts"`
+	Duration           string      `json:"duration"`
+	Disposition        Disposition `json:"disposition"`
+	BitRate            string      `json:"bit_rate"`
+}
+
+// Disposition ...
+type Disposition struct {
+	Default         int `json:"default"`
+	Dub             int `json:"dub"`
+	Original        int `json:"original"`
+	Comment         int `json:"comment"`
+	Lyrics          int `json:"lyrics"`
+	Karaoke         int `json:"karaoke"`
+	Forced          int `json:"forced"`
+	HearingImpaired int `json:"hearing_impaired"`
+	VisualImpaired  int `json:"visual_impaired"`
+	CleanEffects    int `json:"clean_effects"`
+}
+
+// Format ...
+type Format struct {
+	Filename       string
+	NbStreams      int    `json:"nb_streams"`
+	NbPrograms     int    `json:"nb_programs"`
+	FormatName     string `json:"format_name"`
+	FormatLongName string `json:"format_long_name"`
+	Duration       string `json:"duration"`
+	Size           string `json:"size"`
+	BitRate        string `json:"bit_rate"`
+	ProbeScore     int    `json:"probe_score"`
+	Tags           Tags   `json:"tags"`
+}
+
+// Tags ...
+type Tags struct {
+	Encoder string `json:"ENCODER"`
+}

+ 10 - 0
pkg/silk2audio/transcoder/ffmpeg/progress.go

@@ -0,0 +1,10 @@
+package ffmpeg
+
+// Progress ...
+type Progress struct {
+	FramesProcessed string
+	CurrentTime     string
+	CurrentBitrate  string
+	Progress        float64
+	Speed           string
+}

+ 6 - 0
pkg/silk2audio/transcoder/options.go

@@ -0,0 +1,6 @@
+package transcoder
+
+// Options ...
+type Options interface {
+	GetStrArguments() []string
+}

+ 5 - 0
pkg/silk2audio/transcoder/progress.go

@@ -0,0 +1,5 @@
+package transcoder
+
+// Progress ...
+type Progress interface {
+}

+ 13 - 0
pkg/silk2audio/transcoder/transcoder.go

@@ -0,0 +1,13 @@
+package transcoder
+
+import "io"
+
+// Transcoder ...
+type Transcoder interface {
+	Start(opts Options) (<-chan Progress, error)
+	Input(i string) Transcoder
+	InputPipe(w *io.WriteCloser, r *io.ReadCloser) Transcoder
+	Output(o string) Transcoder
+	OutputPipe(w *io.WriteCloser, r *io.ReadCloser) Transcoder
+	WithOptions(opts Options) Transcoder
+}

+ 22 - 0
pkg/silk2audio/transcoder/utils/utils.go

@@ -0,0 +1,22 @@
+package utils
+
+import (
+	"strconv"
+	"strings"
+)
+
+// DurToSec ...
+func DurToSec(dur string) (sec float64) {
+	durAry := strings.Split(dur, ":")
+	var secs float64
+	if len(durAry) != 3 {
+		return
+	}
+	hr, _ := strconv.ParseFloat(durAry[0], 64)
+	secs = hr * (60 * 60)
+	min, _ := strconv.ParseFloat(durAry[1], 64)
+	secs += min * (60)
+	second, _ := strconv.ParseFloat(durAry[2], 64)
+	secs += second
+	return secs
+}

+ 13 - 0
transcoder.api

@@ -0,0 +1,13 @@
+type Request {
+	Path string `form:"path"`
+}
+
+type Response {
+	Path    string `json:"path"`
+	Message string `json:"message"`
+}
+
+service transcoder {
+	@handler TranscoderHandler
+	get /v1/transcoder(Request) returns (Response)
+}

+ 31 - 0
transcoder.go

@@ -0,0 +1,31 @@
+package main
+
+import (
+	"flag"
+	"fmt"
+
+	"audio_transcoder/internal/config"
+	"audio_transcoder/internal/handler"
+	"audio_transcoder/internal/svc"
+
+	"github.com/zeromicro/go-zero/core/conf"
+	"github.com/zeromicro/go-zero/rest"
+)
+
+var configFile = flag.String("f", "etc/transcoder.yaml", "the config file")
+
+func main() {
+	flag.Parse()
+
+	var c config.Config
+	conf.MustLoad(*configFile, &c)
+
+	server := rest.MustNewServer(c.RestConf)
+	defer server.Stop()
+
+	ctx := svc.NewServiceContext(c)
+	handler.RegisterHandlers(server, ctx)
+
+	fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
+	server.Start()
+}