opus.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. package codec
  2. import (
  3. "encoding/binary"
  4. "errors"
  5. )
  6. // rfc6716 https://datatracker.ietf.org/doc/html/rfc6716
  7. //
  8. // TOC byte
  9. // 0
  10. // 0 1 2 3 4 5 6 7
  11. // +-+-+-+-+-+-+-+-+
  12. // | config |s| c |
  13. // +-+-+-+-+-+-+-+-+
  14. // +-----------------------+-----------+-----------+-------------------+
  15. // | Configuration | Mode | Bandwidth | Frame Sizes |
  16. // | Number(s) | | | |
  17. // +-----------------------+-----------+-----------+-------------------+
  18. // | 0...3 | SILK-only | NB | 10, 20, 40, 60 ms |
  19. // | | | | |
  20. // | 4...7 | SILK-only | MB | 10, 20, 40, 60 ms |
  21. // | | | | |
  22. // | 8...11 | SILK-only | WB | 10, 20, 40, 60 ms |
  23. // | | | | |
  24. // | 12...13 | Hybrid | SWB | 10, 20 ms |
  25. // | | | | |
  26. // | 14...15 | Hybrid | FB | 10, 20 ms |
  27. // | | | | |
  28. // | 16...19 | CELT-only | NB | 2.5, 5, 10, 20 ms |
  29. // | | | | |
  30. // | 20...23 | CELT-only | WB | 2.5, 5, 10, 20 ms |
  31. // | | | | |
  32. // | 24...27 | CELT-only | SWB | 2.5, 5, 10, 20 ms |
  33. // | | | | |
  34. // | 28...31 | CELT-only | FB | 2.5, 5, 10, 20 ms |
  35. // +-----------------------+-----------+-----------+-------------------+
  36. // s: with 0 indicating mono and 1 indicating stereo.
  37. //
  38. // c : codes 0 to 3
  39. // 0: 1 frame in the packet
  40. // 1: 2 frames in the packet, each with equal compressed size
  41. // 2: 2 frames in the packet, with different compressed sizes
  42. // 3: an arbitrary number of frames in the packet
  43. // Frame Length Coding
  44. // 0: No frame (Discontinuous Transmission (DTX) or lost packet)
  45. // 1...251: Length of the frame in bytes
  46. // 252...255: A second byte is needed. The total length is (second_byte*4)+first_byte
  47. // Code 0:
  48. // 0 1 2 3
  49. // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  50. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  51. // | config |s|0|0| |
  52. // +-+-+-+-+-+-+-+-+ |
  53. // | Compressed frame 1 (N-1 bytes)... :
  54. // : |
  55. // | |
  56. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  57. // Code 1:
  58. // 0 1 2 3
  59. // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  60. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  61. // | config |s|0|1| |
  62. // +-+-+-+-+-+-+-+-+ :
  63. // | Compressed frame 1 ((N-1)/2 bytes)... |
  64. // : +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  65. // | | |
  66. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ :
  67. // | Compressed frame 2 ((N-1)/2 bytes)... |
  68. // : +-+-+-+-+-+-+-+-+
  69. // | |
  70. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  71. // Code 2:
  72. // 0 1 2 3
  73. // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  74. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  75. // | config |s|1|0| N1 (1-2 bytes): |
  76. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ :
  77. // | Compressed frame 1 (N1 bytes)... |
  78. // : +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  79. // | | |
  80. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
  81. // | Compressed frame 2... :
  82. // : |
  83. // | |
  84. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  85. //Code 3:
  86. // Frame Count Byte
  87. // 0
  88. // 0 1 2 3 4 5 6 7
  89. // +-+-+-+-+-+-+-+-+
  90. // |v|p| M |
  91. // +-+-+-+-+-+-+-+-+
  92. // v: 0 - CBR 1 - VBR
  93. // p: 0 - no padding 1 - padding after frame
  94. // M: frame count
  95. // A CBR Code 3 Packet
  96. // 0 1 2 3
  97. // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  98. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  99. // | config |s|1|1|0|p| M | Padding length (Optional) :
  100. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  101. // | |
  102. // : Compressed frame 1 (R/M bytes)... :
  103. // | |
  104. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  105. // | |
  106. // : Compressed frame 2 (R/M bytes)... :
  107. // | |
  108. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  109. // | |
  110. // : ... :
  111. // | |
  112. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  113. // | |
  114. // : Compressed frame M (R/M bytes)... :
  115. // | |
  116. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  117. // : Opus Padding (Optional)... |
  118. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  119. //
  120. //
  121. // A VBR Code 3 Packet
  122. // 0 1 2 3
  123. // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  124. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  125. // | config |s|1|1|1|p| M | Padding length (Optional) :
  126. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  127. // : N1 (1-2 bytes): N2 (1-2 bytes): ... : N[M-1] |
  128. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  129. // | |
  130. // : Compressed frame 1 (N1 bytes)... :
  131. // | |
  132. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  133. // | |
  134. // : Compressed frame 2 (N2 bytes)... :
  135. // | |
  136. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  137. // | |
  138. // : ... :
  139. // | |
  140. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  141. // | |
  142. // : Compressed frame M... :
  143. // | |
  144. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  145. // : Opus Padding (Optional)... |
  146. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  147. var (
  148. /// 10ms,20ms,40ms,60ms, samplerate 48000
  149. // sample num per millisecond
  150. // 48000 / 1000ms * 10 = 480 ...
  151. SLKOpusSampleSize [4]int = [4]int{480, 960, 1920, 2880}
  152. HybridOpusSampleSize [4]int = [4]int{480, 960}
  153. CELTOpusSampleSize [4]int = [4]int{120, 210, 480, 960}
  154. )
  155. func OpusPacketDuration(packet []byte) uint64 {
  156. config := int(packet[0] >> 3)
  157. code := packet[0] & 0x03
  158. frameCount := 0
  159. var duration uint64
  160. if code == 0 {
  161. frameCount = 1
  162. } else if code == 1 || code == 2 {
  163. frameCount = 2
  164. } else if code == 3 {
  165. frameCount = int(packet[1] & 0x1F)
  166. } else {
  167. panic("code must <= 3")
  168. }
  169. switch {
  170. case config >= 0 && config < 12:
  171. duration = uint64(frameCount * SLKOpusSampleSize[config%4])
  172. case config >= 12 && config < 16:
  173. duration = uint64(frameCount * HybridOpusSampleSize[config%2])
  174. case config >= 16 && config < 32:
  175. duration = uint64(frameCount * CELTOpusSampleSize[config%4])
  176. default:
  177. panic("unkown opus config")
  178. }
  179. return duration
  180. }
  181. //ffmpeg opus.h OpusPacket
  182. type OpusPacket struct {
  183. Code int
  184. Config int
  185. Stereo int
  186. Vbr int
  187. FrameCount int
  188. FrameLen []uint16
  189. Frame []byte
  190. Duration uint64
  191. }
  192. func DecodeOpusPacket(packet []byte) *OpusPacket {
  193. pkt := &OpusPacket{}
  194. pkt.Code = int(packet[0] & 0x03)
  195. pkt.Stereo = int((packet[0] >> 2) & 0x01)
  196. pkt.Config = int(packet[0] >> 3)
  197. switch pkt.Code {
  198. case 0:
  199. pkt.FrameCount = 1
  200. pkt.FrameLen = make([]uint16, 1)
  201. pkt.FrameLen[0] = uint16(len(packet) - 1)
  202. pkt.Frame = packet[1:]
  203. case 1:
  204. pkt.FrameCount = 2
  205. pkt.FrameLen = make([]uint16, 1)
  206. pkt.FrameLen[0] = uint16(len(packet)-1) / 2
  207. pkt.Frame = packet[1:]
  208. case 2:
  209. pkt.FrameCount = 2
  210. hdr := 1
  211. N1 := int(packet[1])
  212. if N1 >= 252 {
  213. N1 = N1 + int(packet[2]*4)
  214. hdr = 2
  215. }
  216. pkt.FrameLen = make([]uint16, 2)
  217. pkt.FrameLen[0] = uint16(N1)
  218. pkt.FrameLen[1] = uint16(len(packet)-hdr) - uint16(N1)
  219. case 3:
  220. hdr := 2
  221. pkt.Vbr = int(packet[1] >> 7)
  222. padding := packet[1] >> 6
  223. pkt.FrameCount = int(packet[1] & 0x1F)
  224. paddingLen := 0
  225. if padding == 1 {
  226. for packet[hdr] == 255 {
  227. paddingLen += 254
  228. hdr++
  229. }
  230. paddingLen += int(packet[hdr])
  231. }
  232. if pkt.Vbr == 0 {
  233. pkt.FrameLen = make([]uint16, 1)
  234. pkt.FrameLen[0] = uint16(len(packet)-hdr-paddingLen) / uint16(pkt.FrameCount)
  235. pkt.Frame = packet[hdr : hdr+int(pkt.FrameLen[0]*uint16(pkt.FrameCount))]
  236. } else {
  237. n := 0
  238. for i := 0; i < int(pkt.FrameCount)-1; i++ {
  239. N1 := int(packet[hdr])
  240. hdr += 1
  241. if N1 >= 252 {
  242. N1 = N1 + int(packet[hdr]*4)
  243. hdr += 1
  244. }
  245. n += N1
  246. pkt.FrameLen = append(pkt.FrameLen, uint16(N1))
  247. }
  248. lastFrameLen := len(packet) - hdr - paddingLen - n
  249. pkt.FrameLen = append(pkt.FrameLen, uint16(lastFrameLen))
  250. pkt.Frame = packet[hdr : hdr+n+lastFrameLen]
  251. }
  252. default:
  253. panic("Error C must <= 3")
  254. }
  255. OpusPacketDuration(packet)
  256. return pkt
  257. }
  258. const (
  259. LEFT_CHANNEL = 0
  260. RIGHT_CHANNEL = 1
  261. )
  262. var (
  263. vorbisChanLayoutOffset [8][8]byte = [8][8]byte{
  264. {0},
  265. {0, 1},
  266. {0, 2, 1},
  267. {0, 1, 2, 3},
  268. {0, 2, 1, 3, 4},
  269. {0, 2, 1, 5, 3, 4},
  270. {0, 2, 1, 6, 5, 3, 4},
  271. {0, 2, 1, 7, 5, 6, 3, 4},
  272. }
  273. )
  274. type ChannelOrder func(channels int, idx int) int
  275. func defalutOrder(channels int, idx int) int {
  276. return idx
  277. }
  278. func vorbisOrder(channels int, idx int) int {
  279. return int(vorbisChanLayoutOffset[channels-1][idx])
  280. }
  281. type ChannelMap struct {
  282. StreamIdx int
  283. ChannelIdx int
  284. Silence bool
  285. Copy bool
  286. CopyFrom int
  287. }
  288. type OpusContext struct {
  289. Preskip int
  290. SampleRate int
  291. ChannelCount int
  292. StreamCount int
  293. StereoStreamCount int
  294. OutputGain uint16
  295. MapType uint8
  296. ChannelMaps []ChannelMap
  297. }
  298. // opus ID Head
  299. // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  300. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  301. // | 'O' | 'p' | 'u' | 's' |
  302. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  303. // | 'H' | 'e' | 'a' | 'd' |
  304. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  305. // | Version = 1 | Channel Count | Pre-skip |
  306. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  307. // | Input Sample Rate (Hz) |
  308. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  309. // | Output Gain (Q7.8 in dB) | Mapping Family| |
  310. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ :
  311. // | |
  312. // : Optional Channel Mapping Table... :
  313. // | |
  314. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  315. // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  316. // +-+-+-+-+-+-+-+-+
  317. // | Stream Count |
  318. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  319. // | Coupled Count | Channel Mapping... :
  320. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  321. //
  322. func (ctx *OpusContext) ParseExtranData(extraData []byte) error {
  323. if string(extraData[0:8]) != "OpusHead" {
  324. return errors.New("magic signature must equal OpusHead")
  325. }
  326. _ = extraData[8] // version
  327. ctx.ChannelCount = int(extraData[9])
  328. ctx.Preskip = int(binary.LittleEndian.Uint16(extraData[10:]))
  329. ctx.SampleRate = int(binary.LittleEndian.Uint32(extraData[12:]))
  330. ctx.OutputGain = binary.LittleEndian.Uint16(extraData[16:])
  331. ctx.MapType = extraData[18]
  332. var channel []byte
  333. var order ChannelOrder
  334. if ctx.MapType == 0 {
  335. ctx.StreamCount = 1
  336. ctx.StereoStreamCount = ctx.ChannelCount - 1
  337. channel = []byte{0, 1}
  338. order = defalutOrder
  339. } else if ctx.MapType == 1 || ctx.MapType == 2 || ctx.MapType == 255 {
  340. ctx.StreamCount = int(extraData[19])
  341. ctx.StereoStreamCount = int(extraData[20])
  342. if ctx.MapType == 1 {
  343. channel = extraData[21 : 21+ctx.ChannelCount]
  344. order = vorbisOrder
  345. }
  346. } else {
  347. return errors.New("unsupport map type 255")
  348. }
  349. for i := 0; i < ctx.ChannelCount; i++ {
  350. cm := ChannelMap{}
  351. index := channel[order(ctx.ChannelCount, i)]
  352. if index == 255 {
  353. cm.Silence = true
  354. continue
  355. } else if index > byte(ctx.StereoStreamCount)+byte(ctx.StreamCount) {
  356. return errors.New("index must < (streamcount + stereo streamcount)")
  357. }
  358. for j := 0; j < i; j++ {
  359. if channel[order(ctx.ChannelCount, i)] == index {
  360. cm.Copy = true
  361. cm.CopyFrom = j
  362. break
  363. }
  364. }
  365. if int(index) < 2*ctx.StereoStreamCount {
  366. cm.StreamIdx = int(index) / 2
  367. if index&1 == 0 {
  368. cm.ChannelIdx = LEFT_CHANNEL
  369. } else {
  370. cm.ChannelIdx = RIGHT_CHANNEL
  371. }
  372. } else {
  373. cm.StreamIdx = int(index) - ctx.StereoStreamCount
  374. cm.ChannelIdx = 0
  375. }
  376. ctx.ChannelMaps = append(ctx.ChannelMaps, cm)
  377. }
  378. return nil
  379. }
  380. func (ctx *OpusContext) WriteOpusExtraData() []byte {
  381. extraData := make([]byte, 19)
  382. copy(extraData, string("OpusHead"))
  383. extraData[8] = 0x01
  384. extraData[9] = byte(ctx.ChannelCount)
  385. binary.LittleEndian.PutUint16(extraData[10:], uint16(ctx.Preskip))
  386. binary.LittleEndian.PutUint32(extraData[12:], uint32(ctx.SampleRate))
  387. return extraData
  388. }
  389. func WriteDefaultOpusExtraData() []byte {
  390. return []byte{
  391. 'O', 'p', 'u', 's', 'H', 'e', 'a', 'd',
  392. 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  393. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  394. }
  395. }