-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmultistream_encode.go
More file actions
109 lines (97 loc) · 3.57 KB
/
multistream_encode.go
File metadata and controls
109 lines (97 loc) · 3.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package gopus
// Encode encodes float32 PCM samples into an Opus multistream packet.
//
// pcm: Input samples (interleaved). Length must be frameSize * channels.
// data: Output buffer for the encoded packet. Recommended size is 4000 bytes per stream.
//
// Returns the number of bytes written to data, or an error.
// Returns 0 bytes written if DTX suppresses all frames (silence detected in all streams).
func (e *MultistreamEncoder) Encode(pcm []float32, data []byte) (int, error) {
expected := e.frameSize * e.channels
if len(pcm) != expected {
return 0, ErrInvalidFrameSize
}
pcm64 := make([]float64, len(pcm))
for i, v := range pcm {
pcm64[i] = float64(v)
}
packet, err := e.enc.Encode(pcm64, e.frameSize)
if err != nil {
return 0, err
}
e.encodedOnce = true
return copyEncodedPacket(packet, data)
}
// EncodeInt16 encodes int16 PCM samples into an Opus multistream packet.
//
// pcm: Input samples (interleaved). Length must be frameSize * channels.
// data: Output buffer for the encoded packet.
//
// Returns the number of bytes written to data, or an error.
func (e *MultistreamEncoder) EncodeInt16(pcm []int16, data []byte) (int, error) {
pcm32 := make([]float32, len(pcm))
for i, v := range pcm {
pcm32[i] = float32(v) / 32768.0
}
return e.Encode(pcm32, data)
}
// EncodeInt24 encodes 24-bit PCM samples stored in int32 values into an Opus multistream packet.
//
// pcm: Input samples (interleaved). Length must be frameSize * channels.
// data: Output buffer for the encoded packet.
//
// Returns the number of bytes written to data, or an error.
//
// The input values are interpreted as right-justified signed 24-bit PCM
// carried in int32 containers with numeric range [-8388608, 8388607].
// Left-shifted 24-in-32 input will be mis-scaled.
func (e *MultistreamEncoder) EncodeInt24(pcm []int32, data []byte) (int, error) {
expected := e.frameSize * e.channels
if len(pcm) != expected {
return 0, ErrInvalidFrameSize
}
pcm64 := make([]float64, len(pcm))
for i, v := range pcm {
pcm64[i] = float64(v) / 8388608.0
}
packet, err := e.enc.Encode(pcm64, e.frameSize)
if err != nil {
return 0, err
}
e.encodedOnce = true
return copyEncodedPacket(packet, data)
}
// EncodeFloat32 encodes float32 PCM samples and returns a new byte slice.
//
// This is a convenience method that allocates the output buffer.
// For performance-critical code, use Encode with a pre-allocated buffer.
//
// pcm: Input samples (interleaved).
//
// Returns the encoded packet or an error.
func (e *MultistreamEncoder) EncodeFloat32(pcm []float32) ([]byte, error) {
return encodeToOwnedPacket(maxPacketBytesPerStream*e.enc.Streams(), func(data []byte) (int, error) {
return e.Encode(pcm, data)
})
}
// EncodeInt16Slice encodes int16 PCM samples and returns a new byte slice.
//
// This is a convenience method that allocates the output buffer.
// For performance-critical code, use EncodeInt16 with a pre-allocated buffer.
//
// pcm: Input samples (interleaved).
//
// Returns the encoded packet or an error.
func (e *MultistreamEncoder) EncodeInt16Slice(pcm []int16) ([]byte, error) {
return encodeToOwnedPacket(maxPacketBytesPerStream*e.enc.Streams(), func(data []byte) (int, error) {
return e.EncodeInt16(pcm, data)
})
}
// EncodeInt24Slice encodes 24-bit PCM samples stored in int32 values and returns a new byte slice.
//
// This is a convenience method that allocates the output buffer.
func (e *MultistreamEncoder) EncodeInt24Slice(pcm []int32) ([]byte, error) {
return encodeToOwnedPacket(maxPacketBytesPerStream*e.enc.Streams(), func(data []byte) (int, error) {
return e.EncodeInt24(pcm, data)
})
}