sip-lab 1.28.12 → 1.30.0
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/DEV.md +55 -0
- package/README.md +8 -2
- package/binding.gyp +1 -0
- package/build_deps.sh +2 -1
- package/index.js +7 -0
- package/package.json +1 -1
- package/prebuilds/linux-x64/node.abi102.node +0 -0
- package/prebuilds/linux-x64/node.abi108.node +0 -0
- package/prebuilds/linux-x64/node.abi111.node +0 -0
- package/prebuilds/linux-x64/node.abi115.node +0 -0
- package/prebuilds/linux-x64/node.abi120.node +0 -0
- package/prebuilds/linux-x64/node.abi88.node +0 -0
- package/prebuilds/linux-x64/node.abi93.node +0 -0
- package/samples/100_calls.js +4 -0
- package/samples/16_audio_streams.js +2 -0
- package/samples/183_session_progress.js +2 -0
- package/samples/delayed_media.js +2 -0
- package/samples/four_audio_streams_two_refused.js +7 -4
- package/samples/mrcp_and_audio.simplified_media.js +2 -0
- package/samples/multiple_audio_streams.js +2 -0
- package/samples/refuse_telephone_event.js +3 -0
- package/samples/reinvite_and_dtmf.js +3 -0
- package/samples/reinvite_audio_audio.js +2 -0
- package/samples/reinvite_with_hold_unhold.js +2 -0
- package/samples/rtp_and_srtp.js +3 -0
- package/samples/rtp_and_srtp.rtp_refused.js +3 -0
- package/samples/send_and_receive_bfsk.js.future +171 -0
- package/samples/srtp.js +3 -0
- package/samples/tcp.js +2 -0
- package/samples/text_to_speech.js +3 -0
- package/samples/two_audio_streams.js +4 -0
- package/samples/two_audio_streams.port_zero.js +4 -0
- package/samples_extra/ws_speech_server.bfsk.js +154 -0
- package/samples_extra/ws_speech_server.dtmf.js +5 -21
- package/samples_extra/ws_speech_server.google.js +8 -10
- package/samples_extra/ws_speech_server.send_bfsk.js +156 -0
- package/samples_extra/ws_speech_server.start_bfsk_detection.js.future +164 -0
- package/src/addon.cpp +180 -10
- package/src/event_templates.cpp +8 -0
- package/src/event_templates.hpp +3 -0
- package/src/pjmedia/include/pjmedia/bfsk_det.h +23 -0
- package/src/pjmedia/include/pjmedia/ws_speech_port.h +1 -0
- package/src/pjmedia/src/pjmedia/bfsk_det.c +289 -0
- package/src/pjmedia/src/pjmedia/ws_speech_port.cpp +8 -0
- package/src/sip.cpp +552 -35
- package/src/sip.cpp.old +9236 -0
- package/src/sip.hpp +11 -0
package/src/sip.cpp
CHANGED
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
#include "websock.h"
|
|
25
25
|
|
|
26
26
|
#include "dtmfdet.h"
|
|
27
|
+
#include "bfsk_det.h"
|
|
27
28
|
#include "fax_port.h"
|
|
28
29
|
#include "flite_port.h"
|
|
29
30
|
#include "pocketsphinx_port.h"
|
|
@@ -266,6 +267,7 @@ int ms_timestamp();
|
|
|
266
267
|
bool g_shutting_down;
|
|
267
268
|
|
|
268
269
|
int g_dtmf_inter_digit_timer = 0;
|
|
270
|
+
int g_bfsk_inter_bit_timer = 200;
|
|
269
271
|
|
|
270
272
|
pj_str_t g_sip_ipaddress;
|
|
271
273
|
|
|
@@ -329,7 +331,8 @@ struct ConfBridgePort {
|
|
|
329
331
|
#define FP_FAX 4
|
|
330
332
|
#define FP_SPEECH_SYNTH 5
|
|
331
333
|
#define FP_SPEECH_RECOG 6
|
|
332
|
-
#define
|
|
334
|
+
#define FP_BFSK_DET 7
|
|
335
|
+
#define MAX_FP 8
|
|
333
336
|
|
|
334
337
|
struct AudioEndpoint {
|
|
335
338
|
pjmedia_transport *med_transport;
|
|
@@ -341,6 +344,10 @@ struct AudioEndpoint {
|
|
|
341
344
|
|
|
342
345
|
pj_str_t mode;
|
|
343
346
|
|
|
347
|
+
char BfskBuffer[MAXDIGITS + 1];
|
|
348
|
+
int BfskBufferLength;
|
|
349
|
+
int last_bit_timestamp;
|
|
350
|
+
|
|
344
351
|
pjmedia_conf *conf;
|
|
345
352
|
pjmedia_master_port *master_port;
|
|
346
353
|
pjmedia_port *null_port;
|
|
@@ -634,11 +641,12 @@ static void build_stream_stat(ostringstream &oss, pjmedia_rtcp_stat *stat,
|
|
|
634
641
|
|
|
635
642
|
bool prepare_tonegen(Call *call, AudioEndpoint *ae);
|
|
636
643
|
bool prepare_dtmfdet(Call *call, AudioEndpoint *ae);
|
|
644
|
+
bool prepare_bfsk_det(Call *call, AudioEndpoint *ae, const int freq_zero, const int freq_one);
|
|
637
645
|
bool prepare_wav_player(Call *call, AudioEndpoint *ae, const char *file, unsigned flags, bool end_of_file_event);
|
|
638
646
|
bool prepare_wav_writer(Call *call, AudioEndpoint *ae, const char *file);
|
|
639
647
|
bool prepare_fax(Call *call, AudioEndpoint *ae, bool is_sender, const char *file, unsigned flags);
|
|
640
|
-
bool prepare_speech_synth(Call *call, AudioEndpoint *ae, const char *server_url, const char *engine, const char *voice, const char *language, const char *text, int times);
|
|
641
|
-
bool prepare_speech_recog(Call *call, AudioEndpoint *ae, const char *server_url, const char *engine, const char *language);
|
|
648
|
+
bool prepare_speech_synth(Call *call, AudioEndpoint *ae, const char *server_url, const char *uuid, const char *engine, const char *voice, const char *language, const char *text, int times);
|
|
649
|
+
bool prepare_speech_recog(Call *call, AudioEndpoint *ae, const char *server_url, const char *uuid, const char *engine, const char *language);
|
|
642
650
|
|
|
643
651
|
void prepare_error_event(ostringstream *oss, char *scope, char *details);
|
|
644
652
|
// void prepare_pjsipcall_error_event(ostringstream *oss, char *scope, char
|
|
@@ -659,6 +667,7 @@ pj_status_t audio_endpoint_stop_record_wav(Call *call, AudioEndpoint *ae);
|
|
|
659
667
|
pj_status_t audio_endpoint_stop_fax(Call *call, AudioEndpoint *ae);
|
|
660
668
|
pj_status_t audio_endpoint_stop_speech_synth(Call *call, AudioEndpoint *ae);
|
|
661
669
|
pj_status_t audio_endpoint_stop_speech_recog(Call *call, AudioEndpoint *ae);
|
|
670
|
+
pj_status_t audio_endpoint_stop_inband_dtmf_detection(Call *call, AudioEndpoint *ae);
|
|
662
671
|
|
|
663
672
|
static pjsip_module mod_tester = {
|
|
664
673
|
NULL,
|
|
@@ -791,13 +800,13 @@ pj_status_t create_audio_endpoint_conf(Call *call, AudioEndpoint *ae, pjmedia_po
|
|
|
791
800
|
return PJ_SUCCESS;
|
|
792
801
|
}
|
|
793
802
|
|
|
794
|
-
static int
|
|
795
|
-
pjmedia_port *port) {
|
|
803
|
+
static int find_endpoint_by_media_port(Call *call,
|
|
804
|
+
pjmedia_port *port, int type) {
|
|
796
805
|
for (int i = 0; i < call->media_count; i++) {
|
|
797
806
|
MediaEndpoint *me = (MediaEndpoint *)call->media[i];
|
|
798
807
|
if (ENDPOINT_TYPE_AUDIO == me->type) {
|
|
799
808
|
AudioEndpoint *ae = (AudioEndpoint *)me->endpoint.audio;
|
|
800
|
-
if (ae->feature_cbps[
|
|
809
|
+
if (ae->feature_cbps[type].port && (pjmedia_port *)ae->feature_cbps[type].port == port) {
|
|
801
810
|
return i;
|
|
802
811
|
}
|
|
803
812
|
}
|
|
@@ -825,7 +834,7 @@ static void on_inband_dtmf(pjmedia_port *port, void *user_data, char digit) {
|
|
|
825
834
|
|
|
826
835
|
Call *call = (Call *)user_data;
|
|
827
836
|
|
|
828
|
-
int media_id =
|
|
837
|
+
int media_id = find_endpoint_by_media_port(call, port, FP_DTMFDET);
|
|
829
838
|
assert(media_id >= 0);
|
|
830
839
|
|
|
831
840
|
MediaEndpoint *me = (MediaEndpoint *)call->media[media_id];
|
|
@@ -855,6 +864,53 @@ static void on_inband_dtmf(pjmedia_port *port, void *user_data, char digit) {
|
|
|
855
864
|
}
|
|
856
865
|
}
|
|
857
866
|
|
|
867
|
+
static void on_bfsk_bit(pjmedia_port *port, void *user_data, int bit) {
|
|
868
|
+
printf("on_bfsk_bit: %i\n", bit);
|
|
869
|
+
|
|
870
|
+
if (g_shutting_down)
|
|
871
|
+
return;
|
|
872
|
+
|
|
873
|
+
long call_id;
|
|
874
|
+
if (!g_call_ids.get_id((long)user_data, call_id)) {
|
|
875
|
+
addon_log(
|
|
876
|
+
L_DBG,
|
|
877
|
+
"on_bfsk_bit: Failed to get call_id. Event will not be notified.\n");
|
|
878
|
+
return;
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
Call *call = (Call *)user_data;
|
|
882
|
+
|
|
883
|
+
int media_id = find_endpoint_by_media_port(call, port, FP_BFSK_DET);
|
|
884
|
+
assert(media_id >= 0);
|
|
885
|
+
|
|
886
|
+
MediaEndpoint *me = (MediaEndpoint *)call->media[media_id];
|
|
887
|
+
AudioEndpoint *ae = (AudioEndpoint *)me->endpoint.audio;
|
|
888
|
+
|
|
889
|
+
if (g_bfsk_inter_bit_timer) {
|
|
890
|
+
|
|
891
|
+
PJW_LOCK();
|
|
892
|
+
int len = ae->BfskBufferLength;
|
|
893
|
+
|
|
894
|
+
if (len > MAXDIGITS) {
|
|
895
|
+
PJW_UNLOCK();
|
|
896
|
+
addon_log(L_DBG, "No more space for bits in bfsk buffer\n");
|
|
897
|
+
return;
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
ae->BfskBuffer[len] = bit == 0 ? '0' : '1';
|
|
901
|
+
ae->BfskBufferLength++;
|
|
902
|
+
|
|
903
|
+
ae->last_bit_timestamp = ms_timestamp();
|
|
904
|
+
PJW_UNLOCK();
|
|
905
|
+
} else {
|
|
906
|
+
char evt[1024];
|
|
907
|
+
char the_bit[1];
|
|
908
|
+
the_bit[0] = bit == 0 ? '0' : '1';
|
|
909
|
+
make_evt_bfsk(evt, sizeof(evt), call_id, 1, the_bit, media_id);
|
|
910
|
+
dispatch_event(evt);
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
|
|
858
914
|
static void on_fax_result(pjmedia_port *port, void *user_data, int result) {
|
|
859
915
|
if (g_shutting_down)
|
|
860
916
|
return;
|
|
@@ -1401,11 +1457,13 @@ int __pjw_init() {
|
|
|
1401
1457
|
return 1;
|
|
1402
1458
|
}
|
|
1403
1459
|
|
|
1460
|
+
/*
|
|
1404
1461
|
status = pjsip_replaces_init_module(g_sip_endpt);
|
|
1405
1462
|
if (status != PJ_SUCCESS) {
|
|
1406
1463
|
addon_log(L_DBG, "pjsip_replaces_init_module failed\n");
|
|
1407
1464
|
return 1;
|
|
1408
1465
|
}
|
|
1466
|
+
*/
|
|
1409
1467
|
|
|
1410
1468
|
pjsip_inv_callback inv_cb;
|
|
1411
1469
|
pj_bzero(&inv_cb, sizeof(inv_cb));
|
|
@@ -2367,6 +2425,8 @@ int pjw_call_respond(long call_id, const char *json) {
|
|
|
2367
2425
|
|
|
2368
2426
|
if (code >= 200 && code < 300) {
|
|
2369
2427
|
call->pending_request = -1;
|
|
2428
|
+
|
|
2429
|
+
pjsip_msg_find_remove_hdr(tdata->msg, PJSIP_H_SUPPORTED, NULL);
|
|
2370
2430
|
}
|
|
2371
2431
|
}
|
|
2372
2432
|
} else {
|
|
@@ -2390,6 +2450,9 @@ int pjw_call_respond(long call_id, const char *json) {
|
|
|
2390
2450
|
|
|
2391
2451
|
if (code >= 200 && code < 300) {
|
|
2392
2452
|
call->pending_request = -1;
|
|
2453
|
+
|
|
2454
|
+
pjsip_msg *msg = tdata->msg;
|
|
2455
|
+
pjsip_msg_find_remove_hdr(msg, PJSIP_H_SUPPORTED, NULL);
|
|
2393
2456
|
}
|
|
2394
2457
|
}
|
|
2395
2458
|
|
|
@@ -3193,6 +3256,8 @@ int call_create(Transport *t, unsigned flags, pjsip_dialog *dlg,
|
|
|
3193
3256
|
}
|
|
3194
3257
|
addon_log(L_DBG, "inv=%p tdata=%p\n", (void*)inv, (void*)tdata);
|
|
3195
3258
|
|
|
3259
|
+
pjsip_msg_find_remove_hdr(tdata->msg, PJSIP_H_SUPPORTED, NULL);
|
|
3260
|
+
|
|
3196
3261
|
status = pjsip_inv_send_msg(inv, tdata);
|
|
3197
3262
|
addon_log(L_DBG, "status=%d\n", status);
|
|
3198
3263
|
if (status != PJ_SUCCESS) {
|
|
@@ -3413,6 +3478,176 @@ out:
|
|
|
3413
3478
|
return 0;
|
|
3414
3479
|
}
|
|
3415
3480
|
|
|
3481
|
+
pj_status_t audio_endpoint_send_bfsk(Call *call, AudioEndpoint *ae,
|
|
3482
|
+
const char *bits, const int freq_zero, const int freq_one, const int level, const int signal_duration) {
|
|
3483
|
+
pj_status_t status;
|
|
3484
|
+
|
|
3485
|
+
if (!prepare_tonegen(call, ae)) {
|
|
3486
|
+
set_error("prepare_tonegen failed.");
|
|
3487
|
+
return -1;
|
|
3488
|
+
}
|
|
3489
|
+
|
|
3490
|
+
int len = strlen(bits);
|
|
3491
|
+
|
|
3492
|
+
pjmedia_tone_desc *tones = (pjmedia_tone_desc*)pj_pool_zalloc(call->inv->pool, sizeof(pjmedia_tone_desc) * len);
|
|
3493
|
+
|
|
3494
|
+
for (int i = 0; i < len; ++i) {
|
|
3495
|
+
tones[i].freq1 = bits[i] == '0' ? freq_zero : freq_one;
|
|
3496
|
+
tones[i].on_msec = signal_duration;
|
|
3497
|
+
tones[i].off_msec = signal_duration;
|
|
3498
|
+
tones[i].volume = level;
|
|
3499
|
+
}
|
|
3500
|
+
|
|
3501
|
+
status = pjmedia_tonegen_play((pjmedia_port *)ae->feature_cbps[FP_TONEGEN].port, len, tones, 0);
|
|
3502
|
+
if (status != PJ_SUCCESS) {
|
|
3503
|
+
set_error("pjmedia_tonegen_plays failed.");
|
|
3504
|
+
return status;
|
|
3505
|
+
}
|
|
3506
|
+
|
|
3507
|
+
return PJ_SUCCESS;
|
|
3508
|
+
}
|
|
3509
|
+
|
|
3510
|
+
pj_status_t send_bfsk(Call *call, const char *bits, const int freq_zero, const int freq_one, const int level, const int signal_duration) {
|
|
3511
|
+
for (int i = 0; i < call->media_count; i++) {
|
|
3512
|
+
MediaEndpoint *me = (MediaEndpoint *)call->media[i];
|
|
3513
|
+
if (me->type != ENDPOINT_TYPE_AUDIO)
|
|
3514
|
+
continue;
|
|
3515
|
+
|
|
3516
|
+
if(me->port == 0)
|
|
3517
|
+
continue;
|
|
3518
|
+
|
|
3519
|
+
AudioEndpoint *ae = (AudioEndpoint *)me->endpoint.audio;
|
|
3520
|
+
|
|
3521
|
+
pj_status_t status = audio_endpoint_send_bfsk(call, ae, bits, freq_zero, freq_one, level, signal_duration);
|
|
3522
|
+
if (status != PJ_SUCCESS)
|
|
3523
|
+
return status;
|
|
3524
|
+
}
|
|
3525
|
+
|
|
3526
|
+
return PJ_SUCCESS;
|
|
3527
|
+
}
|
|
3528
|
+
|
|
3529
|
+
int pjw_call_send_bfsk(long call_id, const char *json) {
|
|
3530
|
+
#define BITS_MAX_LEN 32 // pjmedia_tonegen limit
|
|
3531
|
+
|
|
3532
|
+
PJW_LOCK();
|
|
3533
|
+
clear_error();
|
|
3534
|
+
|
|
3535
|
+
Call *call;
|
|
3536
|
+
|
|
3537
|
+
pj_status_t status;
|
|
3538
|
+
|
|
3539
|
+
long val;
|
|
3540
|
+
|
|
3541
|
+
int len;
|
|
3542
|
+
|
|
3543
|
+
char *bits;
|
|
3544
|
+
int freq_zero;
|
|
3545
|
+
int freq_one;
|
|
3546
|
+
int level = 24000;
|
|
3547
|
+
int signal_duration = 10;
|
|
3548
|
+
|
|
3549
|
+
MediaEndpoint *me;
|
|
3550
|
+
AudioEndpoint *ae;
|
|
3551
|
+
int res;
|
|
3552
|
+
|
|
3553
|
+
int media_id = -1;
|
|
3554
|
+
|
|
3555
|
+
char buffer[MAX_JSON_INPUT];
|
|
3556
|
+
|
|
3557
|
+
Document document;
|
|
3558
|
+
|
|
3559
|
+
const char *valid_params[] = {"bits", "freq_zero", "freq_one", "level", "signal_duration", "media_id", ""};
|
|
3560
|
+
|
|
3561
|
+
if (!g_call_ids.get(call_id, val)) {
|
|
3562
|
+
set_error("Invalid call_id");
|
|
3563
|
+
goto out;
|
|
3564
|
+
}
|
|
3565
|
+
call = (Call *)val;
|
|
3566
|
+
|
|
3567
|
+
if (!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
3568
|
+
goto out;
|
|
3569
|
+
}
|
|
3570
|
+
|
|
3571
|
+
if (!validate_params(document, valid_params)) {
|
|
3572
|
+
goto out;
|
|
3573
|
+
}
|
|
3574
|
+
|
|
3575
|
+
if (json_get_string_param(document, "bits", false, &bits) <= 0) {
|
|
3576
|
+
goto out;
|
|
3577
|
+
}
|
|
3578
|
+
|
|
3579
|
+
if (json_get_int_param(document, "freq_zero", false, &freq_zero) <= 0) {
|
|
3580
|
+
goto out;
|
|
3581
|
+
}
|
|
3582
|
+
|
|
3583
|
+
if (json_get_int_param(document, "freq_one", false, &freq_one) <= 0) {
|
|
3584
|
+
goto out;
|
|
3585
|
+
}
|
|
3586
|
+
|
|
3587
|
+
if (json_get_int_param(document, "level", true, &level) <= 0) {
|
|
3588
|
+
goto out;
|
|
3589
|
+
}
|
|
3590
|
+
|
|
3591
|
+
if (json_get_int_param(document, "signal_duration", true, &signal_duration) <= 0) {
|
|
3592
|
+
goto out;
|
|
3593
|
+
}
|
|
3594
|
+
|
|
3595
|
+
len = strlen(bits);
|
|
3596
|
+
|
|
3597
|
+
if (len > BITS_MAX_LEN) {
|
|
3598
|
+
set_error("bits too long");
|
|
3599
|
+
goto out;
|
|
3600
|
+
}
|
|
3601
|
+
|
|
3602
|
+
for (int i = 0; i < len; ++i) {
|
|
3603
|
+
if (bits[i] != '0' && bits[i] != '1') {
|
|
3604
|
+
set_error("Invalid character");
|
|
3605
|
+
goto out;
|
|
3606
|
+
}
|
|
3607
|
+
}
|
|
3608
|
+
|
|
3609
|
+
res = json_get_int_param(document, "media_id", true, &media_id);
|
|
3610
|
+
if (res <= 0) {
|
|
3611
|
+
goto out;
|
|
3612
|
+
}
|
|
3613
|
+
|
|
3614
|
+
if (NOT_FOUND_OPTIONAL == res) {
|
|
3615
|
+
// send_bfsk_bits to all audio endpoints
|
|
3616
|
+
status = send_bfsk(call, bits, freq_zero, freq_one, level, signal_duration);
|
|
3617
|
+
if (status != PJ_SUCCESS) {
|
|
3618
|
+
goto out;
|
|
3619
|
+
}
|
|
3620
|
+
} else {
|
|
3621
|
+
// send_bfsk_bits to specified media_id
|
|
3622
|
+
|
|
3623
|
+
if (media_id >= call->media_count) {
|
|
3624
|
+
set_error("invalid media_id");
|
|
3625
|
+
goto out;
|
|
3626
|
+
}
|
|
3627
|
+
|
|
3628
|
+
me = (MediaEndpoint *)call->media[media_id];
|
|
3629
|
+
if (ENDPOINT_TYPE_AUDIO != me->type) {
|
|
3630
|
+
set_error("invalid media_id non audio");
|
|
3631
|
+
goto out;
|
|
3632
|
+
}
|
|
3633
|
+
|
|
3634
|
+
ae = (AudioEndpoint *)me->endpoint.audio;
|
|
3635
|
+
|
|
3636
|
+
status = audio_endpoint_send_bfsk(call, ae, bits, freq_one, freq_zero, level, signal_duration);
|
|
3637
|
+
if (status != PJ_SUCCESS) {
|
|
3638
|
+
goto out;
|
|
3639
|
+
}
|
|
3640
|
+
}
|
|
3641
|
+
|
|
3642
|
+
out:
|
|
3643
|
+
PJW_UNLOCK();
|
|
3644
|
+
if (pjw_errorstring[0]) {
|
|
3645
|
+
return -1;
|
|
3646
|
+
}
|
|
3647
|
+
|
|
3648
|
+
return 0;
|
|
3649
|
+
}
|
|
3650
|
+
|
|
3416
3651
|
pj_status_t audio_endpoint_remove_port(Call *call, AudioEndpoint *ae, ConfBridgePort *cbp) {
|
|
3417
3652
|
printf("audio_endpoint_remove_port\n");
|
|
3418
3653
|
pj_status_t status;
|
|
@@ -3531,6 +3766,8 @@ int pjw_call_reinvite(long call_id, const char *json) {
|
|
|
3531
3766
|
goto out;
|
|
3532
3767
|
}
|
|
3533
3768
|
|
|
3769
|
+
pjsip_msg_find_remove_hdr(tdata->msg, PJSIP_H_SUPPORTED, NULL);
|
|
3770
|
+
|
|
3534
3771
|
status = pjsip_inv_send_msg(call->inv, tdata);
|
|
3535
3772
|
if (status != PJ_SUCCESS) {
|
|
3536
3773
|
set_error("pjsip_inv_send_msg failed");
|
|
@@ -3943,7 +4180,7 @@ out:
|
|
|
3943
4180
|
return 0;
|
|
3944
4181
|
}
|
|
3945
4182
|
|
|
3946
|
-
pj_status_t audio_endpoint_start_speech_synth(Call *call, AudioEndpoint *ae, const char *server_url, const char *engine, const char *voice, const char *language, const char *text, int times) {
|
|
4183
|
+
pj_status_t audio_endpoint_start_speech_synth(Call *call, AudioEndpoint *ae, const char *server_url, const char *uuid, const char *engine, const char *voice, const char *language, const char *text, int times) {
|
|
3947
4184
|
pj_status_t status;
|
|
3948
4185
|
|
|
3949
4186
|
if(!ae->stream_cbp.port) {
|
|
@@ -3957,7 +4194,7 @@ pj_status_t audio_endpoint_start_speech_synth(Call *call, AudioEndpoint *ae, con
|
|
|
3957
4194
|
return -1;
|
|
3958
4195
|
}
|
|
3959
4196
|
|
|
3960
|
-
if (!prepare_speech_synth(call, ae, server_url, engine, voice, language, text, times)) {
|
|
4197
|
+
if (!prepare_speech_synth(call, ae, server_url, uuid, engine, voice, language, text, times)) {
|
|
3961
4198
|
return -1;
|
|
3962
4199
|
}
|
|
3963
4200
|
|
|
@@ -4076,13 +4313,16 @@ int pjw_call_start_speech_synth(long call_id, const char *json) {
|
|
|
4076
4313
|
}
|
|
4077
4314
|
}
|
|
4078
4315
|
|
|
4316
|
+
char uuid[1024];
|
|
4317
|
+
sprintf(uuid, "%.*s", call->inv->dlg->call_id->id.slen, call->inv->dlg->call_id->id.ptr);
|
|
4318
|
+
|
|
4079
4319
|
if (NOT_FOUND_OPTIONAL == res) {
|
|
4080
4320
|
// start on all audio media endpoints
|
|
4081
4321
|
for (int i = 0; i < call->media_count; i++) {
|
|
4082
4322
|
MediaEndpoint *me = (MediaEndpoint *)call->media[i];
|
|
4083
4323
|
if (me->type == ENDPOINT_TYPE_AUDIO) {
|
|
4084
4324
|
AudioEndpoint *ae = (AudioEndpoint *)me->endpoint.audio;
|
|
4085
|
-
status = audio_endpoint_start_speech_synth(call, ae, server_url, engine, voice, language, text, times);
|
|
4325
|
+
status = audio_endpoint_start_speech_synth(call, ae, server_url, uuid, engine, voice, language, text, times);
|
|
4086
4326
|
if (status != PJ_SUCCESS) goto out;
|
|
4087
4327
|
}
|
|
4088
4328
|
}
|
|
@@ -4100,7 +4340,7 @@ int pjw_call_start_speech_synth(long call_id, const char *json) {
|
|
|
4100
4340
|
|
|
4101
4341
|
ae = (AudioEndpoint *)me->endpoint.audio;
|
|
4102
4342
|
|
|
4103
|
-
audio_endpoint_start_speech_synth(call, ae, server_url, engine, voice, language, text, times);
|
|
4343
|
+
audio_endpoint_start_speech_synth(call, ae, server_url, uuid, engine, voice, language, text, times);
|
|
4104
4344
|
}
|
|
4105
4345
|
|
|
4106
4346
|
out:
|
|
@@ -4112,7 +4352,7 @@ out:
|
|
|
4112
4352
|
return 0;
|
|
4113
4353
|
}
|
|
4114
4354
|
|
|
4115
|
-
pj_status_t audio_endpoint_start_speech_recog(Call *call, AudioEndpoint *ae, const char *server_url, const char *engine, const char *language) {
|
|
4355
|
+
pj_status_t audio_endpoint_start_speech_recog(Call *call, AudioEndpoint *ae, const char *server_url, const char *uuid, const char *engine, const char *language) {
|
|
4116
4356
|
pj_status_t status;
|
|
4117
4357
|
|
|
4118
4358
|
if(!ae->stream_cbp.port) {
|
|
@@ -4126,7 +4366,7 @@ pj_status_t audio_endpoint_start_speech_recog(Call *call, AudioEndpoint *ae, con
|
|
|
4126
4366
|
return -1;
|
|
4127
4367
|
}
|
|
4128
4368
|
|
|
4129
|
-
if (!prepare_speech_recog(call, ae, server_url, engine, language)) {
|
|
4369
|
+
if (!prepare_speech_recog(call, ae, server_url, uuid, engine, language)) {
|
|
4130
4370
|
return -1;
|
|
4131
4371
|
}
|
|
4132
4372
|
|
|
@@ -4217,13 +4457,16 @@ int pjw_call_start_speech_recog(long call_id, const char *json) {
|
|
|
4217
4457
|
}
|
|
4218
4458
|
}
|
|
4219
4459
|
|
|
4460
|
+
char uuid[1024];
|
|
4461
|
+
sprintf(uuid, "%.*s", call->inv->dlg->call_id->id.slen, call->inv->dlg->call_id->id.ptr);
|
|
4462
|
+
|
|
4220
4463
|
if (NOT_FOUND_OPTIONAL == res) {
|
|
4221
4464
|
// start on all audio media endpoints
|
|
4222
4465
|
for (int i = 0; i < call->media_count; i++) {
|
|
4223
4466
|
MediaEndpoint *me = (MediaEndpoint *)call->media[i];
|
|
4224
4467
|
if (me->type == ENDPOINT_TYPE_AUDIO) {
|
|
4225
4468
|
AudioEndpoint *ae = (AudioEndpoint *)me->endpoint.audio;
|
|
4226
|
-
status = audio_endpoint_start_speech_recog(call, ae, server_url, engine, language);
|
|
4469
|
+
status = audio_endpoint_start_speech_recog(call, ae, server_url, uuid, engine, language);
|
|
4227
4470
|
if (status != PJ_SUCCESS) goto out;
|
|
4228
4471
|
}
|
|
4229
4472
|
}
|
|
@@ -4241,7 +4484,218 @@ int pjw_call_start_speech_recog(long call_id, const char *json) {
|
|
|
4241
4484
|
|
|
4242
4485
|
ae = (AudioEndpoint *)me->endpoint.audio;
|
|
4243
4486
|
|
|
4244
|
-
audio_endpoint_start_speech_recog(call, ae, server_url, engine, language);
|
|
4487
|
+
audio_endpoint_start_speech_recog(call, ae, server_url, uuid, engine, language);
|
|
4488
|
+
}
|
|
4489
|
+
|
|
4490
|
+
out:
|
|
4491
|
+
PJW_UNLOCK();
|
|
4492
|
+
if (pjw_errorstring[0]) {
|
|
4493
|
+
return -1;
|
|
4494
|
+
}
|
|
4495
|
+
|
|
4496
|
+
return 0;
|
|
4497
|
+
}
|
|
4498
|
+
|
|
4499
|
+
pj_status_t audio_endpoint_start_inband_dtmf_detection(Call *call, AudioEndpoint *ae) {
|
|
4500
|
+
pj_status_t status;
|
|
4501
|
+
|
|
4502
|
+
if(!ae->stream_cbp.port) {
|
|
4503
|
+
set_error("stream port is not ready yet");
|
|
4504
|
+
return -1;
|
|
4505
|
+
}
|
|
4506
|
+
|
|
4507
|
+
if(!prepare_dtmfdet(call, ae)) {
|
|
4508
|
+
return -1;
|
|
4509
|
+
}
|
|
4510
|
+
|
|
4511
|
+
return PJ_SUCCESS;
|
|
4512
|
+
}
|
|
4513
|
+
|
|
4514
|
+
int pjw_call_start_inband_dtmf_detection(long call_id, const char *json) {
|
|
4515
|
+
printf("pjw_call_start_inband_dtmf_detection\n");
|
|
4516
|
+
PJW_LOCK();
|
|
4517
|
+
clear_error();
|
|
4518
|
+
|
|
4519
|
+
long val;
|
|
4520
|
+
Call *call;
|
|
4521
|
+
|
|
4522
|
+
pj_status_t status;
|
|
4523
|
+
|
|
4524
|
+
MediaEndpoint *me;
|
|
4525
|
+
AudioEndpoint *ae;
|
|
4526
|
+
int ae_count;
|
|
4527
|
+
int res;
|
|
4528
|
+
|
|
4529
|
+
int media_id = -1;
|
|
4530
|
+
|
|
4531
|
+
char buffer[MAX_JSON_INPUT];
|
|
4532
|
+
|
|
4533
|
+
Document document;
|
|
4534
|
+
|
|
4535
|
+
const char *valid_params[] = {"media_id", ""};
|
|
4536
|
+
|
|
4537
|
+
if (!g_call_ids.get(call_id, val)) {
|
|
4538
|
+
set_error("Invalid call_id");
|
|
4539
|
+
goto out;
|
|
4540
|
+
}
|
|
4541
|
+
call = (Call *)val;
|
|
4542
|
+
|
|
4543
|
+
ae_count = count_media_by_type(call, ENDPOINT_TYPE_AUDIO);
|
|
4544
|
+
|
|
4545
|
+
if (ae_count == 0) {
|
|
4546
|
+
set_error("No audio endpoint");
|
|
4547
|
+
goto out;
|
|
4548
|
+
}
|
|
4549
|
+
|
|
4550
|
+
if (!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
4551
|
+
goto out;
|
|
4552
|
+
}
|
|
4553
|
+
|
|
4554
|
+
if (!validate_params(document, valid_params)) {
|
|
4555
|
+
goto out;
|
|
4556
|
+
}
|
|
4557
|
+
|
|
4558
|
+
res = json_get_int_param(document, "media_id", true, &media_id);
|
|
4559
|
+
if (res <= 0) {
|
|
4560
|
+
goto out;
|
|
4561
|
+
}
|
|
4562
|
+
|
|
4563
|
+
if (NOT_FOUND_OPTIONAL == res) {
|
|
4564
|
+
for (int i = 0; i < call->media_count; i++) {
|
|
4565
|
+
MediaEndpoint *me = (MediaEndpoint *)call->media[i];
|
|
4566
|
+
if (me->type == ENDPOINT_TYPE_AUDIO) {
|
|
4567
|
+
AudioEndpoint *ae = (AudioEndpoint *)me->endpoint.audio;
|
|
4568
|
+
status = audio_endpoint_start_inband_dtmf_detection(call, ae);
|
|
4569
|
+
if (status != PJ_SUCCESS) goto out;
|
|
4570
|
+
}
|
|
4571
|
+
}
|
|
4572
|
+
} else {
|
|
4573
|
+
if ((int)media_id >= call->media_count) {
|
|
4574
|
+
set_error("invalid media_id");
|
|
4575
|
+
goto out;
|
|
4576
|
+
}
|
|
4577
|
+
|
|
4578
|
+
me = (MediaEndpoint *)call->media[media_id];
|
|
4579
|
+
if (ENDPOINT_TYPE_AUDIO != me->type) {
|
|
4580
|
+
set_error("media_endpoint is not audio endpoint");
|
|
4581
|
+
goto out;
|
|
4582
|
+
}
|
|
4583
|
+
|
|
4584
|
+
ae = (AudioEndpoint *)me->endpoint.audio;
|
|
4585
|
+
|
|
4586
|
+
audio_endpoint_start_inband_dtmf_detection(call, ae);
|
|
4587
|
+
}
|
|
4588
|
+
|
|
4589
|
+
out:
|
|
4590
|
+
PJW_UNLOCK();
|
|
4591
|
+
if (pjw_errorstring[0]) {
|
|
4592
|
+
return -1;
|
|
4593
|
+
}
|
|
4594
|
+
|
|
4595
|
+
return 0;
|
|
4596
|
+
}
|
|
4597
|
+
|
|
4598
|
+
pj_status_t audio_endpoint_start_bfsk_detection(Call *call, AudioEndpoint *ae, const int freq_zero, const int freq_one) {
|
|
4599
|
+
pj_status_t status;
|
|
4600
|
+
|
|
4601
|
+
if(!ae->stream_cbp.port) {
|
|
4602
|
+
set_error("stream port is not ready yet");
|
|
4603
|
+
return -1;
|
|
4604
|
+
}
|
|
4605
|
+
|
|
4606
|
+
if(!prepare_bfsk_det(call, ae, freq_zero, freq_one)) {
|
|
4607
|
+
return -1;
|
|
4608
|
+
}
|
|
4609
|
+
|
|
4610
|
+
return PJ_SUCCESS;
|
|
4611
|
+
}
|
|
4612
|
+
|
|
4613
|
+
int pjw_call_start_bfsk_detection(long call_id, const char *json) {
|
|
4614
|
+
printf("pjw_call_start_bfsk_detection\n");
|
|
4615
|
+
PJW_LOCK();
|
|
4616
|
+
clear_error();
|
|
4617
|
+
|
|
4618
|
+
long val;
|
|
4619
|
+
Call *call;
|
|
4620
|
+
|
|
4621
|
+
pj_status_t status;
|
|
4622
|
+
|
|
4623
|
+
MediaEndpoint *me;
|
|
4624
|
+
AudioEndpoint *ae;
|
|
4625
|
+
int ae_count;
|
|
4626
|
+
int res;
|
|
4627
|
+
|
|
4628
|
+
int media_id = -1;
|
|
4629
|
+
|
|
4630
|
+
int freq_zero;
|
|
4631
|
+
int freq_one;
|
|
4632
|
+
|
|
4633
|
+
char buffer[MAX_JSON_INPUT];
|
|
4634
|
+
|
|
4635
|
+
Document document;
|
|
4636
|
+
|
|
4637
|
+
const char *valid_params[] = {"freq_zero", "freq_one", "media_id", ""};
|
|
4638
|
+
|
|
4639
|
+
if (!g_call_ids.get(call_id, val)) {
|
|
4640
|
+
set_error("Invalid call_id");
|
|
4641
|
+
goto out;
|
|
4642
|
+
}
|
|
4643
|
+
call = (Call *)val;
|
|
4644
|
+
|
|
4645
|
+
ae_count = count_media_by_type(call, ENDPOINT_TYPE_AUDIO);
|
|
4646
|
+
|
|
4647
|
+
if (ae_count == 0) {
|
|
4648
|
+
set_error("No audio endpoint");
|
|
4649
|
+
goto out;
|
|
4650
|
+
}
|
|
4651
|
+
|
|
4652
|
+
if (!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
4653
|
+
goto out;
|
|
4654
|
+
}
|
|
4655
|
+
|
|
4656
|
+
if (!validate_params(document, valid_params)) {
|
|
4657
|
+
goto out;
|
|
4658
|
+
}
|
|
4659
|
+
|
|
4660
|
+
res = json_get_int_param(document, "freq_zero", false, &freq_zero);
|
|
4661
|
+
if (res <= 0) {
|
|
4662
|
+
goto out;
|
|
4663
|
+
}
|
|
4664
|
+
|
|
4665
|
+
res = json_get_int_param(document, "freq_one", false, &freq_one);
|
|
4666
|
+
if (res <= 0) {
|
|
4667
|
+
goto out;
|
|
4668
|
+
}
|
|
4669
|
+
|
|
4670
|
+
res = json_get_int_param(document, "media_id", true, &media_id);
|
|
4671
|
+
if (res <= 0) {
|
|
4672
|
+
goto out;
|
|
4673
|
+
}
|
|
4674
|
+
|
|
4675
|
+
if (NOT_FOUND_OPTIONAL == res) {
|
|
4676
|
+
for (int i = 0; i < call->media_count; i++) {
|
|
4677
|
+
MediaEndpoint *me = (MediaEndpoint *)call->media[i];
|
|
4678
|
+
if (me->type == ENDPOINT_TYPE_AUDIO) {
|
|
4679
|
+
AudioEndpoint *ae = (AudioEndpoint *)me->endpoint.audio;
|
|
4680
|
+
status = audio_endpoint_start_bfsk_detection(call, ae, freq_zero, freq_one);
|
|
4681
|
+
if (status != PJ_SUCCESS) goto out;
|
|
4682
|
+
}
|
|
4683
|
+
}
|
|
4684
|
+
} else {
|
|
4685
|
+
if ((int)media_id >= call->media_count) {
|
|
4686
|
+
set_error("invalid media_id");
|
|
4687
|
+
goto out;
|
|
4688
|
+
}
|
|
4689
|
+
|
|
4690
|
+
me = (MediaEndpoint *)call->media[media_id];
|
|
4691
|
+
if (ENDPOINT_TYPE_AUDIO != me->type) {
|
|
4692
|
+
set_error("media_endpoint is not audio endpoint");
|
|
4693
|
+
goto out;
|
|
4694
|
+
}
|
|
4695
|
+
|
|
4696
|
+
ae = (AudioEndpoint *)me->endpoint.audio;
|
|
4697
|
+
|
|
4698
|
+
audio_endpoint_start_bfsk_detection(call, ae, freq_zero, freq_one);
|
|
4245
4699
|
}
|
|
4246
4700
|
|
|
4247
4701
|
out:
|
|
@@ -4274,6 +4728,7 @@ pj_status_t call_stop_op_on_all_audio_endpoints(Call *call,
|
|
|
4274
4728
|
return PJ_SUCCESS;
|
|
4275
4729
|
}
|
|
4276
4730
|
|
|
4731
|
+
|
|
4277
4732
|
int audio_endpoint_stop_op(long call_id, const char *json, audio_endpoint_stop_op_t op) {
|
|
4278
4733
|
PJW_LOCK();
|
|
4279
4734
|
clear_error();
|
|
@@ -4362,6 +4817,14 @@ pj_status_t audio_endpoint_stop_speech_recog(Call *call, AudioEndpoint *ae) {
|
|
|
4362
4817
|
return audio_endpoint_remove_port(call, ae, &ae->feature_cbps[FP_SPEECH_RECOG]);
|
|
4363
4818
|
}
|
|
4364
4819
|
|
|
4820
|
+
pj_status_t audio_endpoint_stop_inband_dtmf_detection(Call *call, AudioEndpoint *ae) {
|
|
4821
|
+
return audio_endpoint_remove_port(call, ae, &ae->feature_cbps[FP_DTMFDET]);
|
|
4822
|
+
}
|
|
4823
|
+
|
|
4824
|
+
pj_status_t audio_endpoint_stop_bfsk_detection(Call *call, AudioEndpoint *ae) {
|
|
4825
|
+
return audio_endpoint_remove_port(call, ae, &ae->feature_cbps[FP_BFSK_DET]);
|
|
4826
|
+
}
|
|
4827
|
+
|
|
4365
4828
|
|
|
4366
4829
|
int pjw_call_stop_play_wav(long call_id, const char *json) {
|
|
4367
4830
|
return audio_endpoint_stop_op(call_id, json, audio_endpoint_stop_play_wav);
|
|
@@ -4383,6 +4846,11 @@ int pjw_call_stop_speech_recog(long call_id, const char *json) {
|
|
|
4383
4846
|
return audio_endpoint_stop_op(call_id, json, audio_endpoint_stop_speech_recog);
|
|
4384
4847
|
}
|
|
4385
4848
|
|
|
4849
|
+
int pjw_call_stop_inband_dtmf_detection(long call_id, const char *json) {
|
|
4850
|
+
return audio_endpoint_stop_op(call_id, json, audio_endpoint_stop_inband_dtmf_detection);
|
|
4851
|
+
}
|
|
4852
|
+
|
|
4853
|
+
|
|
4386
4854
|
|
|
4387
4855
|
int pjw_call_start_fax(long call_id, const char *json) {
|
|
4388
4856
|
PJW_LOCK();
|
|
@@ -5030,14 +5498,6 @@ bool restart_media_stream(Call *call, MediaEndpoint *me,
|
|
|
5030
5498
|
dispatch_event(evt);
|
|
5031
5499
|
return false;
|
|
5032
5500
|
}
|
|
5033
|
-
|
|
5034
|
-
// we always add dtmfdet to audio endpoints
|
|
5035
|
-
if(!prepare_dtmfdet(call, ae)) {
|
|
5036
|
-
make_evt_media_update(evt, sizeof(evt), call->id,
|
|
5037
|
-
"setup_failed (prepare_dtmfdet failed)", "");
|
|
5038
|
-
dispatch_event(evt);
|
|
5039
|
-
return false;
|
|
5040
|
-
}
|
|
5041
5501
|
} else if(
|
|
5042
5502
|
(PJMEDIA_PIA_SRATE(&old_port->info) != PJMEDIA_PIA_SRATE(&new_port->info)) ||
|
|
5043
5503
|
(PJMEDIA_PIA_CCNT(&old_port->info) != PJMEDIA_PIA_CCNT(&new_port->info)) ||
|
|
@@ -5065,14 +5525,6 @@ bool restart_media_stream(Call *call, MediaEndpoint *me,
|
|
|
5065
5525
|
return false;
|
|
5066
5526
|
}
|
|
5067
5527
|
|
|
5068
|
-
// we always add dtmfdet to audio endpoints
|
|
5069
|
-
if(!prepare_dtmfdet(call, ae)) {
|
|
5070
|
-
make_evt_media_update(evt, sizeof(evt), call->id,
|
|
5071
|
-
"setup_failed (prepare_dtmfdet failed)", "");
|
|
5072
|
-
dispatch_event(evt);
|
|
5073
|
-
return false;
|
|
5074
|
-
}
|
|
5075
|
-
|
|
5076
5528
|
// at this point we could try to recreate ports (see #91)
|
|
5077
5529
|
} else {
|
|
5078
5530
|
printf("call_id=%i restart_media_stream: stream characteristics no change\n", call->id);
|
|
@@ -7006,10 +7458,16 @@ bool prepare_wav_writer(Call *call, AudioEndpoint *ae, const char *file) {
|
|
|
7006
7458
|
}
|
|
7007
7459
|
|
|
7008
7460
|
bool prepare_dtmfdet(Call *call, AudioEndpoint *ae) {
|
|
7461
|
+
printf("DEBUG prepare_dtmfdet\n");
|
|
7009
7462
|
pj_status_t status;
|
|
7010
7463
|
|
|
7011
7464
|
ConfBridgePort *fp = &ae->feature_cbps[FP_DTMFDET];
|
|
7012
7465
|
|
|
7466
|
+
if(fp->port) {
|
|
7467
|
+
printf("already prepared\n");
|
|
7468
|
+
return true;
|
|
7469
|
+
}
|
|
7470
|
+
|
|
7013
7471
|
status = pjmedia_dtmfdet_create(
|
|
7014
7472
|
call->inv->pool,
|
|
7015
7473
|
PJMEDIA_PIA_SRATE(&ae->stream_cbp.port->info),
|
|
@@ -7033,6 +7491,41 @@ bool prepare_dtmfdet(Call *call, AudioEndpoint *ae) {
|
|
|
7033
7491
|
return connect_feature_port_to_stream_port(call, ae, fp);
|
|
7034
7492
|
}
|
|
7035
7493
|
|
|
7494
|
+
bool prepare_bfsk_det(Call *call, AudioEndpoint *ae, const int freq_zero, const int freq_one) {
|
|
7495
|
+
printf("DEBUG prepare_bfsk_det\n");
|
|
7496
|
+
pj_status_t status;
|
|
7497
|
+
|
|
7498
|
+
ConfBridgePort *fp = &ae->feature_cbps[FP_BFSK_DET];
|
|
7499
|
+
|
|
7500
|
+
if(fp->port) {
|
|
7501
|
+
printf("already prepared\n");
|
|
7502
|
+
return true;
|
|
7503
|
+
}
|
|
7504
|
+
|
|
7505
|
+
status = pjmedia_bfsk_det_create(
|
|
7506
|
+
call->inv->pool,
|
|
7507
|
+
PJMEDIA_PIA_SRATE(&ae->stream_cbp.port->info),
|
|
7508
|
+
PJMEDIA_PIA_CCNT(&ae->stream_cbp.port->info),
|
|
7509
|
+
PJMEDIA_PIA_SPF(&ae->stream_cbp.port->info),
|
|
7510
|
+
PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info),
|
|
7511
|
+
on_bfsk_bit, call, freq_zero, freq_one, &fp->port);
|
|
7512
|
+
if (status != PJ_SUCCESS) {
|
|
7513
|
+
set_error("pjmedia_bfsk_det_create failed");
|
|
7514
|
+
return false;
|
|
7515
|
+
}
|
|
7516
|
+
|
|
7517
|
+
status = pjmedia_conf_add_port(ae->conf, call->inv->pool, fp->port, NULL, &fp->slot);
|
|
7518
|
+
if (status != PJ_SUCCESS) {
|
|
7519
|
+
set_error("pjmedia_conf_add_port failed");
|
|
7520
|
+
return false;
|
|
7521
|
+
}
|
|
7522
|
+
|
|
7523
|
+
fp->connection_mode = CONNECTION_MODE_SINK;
|
|
7524
|
+
|
|
7525
|
+
return connect_feature_port_to_stream_port(call, ae, fp);
|
|
7526
|
+
}
|
|
7527
|
+
|
|
7528
|
+
|
|
7036
7529
|
bool prepare_fax(Call *call, AudioEndpoint *ae, bool is_sender, const char *file, unsigned flags) {
|
|
7037
7530
|
pj_status_t status;
|
|
7038
7531
|
|
|
@@ -7062,7 +7555,7 @@ bool prepare_fax(Call *call, AudioEndpoint *ae, bool is_sender, const char *file
|
|
|
7062
7555
|
return connect_feature_port_to_stream_port(call, ae, fp);
|
|
7063
7556
|
}
|
|
7064
7557
|
|
|
7065
|
-
bool prepare_speech_synth(Call *call, AudioEndpoint *ae, const char *server_url, const char *engine, const char *voice, const char *language, const char *text, int times) {
|
|
7558
|
+
bool prepare_speech_synth(Call *call, AudioEndpoint *ae, const char *server_url, const char *uuid, const char *engine, const char *voice, const char *language, const char *text, int times) {
|
|
7066
7559
|
pj_status_t status;
|
|
7067
7560
|
|
|
7068
7561
|
ConfBridgePort *fp = &ae->feature_cbps[FP_SPEECH_SYNTH];
|
|
@@ -7117,6 +7610,7 @@ bool prepare_speech_synth(Call *call, AudioEndpoint *ae, const char *server_url,
|
|
|
7117
7610
|
PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info),
|
|
7118
7611
|
g_ws_endpt,
|
|
7119
7612
|
server_url,
|
|
7613
|
+
uuid,
|
|
7120
7614
|
engine,
|
|
7121
7615
|
voice,
|
|
7122
7616
|
language,
|
|
@@ -7150,7 +7644,7 @@ bool prepare_speech_synth(Call *call, AudioEndpoint *ae, const char *server_url,
|
|
|
7150
7644
|
return PJ_SUCCESS;
|
|
7151
7645
|
}
|
|
7152
7646
|
|
|
7153
|
-
bool prepare_speech_recog(Call *call, AudioEndpoint *ae, const char *server_url, const char *engine, const char *language) {
|
|
7647
|
+
bool prepare_speech_recog(Call *call, AudioEndpoint *ae, const char *server_url, const char *uuid, const char *engine, const char *language) {
|
|
7154
7648
|
pj_status_t status;
|
|
7155
7649
|
|
|
7156
7650
|
ConfBridgePort *fp = &ae->feature_cbps[FP_SPEECH_RECOG];
|
|
@@ -7182,6 +7676,7 @@ bool prepare_speech_recog(Call *call, AudioEndpoint *ae, const char *server_url,
|
|
|
7182
7676
|
PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info),
|
|
7183
7677
|
g_ws_endpt,
|
|
7184
7678
|
server_url,
|
|
7679
|
+
uuid,
|
|
7185
7680
|
NULL,
|
|
7186
7681
|
NULL,
|
|
7187
7682
|
NULL,
|
|
@@ -8619,11 +9114,33 @@ void check_digit_buffer(Call *call, int mode) {
|
|
|
8619
9114
|
}
|
|
8620
9115
|
}
|
|
8621
9116
|
|
|
8622
|
-
void
|
|
9117
|
+
void check_bit_buffer(Call *call) {
|
|
9118
|
+
char evt[1024];
|
|
9119
|
+
|
|
9120
|
+
for (int i = 0; i < call->media_count; i++) {
|
|
9121
|
+
MediaEndpoint *me = (MediaEndpoint *)call->media[i];
|
|
9122
|
+
if (ENDPOINT_TYPE_AUDIO != me->type)
|
|
9123
|
+
continue;
|
|
9124
|
+
|
|
9125
|
+
AudioEndpoint *ae = (AudioEndpoint *)me->endpoint.audio;
|
|
9126
|
+
|
|
9127
|
+
if (ae->last_bit_timestamp > 0 &&
|
|
9128
|
+
g_now - ae->last_bit_timestamp > g_bfsk_inter_bit_timer) {
|
|
9129
|
+
int len = ae->BfskBufferLength;
|
|
9130
|
+
ae->BfskBufferLength = 0;
|
|
9131
|
+
make_evt_bfsk(evt, sizeof(evt), call->id, len, ae->BfskBuffer, i);
|
|
9132
|
+
dispatch_event(evt);
|
|
9133
|
+
ae->last_bit_timestamp = 0;
|
|
9134
|
+
}
|
|
9135
|
+
}
|
|
9136
|
+
}
|
|
9137
|
+
|
|
9138
|
+
void check_buffers(long id, long val) {
|
|
8623
9139
|
Call *call = (Call *)val;
|
|
8624
9140
|
|
|
8625
9141
|
check_digit_buffer(call, DTMF_MODE_RFC2833);
|
|
8626
9142
|
check_digit_buffer(call, DTMF_MODE_INBAND);
|
|
9143
|
+
check_bit_buffer(call);
|
|
8627
9144
|
}
|
|
8628
9145
|
|
|
8629
9146
|
static int digit_buffer_thread(void *arg) {
|
|
@@ -8638,7 +9155,7 @@ static int digit_buffer_thread(void *arg) {
|
|
|
8638
9155
|
PJW_LOCK();
|
|
8639
9156
|
if (g_dtmf_inter_digit_timer > 0) {
|
|
8640
9157
|
g_now = ms_timestamp();
|
|
8641
|
-
g_call_ids.iterate(
|
|
9158
|
+
g_call_ids.iterate(check_buffers);
|
|
8642
9159
|
}
|
|
8643
9160
|
PJW_UNLOCK();
|
|
8644
9161
|
|