@babblevoice/projectrtp 2.5.20 → 2.5.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/lib/server.js +9 -1
- package/package.json +1 -1
- package/src/globals.h +3 -0
- package/src/projectrtpchannel.cpp +16 -2
- package/src/projectrtpchannelmux.cpp +17 -7
- package/src/projectrtpchannelmux.h +4 -2
- package/src/projectrtpcodecx.cpp +76 -93
- package/src/projectrtpcodecx.h +1 -3
- package/src/projectrtprawsound.cpp +34 -70
- package/src/projectrtpsoundfile.cpp +62 -52
- package/src/projectrtpsoundfile.h +1 -0
- package/test/interface/pcap.js +2 -2
- package/test/interface/pcaps/440hzinbackgroundg722.pcap +0 -0
- package/test/interface/projectrtpchannel.js +4 -9
- package/test/interface/projectrtpdtmf.js +147 -6
- package/test/interface/projectrtpmix.js +77 -6
- package/test/interface/projectrtpsound.js +145 -91
- package/test/interface/transcode.js +164 -0
- package/test/util/rtp.js +17 -0
package/README.md
CHANGED
|
@@ -60,7 +60,7 @@ If you wish to build outsode of a Docker image, there are npm target scripts for
|
|
|
60
60
|
|
|
61
61
|
```bash
|
|
62
62
|
docker buildx prune
|
|
63
|
-
docker buildx build --platform linux/amd64,linux/arm64 -t tinpotnick/projectrtp:2.
|
|
63
|
+
docker buildx build --platform linux/amd64,linux/arm64 -t tinpotnick/projectrtp:2.5.23_beta4 . --push
|
|
64
64
|
```
|
|
65
65
|
|
|
66
66
|
## Example scripts
|
package/lib/server.js
CHANGED
|
@@ -277,7 +277,15 @@ class channel {
|
|
|
277
277
|
|
|
278
278
|
options.channel = "open"
|
|
279
279
|
|
|
280
|
-
const resolvepromise = new Promise( ( resolve ) => {
|
|
280
|
+
const resolvepromise = new Promise( ( resolve, reject ) => {
|
|
281
|
+
|
|
282
|
+
if ( 0 < nodes.size ) {
|
|
283
|
+
const node = randomenode( options.nodeinstance )
|
|
284
|
+
const request = JSON.parse( JSON.stringify( options ) )
|
|
285
|
+
request.channel = "open"
|
|
286
|
+
channel._createforlisten( request, node, cb, resolve, reject )
|
|
287
|
+
return
|
|
288
|
+
}
|
|
281
289
|
|
|
282
290
|
const newchannel = new channel()
|
|
283
291
|
if( cb ) newchannel.em.on( "all", cb )
|
package/package.json
CHANGED
package/src/globals.h
CHANGED
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
#define G711PAYLOADBYTES 160
|
|
10
10
|
#define G722PAYLOADBYTES 160
|
|
11
11
|
#define L16PAYLOADSAMPLES 160
|
|
12
|
+
#define G711PAYLOADSAMPLES 160
|
|
13
|
+
#define G722PAYLOADSAMPLES 160
|
|
14
|
+
#define L1616PAYLOADSAMPLES 320
|
|
12
15
|
#define L16NARROWBANDBYTES 320
|
|
13
16
|
#define L16WIDEBANDBYTES 640
|
|
14
17
|
#define ILBC20PAYLOADBYTES 38
|
|
@@ -655,7 +655,7 @@ bool projectrtpchannel::checkfordtmf( rtppacket *src ) {
|
|
|
655
655
|
uint16_t sn = src->getsequencenumber();
|
|
656
656
|
|
|
657
657
|
if( 0 != this->rfc2833pt &&
|
|
658
|
-
src->getpayloadtype() ==
|
|
658
|
+
src->getpayloadtype() == RFC2833PAYLOADTYPE ) {
|
|
659
659
|
|
|
660
660
|
if( src->getpayloadlength() >= 4 ) {
|
|
661
661
|
/* We have to look for DTMF events handling issues like missing events - such as the marker or end bit */
|
|
@@ -811,7 +811,8 @@ void projectrtpchannel::correctaddress( void ) {
|
|
|
811
811
|
*/
|
|
812
812
|
void projectrtpchannel::correctssrc( uint32_t ssrc ) {
|
|
813
813
|
if( !this->receivedrtp ) {
|
|
814
|
-
|
|
814
|
+
/* allow settling */
|
|
815
|
+
if( this->inbuff->getpushed() > 5 )this->receivedrtp = true;
|
|
815
816
|
this->ssrcin = ssrc;
|
|
816
817
|
}
|
|
817
818
|
}
|
|
@@ -876,10 +877,21 @@ void projectrtpchannel::readsomertp( void ) {
|
|
|
876
877
|
goto readsomemore;
|
|
877
878
|
}
|
|
878
879
|
|
|
880
|
+
/* TODO ZRTP? */
|
|
881
|
+
if( buf->getpacketextension() ) {
|
|
882
|
+
this->receivedpkskip++;
|
|
883
|
+
goto readsomemore;
|
|
884
|
+
}
|
|
885
|
+
|
|
879
886
|
this->tickswithnortpcount = 0;
|
|
880
887
|
|
|
881
888
|
this->correctaddress();
|
|
889
|
+
|
|
890
|
+
/*
|
|
891
|
+
after speaking with Magrathea - more streams are changing ssrc without notice mid-stream
|
|
892
|
+
for now do not check.
|
|
882
893
|
this->correctssrc( buf->getssrc() );
|
|
894
|
+
*/
|
|
883
895
|
|
|
884
896
|
if( this->confirmedrtpsenderendpoint != this->rtpsenderendpoint ) {
|
|
885
897
|
/* After the first packet - we only accept data from the verified source */
|
|
@@ -887,10 +899,12 @@ void projectrtpchannel::readsomertp( void ) {
|
|
|
887
899
|
goto readsomemore;
|
|
888
900
|
}
|
|
889
901
|
|
|
902
|
+
/*
|
|
890
903
|
if( buf->getssrc() != this->ssrcin ) {
|
|
891
904
|
this->receivedpkskip++;
|
|
892
905
|
goto readsomemore;
|
|
893
906
|
}
|
|
907
|
+
*/
|
|
894
908
|
|
|
895
909
|
/* dynamic payload types */
|
|
896
910
|
auto pt = buf->getpayloadtype();
|
|
@@ -15,7 +15,8 @@ projectchannelmux::projectchannelmux( boost::asio::io_context &iocontext ):
|
|
|
15
15
|
newchannels(),
|
|
16
16
|
newchannelslock( false ),
|
|
17
17
|
added(),
|
|
18
|
-
subtracted()
|
|
18
|
+
subtracted(),
|
|
19
|
+
active( false ) {
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
projectchannelmux::~projectchannelmux() {
|
|
@@ -29,22 +30,24 @@ projectchannelmux::pointer projectchannelmux::create( boost::asio::io_context &i
|
|
|
29
30
|
void projectchannelmux::mixall( void ) {
|
|
30
31
|
/* First decide on a common rate (if we only have 8K channels it is pointless
|
|
31
32
|
upsampling them all and wasting resources) */
|
|
32
|
-
int
|
|
33
|
+
int l16format = L168KPAYLOADTYPE;
|
|
33
34
|
size_t insize = L16PAYLOADSAMPLES;
|
|
34
35
|
|
|
35
36
|
for( auto& chan: this->channels ) {
|
|
36
37
|
switch( chan->codec ) {
|
|
37
38
|
case G722PAYLOADTYPE:
|
|
38
39
|
case L1616KPAYLOADTYPE: {
|
|
39
|
-
|
|
40
|
+
l16format = L1616KPAYLOADTYPE;
|
|
41
|
+
insize = L1616PAYLOADSAMPLES;
|
|
40
42
|
goto endofforloop;
|
|
41
43
|
}
|
|
42
44
|
}
|
|
43
45
|
}
|
|
44
46
|
endofforloop:
|
|
45
47
|
|
|
46
|
-
|
|
47
|
-
this->
|
|
48
|
+
/* allocate the max needed */
|
|
49
|
+
this->added.malloc( insize, sizeof( int16_t ), l16format );
|
|
50
|
+
this->subtracted.malloc( insize, sizeof( int16_t ), l16format );
|
|
48
51
|
this->added.zero();
|
|
49
52
|
|
|
50
53
|
/* We first have to add them all up */
|
|
@@ -186,6 +189,8 @@ Our timer handler.
|
|
|
186
189
|
void projectchannelmux::handletick( const boost::system::error_code& error ) {
|
|
187
190
|
if ( error == boost::asio::error::operation_aborted ) return;
|
|
188
191
|
|
|
192
|
+
if( !this->active ) return;
|
|
193
|
+
|
|
189
194
|
this->checkfornewmixes();
|
|
190
195
|
|
|
191
196
|
/* Check for channels which have request removal */
|
|
@@ -193,6 +198,7 @@ void projectchannelmux::handletick( const boost::system::error_code& error ) {
|
|
|
193
198
|
|
|
194
199
|
if( 0 == this->channels.size() ) {
|
|
195
200
|
/* We're done */
|
|
201
|
+
this->active = false;
|
|
196
202
|
return;
|
|
197
203
|
}
|
|
198
204
|
|
|
@@ -233,6 +239,10 @@ void projectchannelmux::setnexttick( void ) {
|
|
|
233
239
|
}
|
|
234
240
|
|
|
235
241
|
void projectchannelmux::go( void ) {
|
|
242
|
+
|
|
243
|
+
if( this->active ) return;
|
|
244
|
+
this->active = true;
|
|
245
|
+
|
|
236
246
|
this->nexttick = std::chrono::high_resolution_clock::now() + std::chrono::milliseconds( 20 );
|
|
237
247
|
|
|
238
248
|
this->tick.expires_after( this->nexttick - std::chrono::high_resolution_clock::now() );
|
|
@@ -315,8 +325,8 @@ void projectchannelmux::postrtpdata( projectrtpchannelptr srcchan, projectrtpcha
|
|
|
315
325
|
return;
|
|
316
326
|
}
|
|
317
327
|
|
|
318
|
-
if( src->getpayloadtype() ==
|
|
319
|
-
dst->setpayloadtype(
|
|
328
|
+
if( src->getpayloadtype() == RFC2833PAYLOADTYPE ) {
|
|
329
|
+
dst->setpayloadtype( dstchan->rfc2833pt );
|
|
320
330
|
dst->copy( src );
|
|
321
331
|
} else {
|
|
322
332
|
srcchan->incodec << codecx::next;
|
|
@@ -22,8 +22,8 @@ typedef std::shared_ptr< projectrtpchannel > projectrtpchannelptr;
|
|
|
22
22
|
typedef std::list< projectrtpchannelptr > projectchanptrlist;
|
|
23
23
|
|
|
24
24
|
class projectchannelmux:
|
|
25
|
-
public std::enable_shared_from_this< projectchannelmux >
|
|
26
|
-
|
|
25
|
+
public std::enable_shared_from_this< projectchannelmux > {
|
|
26
|
+
|
|
27
27
|
public:
|
|
28
28
|
projectchannelmux( boost::asio::io_context &iocontext );
|
|
29
29
|
~projectchannelmux();
|
|
@@ -58,6 +58,8 @@ private:
|
|
|
58
58
|
|
|
59
59
|
rawsound added;
|
|
60
60
|
rawsound subtracted;
|
|
61
|
+
|
|
62
|
+
bool active;
|
|
61
63
|
};
|
|
62
64
|
|
|
63
65
|
#endif /* PROJECTRTPCHANNELMUX_H */
|
package/src/projectrtpcodecx.cpp
CHANGED
|
@@ -87,7 +87,6 @@ codecx::codecx() :
|
|
|
87
87
|
ilbcencoder( nullptr ),
|
|
88
88
|
ilbcdecoder( nullptr ),
|
|
89
89
|
lpfilter(),
|
|
90
|
-
resamplelastsample( 0 ),
|
|
91
90
|
l168kref(),
|
|
92
91
|
l1616kref(),
|
|
93
92
|
pcmaref(),
|
|
@@ -146,7 +145,6 @@ Do enough to manage missing packets.
|
|
|
146
145
|
void codecx::restart( void ) {
|
|
147
146
|
this->lpfilter.reset();
|
|
148
147
|
this->dcpowerfilter.reset();
|
|
149
|
-
this->resamplelastsample = 0;
|
|
150
148
|
this->_hasdata = false;
|
|
151
149
|
}
|
|
152
150
|
|
|
@@ -160,19 +158,17 @@ bool codecx::alaw2ulaw( void ) {
|
|
|
160
158
|
if( this->pcmaref.isdirty() ) return false;
|
|
161
159
|
|
|
162
160
|
uint8_t *inbufptr, *outbufptr;
|
|
163
|
-
size_t insize;
|
|
164
161
|
|
|
165
|
-
insize = this->pcmaref.size();
|
|
166
162
|
inbufptr = this->pcmaref.c_str();
|
|
167
163
|
outbufptr = this->pcmuref.c_str();
|
|
168
|
-
this->pcmuref.size(
|
|
164
|
+
this->pcmuref.size( G711PAYLOADBYTES );
|
|
169
165
|
|
|
170
166
|
if( nullptr == outbufptr || nullptr == inbufptr ) {
|
|
171
167
|
std::cerr << "PCMA NULLPTR shouldn't happen (" << (void*)outbufptr << ", " << (void*)inbufptr << ")" << std::endl;
|
|
172
168
|
return false;
|
|
173
169
|
}
|
|
174
170
|
|
|
175
|
-
for( size_t i = 0; i <
|
|
171
|
+
for( size_t i = 0; i < G711PAYLOADBYTES; i++ ) {
|
|
176
172
|
*outbufptr = alaw_to_ulaw_table[ *inbufptr ];
|
|
177
173
|
inbufptr++;
|
|
178
174
|
outbufptr++;
|
|
@@ -187,19 +183,17 @@ bool codecx::ulaw2alaw( void ) {
|
|
|
187
183
|
if( this->pcmuref.isdirty() ) return false;
|
|
188
184
|
|
|
189
185
|
uint8_t *inbufptr, *outbufptr;
|
|
190
|
-
size_t insize;
|
|
191
186
|
|
|
192
|
-
insize = this->pcmuref.size();
|
|
193
187
|
inbufptr = this->pcmuref.c_str();
|
|
194
188
|
outbufptr = this->pcmaref.c_str();
|
|
195
|
-
this->pcmaref.size(
|
|
189
|
+
this->pcmaref.size( G711PAYLOADBYTES );
|
|
196
190
|
|
|
197
191
|
if( nullptr == outbufptr || nullptr == inbufptr ) {
|
|
198
192
|
std::cerr << "PCMU NULLPTR shouldn't happen(" << (void*)outbufptr << ", " << (void*)inbufptr << ")" << std::endl;
|
|
199
193
|
return false;
|
|
200
194
|
}
|
|
201
195
|
|
|
202
|
-
for( size_t i = 0; i <
|
|
196
|
+
for( size_t i = 0; i < G711PAYLOADBYTES; i++ ) {
|
|
203
197
|
*outbufptr = ulaw_to_alaw_table[ *inbufptr ];
|
|
204
198
|
inbufptr++;
|
|
205
199
|
outbufptr++;
|
|
@@ -217,25 +211,22 @@ bool codecx::g711tol16( void )
|
|
|
217
211
|
{
|
|
218
212
|
uint8_t *in;
|
|
219
213
|
int16_t *convert;
|
|
220
|
-
size_t insize;
|
|
221
214
|
|
|
222
215
|
if( this->pcmaref.size() > 0 && !this->pcmaref.isdirty() ) {
|
|
223
216
|
in = this->pcmaref.c_str();
|
|
224
217
|
convert = _pcmatol16;
|
|
225
|
-
insize = this->pcmaref.size();
|
|
226
218
|
} else if ( this->pcmuref.size() > 0 && !this->pcmuref.isdirty() ) {
|
|
227
219
|
in = this->pcmuref.c_str();
|
|
228
220
|
convert = _pcmutol16;
|
|
229
|
-
insize = this->pcmuref.size();
|
|
230
221
|
} else {
|
|
231
222
|
return false;
|
|
232
223
|
}
|
|
233
224
|
|
|
234
|
-
this->l168kref.malloc(
|
|
225
|
+
this->l168kref.malloc( G711PAYLOADSAMPLES, sizeof( int16_t ), L168KPAYLOADTYPE );
|
|
235
226
|
|
|
236
227
|
int16_t *out = ( int16_t * ) this->l168kref.c_str();
|
|
237
228
|
|
|
238
|
-
for( size_t i = 0; i <
|
|
229
|
+
for( size_t i = 0; i < G711PAYLOADSAMPLES; i++ ) {
|
|
239
230
|
*out = convert[ *in ];
|
|
240
231
|
in++;
|
|
241
232
|
out++;
|
|
@@ -257,11 +248,10 @@ bool codecx::l16topcma( void )
|
|
|
257
248
|
uint8_t *out = this->pcmaref.c_str();
|
|
258
249
|
|
|
259
250
|
int16_t *in;
|
|
260
|
-
size_t l168klength = this->l168kref.size();
|
|
261
251
|
in = ( int16_t * ) this->l168kref.c_str();
|
|
262
252
|
|
|
263
253
|
uint16_t index;
|
|
264
|
-
for( size_t i = 0; i <
|
|
254
|
+
for( size_t i = 0; i < G711PAYLOADBYTES; i++ ) {
|
|
265
255
|
index = *in + 32768;
|
|
266
256
|
*out = _l16topcma[ index ];
|
|
267
257
|
in++;
|
|
@@ -281,11 +271,10 @@ bool codecx::l16topcmu( void ) {
|
|
|
281
271
|
uint8_t *out = this->pcmuref.c_str();;
|
|
282
272
|
|
|
283
273
|
int16_t *in;
|
|
284
|
-
size_t l168klength = this->l168kref.size();
|
|
285
274
|
in = ( int16_t * ) this->l168kref.c_str();
|
|
286
275
|
|
|
287
276
|
uint16_t index;
|
|
288
|
-
for( size_t i = 0; i <
|
|
277
|
+
for( size_t i = 0; i < G711PAYLOADBYTES; i++ ) {
|
|
289
278
|
index = *in + 32768;
|
|
290
279
|
*out = _l16topcmu[ index ];
|
|
291
280
|
in++;
|
|
@@ -315,43 +304,16 @@ bool codecx::ilbctol16( void ) {
|
|
|
315
304
|
|
|
316
305
|
int16_t l168klength = WebRtcIlbcfix_Decode( this->ilbcdecoder,
|
|
317
306
|
( ilbcencodedval ) this->ilbcref.c_str(),
|
|
318
|
-
|
|
307
|
+
ILBC20PAYLOADBYTES,
|
|
319
308
|
( ilbcdecodedval )this->l168kref.c_str(),
|
|
320
309
|
&speechType
|
|
321
310
|
);
|
|
322
311
|
|
|
323
312
|
if( -1 == l168klength ) {
|
|
324
|
-
this->l168kref.size( 0 );
|
|
325
313
|
return false;
|
|
326
314
|
}
|
|
327
315
|
|
|
328
316
|
this->l168kref.dirty( false );
|
|
329
|
-
this->l168kref.size( l168klength );
|
|
330
|
-
return true;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
/*!md
|
|
334
|
-
## l16tog722
|
|
335
|
-
As it says.
|
|
336
|
-
*/
|
|
337
|
-
bool codecx::l16tog722( void ) {
|
|
338
|
-
if( 0 == this->l1616kref.size() ) return false;
|
|
339
|
-
if( this->l1616kref.isdirty() ) return false;
|
|
340
|
-
|
|
341
|
-
if( nullptr == this->g722encoder ) {
|
|
342
|
-
this->g722encoder = g722_encode_init( NULL, 64000, G722_PACKED );
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
int len = g722_encode( this->g722encoder, this->g722ref.c_str(), ( int16_t * ) this->l1616kref.c_str(), this->g722ref.size() * 2 );
|
|
346
|
-
|
|
347
|
-
if( len > 0 ) {
|
|
348
|
-
this->g722ref.size( len );
|
|
349
|
-
this->g722ref.dirty( false );
|
|
350
|
-
} else {
|
|
351
|
-
std::cerr << "g722_encode didn't encode any data" << std::endl;
|
|
352
|
-
this->g722ref.size( 0 );
|
|
353
|
-
}
|
|
354
|
-
|
|
355
317
|
return true;
|
|
356
318
|
}
|
|
357
319
|
|
|
@@ -375,11 +337,10 @@ bool codecx::l16toilbc( void ) {
|
|
|
375
337
|
|
|
376
338
|
int16_t len = WebRtcIlbcfix_Encode( this->ilbcencoder,
|
|
377
339
|
( ilbcdecodedval ) this->l168kref.c_str(),
|
|
378
|
-
|
|
340
|
+
L16PAYLOADSAMPLES,
|
|
379
341
|
( ilbcencodedval ) this->ilbcref.c_str()
|
|
380
342
|
);
|
|
381
343
|
if ( len > 0 ) {
|
|
382
|
-
this->ilbcref.size( len );
|
|
383
344
|
this->ilbcref.dirty( false );
|
|
384
345
|
return true;
|
|
385
346
|
}
|
|
@@ -390,6 +351,33 @@ bool codecx::l16toilbc( void ) {
|
|
|
390
351
|
}
|
|
391
352
|
|
|
392
353
|
|
|
354
|
+
/*!md
|
|
355
|
+
## l16tog722
|
|
356
|
+
As it says.
|
|
357
|
+
*/
|
|
358
|
+
bool codecx::l16tog722( void ) {
|
|
359
|
+
|
|
360
|
+
if( 0 == this->l1616kref.size() ) return false;
|
|
361
|
+
if( this->l1616kref.isdirty() ) return false;
|
|
362
|
+
|
|
363
|
+
if( nullptr == this->g722encoder ) {
|
|
364
|
+
this->g722encoder = g722_encode_init( NULL, 64000, G722_PACKED );
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// TODO - when we convert to g722 - 722 buffer is always output -so malloc need sto be able to detect that.
|
|
368
|
+
//this->g722ref.malloc( G722PAYLOADSAMPLES, sizeof( int8_t ), G722PAYLOADTYPE );
|
|
369
|
+
|
|
370
|
+
int len = g722_encode( this->g722encoder, this->g722ref.c_str(), ( int16_t * ) this->l1616kref.c_str(), L1616PAYLOADSAMPLES );
|
|
371
|
+
|
|
372
|
+
if( 160 != len ) {
|
|
373
|
+
std::cerr << "g722_encode didn't encode correct length of data" << std::endl;
|
|
374
|
+
return false;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
this->g722ref.dirty( false );
|
|
378
|
+
return true;
|
|
379
|
+
}
|
|
380
|
+
|
|
393
381
|
/*!md
|
|
394
382
|
## g722tol16
|
|
395
383
|
As it says.
|
|
@@ -398,8 +386,7 @@ bool codecx::g722tol16( void ) {
|
|
|
398
386
|
if( 0 == this->g722ref.size() ) return false;
|
|
399
387
|
if( this->g722ref.isdirty() ) return false;
|
|
400
388
|
|
|
401
|
-
|
|
402
|
-
this->l1616kref.malloc( this->g722ref.size(), sizeof( int16_t ), L1616KPAYLOADTYPE );
|
|
389
|
+
this->l1616kref.malloc( L1616PAYLOADSAMPLES, sizeof( int16_t ), L1616KPAYLOADTYPE );
|
|
403
390
|
|
|
404
391
|
if( nullptr == this->g722decoder ) {
|
|
405
392
|
this->g722decoder = g722_decode_init( NULL, 64000, G722_PACKED );
|
|
@@ -411,9 +398,10 @@ bool codecx::g722tol16( void ) {
|
|
|
411
398
|
size_t l1616klength = g722_decode( this->g722decoder,
|
|
412
399
|
( int16_t * ) this->l1616kref.c_str(),
|
|
413
400
|
this->g722ref.c_str(),
|
|
414
|
-
|
|
401
|
+
G722PAYLOADBYTES );
|
|
415
402
|
|
|
416
|
-
|
|
403
|
+
if( 320 != l1616klength ) return false;
|
|
404
|
+
|
|
417
405
|
this->l1616kref.dirty( false );
|
|
418
406
|
return true;
|
|
419
407
|
}
|
|
@@ -423,23 +411,19 @@ bool codecx::g722tol16( void ) {
|
|
|
423
411
|
Upsample from narrow to wideband. Take each point and interpolate between them. We require the final sample from the last packet to continue the interpolating.
|
|
424
412
|
*/
|
|
425
413
|
bool codecx::l16lowtowideband( void ) {
|
|
426
|
-
size_t l168klength = this->l168kref.size();
|
|
427
414
|
|
|
428
|
-
if( 0 ==
|
|
415
|
+
if( 0 == this->l168kref.size() ) return false;
|
|
429
416
|
if( this->l168kref.isdirty() ) return false;
|
|
430
417
|
|
|
431
|
-
this->l1616kref.malloc(
|
|
418
|
+
this->l1616kref.malloc( L1616PAYLOADSAMPLES, sizeof( int16_t ), L1616KPAYLOADTYPE );
|
|
432
419
|
|
|
433
420
|
int16_t *in = ( int16_t * ) this->l168kref.c_str();
|
|
434
421
|
int16_t *out = ( int16_t * ) this->l1616kref.c_str();
|
|
435
422
|
|
|
436
|
-
for( size_t i = 0; i <
|
|
437
|
-
*out = (
|
|
438
|
-
this->resamplelastsample = *in;
|
|
423
|
+
for( size_t i = 0; i < L16PAYLOADSAMPLES; i++ ) {
|
|
424
|
+
*out = this->lpfilter.execute( *in );
|
|
439
425
|
out++;
|
|
440
|
-
|
|
441
|
-
*out = *in;
|
|
442
|
-
|
|
426
|
+
*out = this->lpfilter.execute( 0 );
|
|
443
427
|
out++;
|
|
444
428
|
in++;
|
|
445
429
|
}
|
|
@@ -454,10 +438,16 @@ Search for the relevent data and convert as necessary.
|
|
|
454
438
|
*/
|
|
455
439
|
bool codecx::requirewideband( void ) {
|
|
456
440
|
if( 0 != this->l1616kref.size() && !this->l1616kref.isdirty() ) return true;
|
|
441
|
+
|
|
442
|
+
if( 0 != this->l168kref.size() && !this->l168kref.isdirty() ) {
|
|
443
|
+
return this->l16lowtowideband();
|
|
444
|
+
}
|
|
445
|
+
|
|
457
446
|
if( this->g722tol16() ) return true;
|
|
458
|
-
if( !this->g711tol16() )
|
|
459
|
-
|
|
460
|
-
|
|
447
|
+
if( !this->g711tol16() ) {
|
|
448
|
+
if( !this->ilbctol16() ) {
|
|
449
|
+
return false;
|
|
450
|
+
}
|
|
461
451
|
}
|
|
462
452
|
|
|
463
453
|
return this->l16lowtowideband();
|
|
@@ -467,22 +457,20 @@ bool codecx::requirewideband( void ) {
|
|
|
467
457
|
## l16widetolowband
|
|
468
458
|
Downsample our L16 wideband samples to 8K. Pass through filter then grab every other sample.
|
|
469
459
|
*/
|
|
470
|
-
bool codecx::l16widetonarrowband( void )
|
|
471
|
-
{
|
|
472
|
-
size_t l1616klength = this->l1616kref.size();
|
|
460
|
+
bool codecx::l16widetonarrowband( void ) {
|
|
473
461
|
|
|
474
|
-
if( 0 ==
|
|
462
|
+
if( 0 == this->l1616kref.size() ) return false;
|
|
475
463
|
if( this->l1616kref.isdirty() ) return false;
|
|
476
464
|
|
|
477
|
-
this->l168kref.malloc(
|
|
465
|
+
this->l168kref.malloc( L16PAYLOADSAMPLES, sizeof( int16_t ), L168KPAYLOADTYPE );
|
|
478
466
|
|
|
479
467
|
int16_t *out = ( int16_t * ) this->l168kref.c_str();
|
|
480
468
|
int16_t *in = ( int16_t * ) this->l1616kref.c_str();
|
|
481
469
|
|
|
482
|
-
for( size_t i = 0; i <
|
|
483
|
-
lpfilter.execute( *in );
|
|
470
|
+
for( size_t i = 0; i < L16PAYLOADSAMPLES; i++ ) {
|
|
471
|
+
this->lpfilter.execute( *in );
|
|
484
472
|
in++;
|
|
485
|
-
*out = lpfilter.execute( *in );
|
|
473
|
+
*out = this->lpfilter.execute( *in );
|
|
486
474
|
in++;
|
|
487
475
|
out++;
|
|
488
476
|
}
|
|
@@ -495,9 +483,13 @@ bool codecx::l16widetonarrowband( void )
|
|
|
495
483
|
## requirenarrowband
|
|
496
484
|
Search for the relevent data and convert as necessary.
|
|
497
485
|
*/
|
|
498
|
-
bool codecx::requirenarrowband( void )
|
|
499
|
-
{
|
|
486
|
+
bool codecx::requirenarrowband( void ) {
|
|
500
487
|
if( 0 != this->l168kref.size() && !this->l168kref.isdirty() ) return true;
|
|
488
|
+
|
|
489
|
+
if( 0 != this->l1616kref.size() && !this->l1616kref.isdirty() ) {
|
|
490
|
+
return this->l16widetonarrowband();
|
|
491
|
+
}
|
|
492
|
+
|
|
501
493
|
if( this->g711tol16() ) return true;
|
|
502
494
|
if( this->ilbctol16() ) return true;
|
|
503
495
|
this->g722tol16();
|
|
@@ -628,52 +620,43 @@ We pass a packet in, then we can take multiple out - i.e. we may want different
|
|
|
628
620
|
|
|
629
621
|
Have a think about if this is where we want to mix audio data.
|
|
630
622
|
*/
|
|
631
|
-
codecx& operator << ( codecx& c, rtppacket& pk )
|
|
632
|
-
{
|
|
623
|
+
codecx& operator << ( codecx& c, rtppacket& pk ) {
|
|
633
624
|
c.inpkcount++;
|
|
634
625
|
rawsound r = rawsound( pk );
|
|
635
626
|
c << r;
|
|
636
627
|
return c;
|
|
637
628
|
}
|
|
638
629
|
|
|
639
|
-
codecx& operator << ( codecx& c, rawsound& raw )
|
|
640
|
-
{
|
|
630
|
+
codecx& operator << ( codecx& c, rawsound& raw ) {
|
|
641
631
|
int inpayloadtype = raw.getformat();
|
|
642
632
|
|
|
643
|
-
switch( inpayloadtype )
|
|
644
|
-
|
|
645
|
-
case PCMAPAYLOADTYPE:
|
|
646
|
-
{
|
|
633
|
+
switch( inpayloadtype ) {
|
|
634
|
+
case PCMAPAYLOADTYPE: {
|
|
647
635
|
c.pcmaref = raw;
|
|
648
636
|
c._hasdata = true;
|
|
649
637
|
break;
|
|
650
638
|
}
|
|
651
|
-
case PCMUPAYLOADTYPE:
|
|
652
|
-
{
|
|
639
|
+
case PCMUPAYLOADTYPE: {
|
|
653
640
|
c.pcmuref = raw;
|
|
654
641
|
c._hasdata = true;
|
|
655
642
|
break;
|
|
656
643
|
}
|
|
657
|
-
case ILBCPAYLOADTYPE:
|
|
658
|
-
{
|
|
644
|
+
case ILBCPAYLOADTYPE: {
|
|
659
645
|
c.ilbcref = raw;
|
|
660
646
|
c._hasdata = true;
|
|
661
647
|
break;
|
|
662
648
|
}
|
|
663
|
-
case G722PAYLOADTYPE:
|
|
664
|
-
{
|
|
649
|
+
case G722PAYLOADTYPE: {
|
|
665
650
|
c.g722ref = raw;
|
|
666
651
|
c._hasdata = true;
|
|
667
652
|
break;
|
|
668
653
|
}
|
|
669
|
-
case L168KPAYLOADTYPE:
|
|
670
|
-
{
|
|
654
|
+
case L168KPAYLOADTYPE: {
|
|
671
655
|
c.l168kref = raw;
|
|
672
656
|
c._hasdata = true;
|
|
673
657
|
break;
|
|
674
658
|
}
|
|
675
|
-
case L1616KPAYLOADTYPE:
|
|
676
|
-
{
|
|
659
|
+
case L1616KPAYLOADTYPE: {
|
|
677
660
|
c.l1616kref = raw;
|
|
678
661
|
c._hasdata = true;
|
|
679
662
|
break;
|
package/src/projectrtpcodecx.h
CHANGED
|
@@ -85,10 +85,8 @@ private:
|
|
|
85
85
|
ilbcencinst *ilbcencoder;
|
|
86
86
|
ilbcdecinst *ilbcdecoder;
|
|
87
87
|
|
|
88
|
-
/* If we require downsampling */
|
|
88
|
+
/* If we require up/downsampling */
|
|
89
89
|
lowpass3_4k16k lpfilter;
|
|
90
|
-
/* When we up sample we need to interpolate so need last sample */
|
|
91
|
-
int16_t resamplelastsample;
|
|
92
90
|
|
|
93
91
|
rawsound l168kref;
|
|
94
92
|
rawsound l1616kref;
|