Skip to content

Commit 8a54760

Browse files
committed
VoiceEncoder_Opus.cpp reworked, refactoring, fix Compress
1 parent 5f71fde commit 8a54760

File tree

2 files changed

+67
-52
lines changed

2 files changed

+67
-52
lines changed

revoice/src/VoiceEncoder_Opus.cpp

Lines changed: 64 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
VoiceEncoder_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

2424
bool 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

7272
int 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;

revoice/src/VoiceEncoder_Opus.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ class VoiceEncoder_Opus: public IVoiceCodec {
1818
int m_samplerate;
1919
int m_bitrate;
2020

21-
uint16 m_nCurFrame;
22-
uint16 m_nLastFrame;
21+
uint16 m_nEncodeSeq;
22+
uint16 m_nDecodeSeq;
2323

2424
bool m_PacketLossConcealment;
2525

@@ -31,7 +31,7 @@ class VoiceEncoder_Opus: public IVoiceCodec {
3131
virtual bool Init(int quality);
3232
virtual void Release();
3333
virtual bool ResetState();
34-
virtual int Compress(const char *pUncompressedBytes, int nSamples, char *pCompressed, int maxCompressedBytes, bool bFinal);
34+
virtual int Compress(const char *pUncompressedBytes, int nSamplesIn, char *pCompressed, int maxCompressedBytes, bool bFinal);
3535
virtual int Decompress(const char *pCompressed, int compressedBytes, char *pUncompressed, int maxUncompressedBytes);
3636

3737
int GetNumQueuedEncodingSamples() const { return m_bufOverflowBytes.TellPut() / BYTES_PER_SAMPLE; }

0 commit comments

Comments
 (0)