22
33VoiceEncoder_Opus::VoiceEncoder_Opus () : m_bitrate(32000 ), m_samplerate(8000 )
44{
5- m_nCurFrame = 0 ;
6- m_nLastFrame = 0 ;
5+ m_nEncodeSeq = 0 ;
6+ m_nDecodeSeq = 0 ;
77 m_pEncoder = nullptr ;
88 m_pDecoder = nullptr ;
99}
@@ -23,8 +23,8 @@ VoiceEncoder_Opus::~VoiceEncoder_Opus()
2323
2424bool VoiceEncoder_Opus::Init (int quality)
2525{
26- m_nCurFrame = 0 ;
27- m_nLastFrame = 0 ;
26+ m_nEncodeSeq = 0 ;
27+ m_nDecodeSeq = 0 ;
2828 m_PacketLossConcealment = true ;
2929
3030 int encSizeBytes = opus_encoder_get_size (MAX_CHANNELS);
@@ -71,33 +71,36 @@ bool VoiceEncoder_Opus::ResetState()
7171
7272int VoiceEncoder_Opus::Compress (const char *pUncompressedIn, int nSamplesIn, char *pCompressed, int maxCompressedBytes, bool bFinal)
7373{
74- if ((nSamplesIn + GetNumQueuedEncodingSamples ()) < FRAME_SIZE && !bFinal) {
74+ if ((nSamplesIn + GetNumQueuedEncodingSamples ()) < FRAME_SIZE && !bFinal)
75+ {
7576 m_bufOverflowBytes.Put (pUncompressedIn, nSamplesIn * BYTES_PER_SAMPLE);
7677 return 0 ;
7778 }
7879
7980 int nSamples = nSamplesIn;
80- int nSamplesRemaining = nSamples % FRAME_SIZE;
81+ int nSamplesRemaining = nSamplesIn % FRAME_SIZE;
8182 char *pUncompressed = (char *)pUncompressedIn;
8283
84+ CUtlBuffer buf;
8385 if (m_bufOverflowBytes.TellPut () || (nSamplesRemaining && bFinal))
8486 {
85- CUtlBuffer buf;
8687 buf.Put (m_bufOverflowBytes.Base (), m_bufOverflowBytes.TellPut ());
8788 buf.Put (pUncompressedIn, nSamplesIn * BYTES_PER_SAMPLE);
8889 m_bufOverflowBytes.Clear ();
8990
90- nSamples = (buf.TellPut () / 2 );
91- nSamplesRemaining = nSamples % FRAME_SIZE;
91+ nSamples = (buf.TellPut () / BYTES_PER_SAMPLE );
92+ nSamplesRemaining = (buf. TellPut () / BYTES_PER_SAMPLE) % FRAME_SIZE;
9293
9394 if (bFinal && nSamplesRemaining)
9495 {
95- for (int i = FRAME_SIZE - nSamplesRemaining; i > 0 ; i--) {
96+ // fill samples with silence
97+ for (int i = FRAME_SIZE - nSamplesRemaining; i > 0 ; i--)
98+ {
9699 buf.PutShort (0 );
97100 }
98101
99- nSamples = (buf.TellPut () / 2 );
100- nSamplesRemaining = nSamples % FRAME_SIZE;
102+ nSamples = (buf.TellPut () / BYTES_PER_SAMPLE );
103+ nSamplesRemaining = (buf. TellPut () / BYTES_PER_SAMPLE) % FRAME_SIZE;
101104 }
102105
103106 pUncompressed = (char *)buf.Base ();
@@ -108,34 +111,39 @@ int VoiceEncoder_Opus::Compress(const char *pUncompressedIn, int nSamplesIn, cha
108111 char *pWritePos = pCompressed;
109112 char *pWritePosMax = pCompressed + maxCompressedBytes;
110113
111- int nBlocks = nSamples - nSamplesRemaining;
112- while (nBlocks > 0 )
114+ int nChunks = nSamples - nSamplesRemaining;
115+ if (nChunks > 0 )
113116 {
114- uint16 *pWritePayloadSize = (uint16 *)pWritePos;
115- pWritePos += sizeof (uint16); // leave 2 bytes for the frame size (will be written after encoding)
116-
117- if (m_PacketLossConcealment)
117+ int nRemainingSamples = (nChunks - 1 ) / FRAME_SIZE + 1 ;
118+ do
118119 {
119- *(uint16 *)pWritePos = m_nCurFrame++;
120- pWritePos += sizeof (uint16);
121- }
120+ uint16 *pWritePayloadSize = (uint16 *)pWritePos;
121+ pWritePos += sizeof (uint16); // leave 2 bytes for the frame size (will be written after encoding)
122+
123+ if (m_PacketLossConcealment)
124+ {
125+ *(uint16 *)pWritePos = m_nEncodeSeq++;
126+ pWritePos += sizeof (uint16);
127+ }
122128
123- int nBytes = (pWritePosMax - pWritePos > 0x7FFF ) ? 0x7FFF : (pWritePosMax - pWritePos);
124- int nWriteBytes = opus_encode (m_pEncoder, (const opus_int16 *)psRead, FRAME_SIZE, (unsigned char *)pWritePos, nBytes);
129+ int nBytes = (( pWritePosMax - pWritePos) < 0x7FFF ) ? (pWritePosMax - pWritePos) : 0x7FFF ;
130+ int nWriteBytes = opus_encode (m_pEncoder, (const opus_int16 *)psRead, FRAME_SIZE, (unsigned char *)pWritePos, nBytes);
125131
126- nBlocks -= FRAME_SIZE;
127- psRead += FRAME_SIZE * 2 ;
128- pWritePos += nWriteBytes;
132+ psRead += MAX_FRAME_SIZE;
133+ pWritePos += nWriteBytes;
129134
130- *pWritePayloadSize = nWriteBytes;
135+ nRemainingSamples--;
136+ *pWritePayloadSize = nWriteBytes;
137+ }
138+ while (nRemainingSamples > 0 );
131139 }
132140
133141 m_bufOverflowBytes.Clear ();
134142
135143 if (nSamplesRemaining)
136144 {
137- Assert ((char *)psRead == pUncompressed + ((nSamples - nSamplesRemaining) * sizeof (uint16 )));
138- m_bufOverflowBytes.Put (pUncompressed + ((nSamples - nSamplesRemaining) * sizeof (uint16 )), 2 * nSamplesRemaining );
145+ Assert ((char *)psRead == pUncompressed + ((nSamples - nSamplesRemaining) * sizeof (int16 )));
146+ m_bufOverflowBytes.Put (pUncompressed + ((nSamples - nSamplesRemaining) * sizeof (int16 )), nSamplesRemaining * BYTES_PER_SAMPLE );
139147 }
140148
141149 if (bFinal)
@@ -148,7 +156,7 @@ int VoiceEncoder_Opus::Compress(const char *pUncompressedIn, int nSamplesIn, cha
148156 pWritePos += sizeof (uint16);
149157 }
150158
151- m_nCurFrame = 0 ;
159+ m_nEncodeSeq = 0 ;
152160 }
153161
154162 return pWritePos - pCompressed;
@@ -162,81 +170,88 @@ int VoiceEncoder_Opus::Decompress(const char *pCompressed, int compressedBytes,
162170 char *pWritePos = pUncompressed;
163171 char *pWritePosMax = &pUncompressed[maxUncompressedBytes];
164172
165- int nPayloadSize;
166-
167173 while (pReadPos < pReadPosMax)
168174 {
169- nPayloadSize = *(uint16 *)pReadPos;
175+ uint16 nPayloadSize = *(uint16 *)pReadPos;
170176 pReadPos += sizeof (uint16);
171177
172- if (nPayloadSize == 0xFFFF ) {
173- m_nLastFrame = 0 ;
178+ if (nPayloadSize == 0xFFFF )
179+ {
174180 ResetState ();
181+ m_nDecodeSeq = 0 ;
175182 break ;
176183 }
177184
178185 if (m_PacketLossConcealment)
179186 {
180- uint16 nCurFrame = *(uint16 *)pReadPos;
187+ uint16 nCurSeq = *(uint16 *)pReadPos;
181188 pReadPos += sizeof (uint16);
182189
183- if (nCurFrame < m_nLastFrame )
190+ if (nCurSeq < m_nDecodeSeq )
184191 {
185192 ResetState ();
186193 }
187- else if (nCurFrame != m_nLastFrame )
194+ else if (nCurSeq != m_nDecodeSeq )
188195 {
189- int nPacketLoss = nCurFrame - m_nLastFrame ;
196+ int nPacketLoss = nCurSeq - m_nDecodeSeq ;
190197 if (nPacketLoss > MAX_PACKET_LOSS) {
191198 nPacketLoss = MAX_PACKET_LOSS;
192199 }
193200
194201 for (int i = 0 ; i < nPacketLoss; i++)
195202 {
196- if (pWritePos + (FRAME_SIZE * 2 ) >= pWritePosMax)
203+ if ((pWritePos + MAX_FRAME_SIZE) >= pWritePosMax)
204+ {
205+ Assert (false );
197206 break ;
207+ }
198208
199209 int nBytes = opus_decode (m_pDecoder, 0 , 0 , (opus_int16 *)pWritePos, FRAME_SIZE, 0 );
200210 if (nBytes <= 0 )
201211 {
202212 // raw corrupted
203- return 0 ;
213+ continue ;
204214 }
205215
206- pWritePos += nBytes * 2 ;
216+ pWritePos += nBytes * BYTES_PER_SAMPLE ;
207217 }
208218 }
209219
210- m_nLastFrame = nCurFrame + 1 ;
220+ m_nDecodeSeq = nCurSeq + 1 ;
211221 }
212222
213- if ((pReadPos + nPayloadSize) > pReadPosMax) {
223+ if ((pReadPos + nPayloadSize) > pReadPosMax)
224+ {
214225 Assert (false );
215226 break ;
216227 }
217228
218- if (pWritePosMax < pWritePos + (FRAME_SIZE * 2 )) {
229+ if ((pWritePos + MAX_FRAME_SIZE) > pWritePosMax)
230+ {
219231 Assert (false );
220232 break ;
221233 }
222234
223- memset (pWritePos, 0 , FRAME_SIZE * 2 );
235+ memset (pWritePos, 0 , MAX_FRAME_SIZE );
224236
225237 if (nPayloadSize == 0 )
226238 {
227- pWritePos += FRAME_SIZE * 2 ;
239+ // DTX (discontinued transmission)
240+ pWritePos += MAX_FRAME_SIZE;
228241 continue ;
229242 }
230243
231244 int nBytes = opus_decode (m_pDecoder, (const unsigned char *)pReadPos, nPayloadSize, (opus_int16 *)pWritePos, FRAME_SIZE, 0 );
232245 if (nBytes <= 0 )
233246 {
234247 // raw corrupted
235- return 0 ;
248+ }
249+ else
250+ {
251+ pWritePos += nBytes * BYTES_PER_SAMPLE;
236252 }
237253
238254 pReadPos += nPayloadSize;
239- pWritePos += nBytes * 2 ;
240255 }
241256
242257 return (pWritePos - pUncompressed) / BYTES_PER_SAMPLE;
0 commit comments